//#include <stdio.h>

//

////下面代码,打印结果是什么?为什么?(突出'\0'的重要性)

//int main()

//{

// char arr1[] = "bit";

// char arr2[] = { 'b', 'i', 't' };

// char arr3[] = { 'b', 'i', 't','\0' };

// printf("%s\n", arr1);

// printf("%s\n", arr2);

// printf("%s\n", arr3);

// return 0;

//}


#include <stdio.h>

//int main()

//{

// //问题1:在屏幕上打印一个单引号',怎么做?

// //问题2:在屏幕上打印一个字符串,字符串的内容是一个双引号“,怎么做?

// printf("%c\n", '\'');

// printf("%s\n", "\"");

// return 0;

//}



//int main()

//{

// printf("%d\n", strlen("abcdef"));

// // \62被解析成一个转义字符

// printf("%d\n", strlen("c:\test\628\test.c"));

// return 0;

//}



//int Add(int x, int y) {

// return x + y;

//}

//C语言风格注释

//int Sub(int x, int y)

//{

// return x - y;

//   }

//    

//int main()

//{

// //C++注释风格

// //int a = 10;

// //调用Add函数,完成加法

// printf("%d\n", Sub(6, 10));

// return 0;

//}





//int main()

//{

// int coding = 0;

// printf("你会去敲代码吗?(选择1 or 0):>");

// scanf("%d", &coding);

// if (coding == 1)

// {

//  printf("坚持,你会有好offer\n");

// }

// else if (coding == 0)

// {

//  printf("放弃,回家卖红薯\n");

// }

// else  

// {

//  printf("输入错误\n");

// }

//

// return 0;

//}



//int main()

//{

// printf("加入比特\n");

// int line = 0;

// while (line <= 20000)

// {

//  line++;

//  printf("我要继续努力敲代码\n");

// }

// if (line>20000)

//  printf("好offer\n");

// return 0;

//}



//int main()

//{

// int i = 0;

// int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

// for (i = 0; i<10; i++)

// {

//  printf("%d ", arr[i]);

// }

// printf("\n");

// return 0;

//}





//int main()

//{

// int i = 0;

//  

// for (i = 1; i<100; i++)

// {

//  printf("%d\n ", i);

// }

// printf("\n");

// return 0;

//}




//布尔位运算符

//表 1 中列举的运算符可以对操作数的每个位进行布尔运算。这种二元运算符把两个不同操作数内相同位置的位关联起来。被设定的位(也就是值为 1 的位)被解释为 true,被清除的位(也就是值为 0 的位)被解释为 false。

//

//除布尔运算符 AND、OR 和 NOT 以外,也有位异或运算符(exclusive - OR,XOR)。这些都在表 1 进行了列举。

//

//表1 布尔位运算符

//运算符 意义 示例 对于每个位位置的结果(1 = 设定,0 = 清除)

//&     位 AND  x&y  如果 x 和 y 都为 1,则得到 1;如果 x 或 y 任何一个为 0,或都为0,则得到 0

//| 位 OR  x | y  如果 x 或 y 为 1,或都为 1,则得到 1;如果 x 和 y 都为 0,则得到 0

//^ 位 XOR  x^y  如果 x 或 y 的值不同,则得到 1;如果两个值相同,则得到 0

//~位 NOT(I的补码)  ~x  如果 x 为 0,则得到 1,如果 x 是 1,则得到 0

//位运算符的操作数必须是整数类型,并且遵循寻常算术转换(usualarithmetic conversion)。转换后获得的操作数通用类型就是整个计算结果的类型。表 2 展示了这些运算符的效果。

//

//表2 位运算符的效果

//表达式(或声明) 位模式

//int a = 6; 0···00110

//int b = 11; 0···01011

//a&b 0···00010

//a | b 0···01111

//a^b 0···01101

//~a 1···11001

//

//可以将一个整数 a 的特定位清除,做法是将整数 a 和另一个整数进行位 AND 运算,其中,另一个整数在需要清除的位为 0,其他位则为 1,并位 AND 运算,其中,另一个整数在需要清除的位为 0,其他位则为 1,并将 AND 运算的结果赋值给整数 a。

//

//该另一个整数,即位 AND 运算的第二个操作数,被设定为 1 的位置(称为位掩码),这些位置经过位 AND 运算,不会改变第一个操作数对应位置的值。例如,一个整数与一个位掩码 0xFF 进行位 AND 运算后,将保留最低位置的 8 个位,而会清除其他所有位的值:

//a &= OxFF;            // 相当于:a = a & OxFF;

//

//在该示例中,复合赋值运算符 &= 也会执行 & 运算。复合赋值运算符与其他二元位运算符具有类似的执行方式,这里不再赘述。

//

//位运算符也可以用来生成位掩码,以供以后的位运算使用。例如,在位模式 0x20 中,只有位5被设定。因此表达式 ~0x20 会生成一个只有位 5 没有被设定的位掩码:

//a &= ~0x20;             // 清除a中的位5

//位掩码 ~0x20 比 0xFFFFFFDF 更受欢迎,因为它的可移植性更好:结果不会受到机器字大小的影响(同时也更方便人阅读)。

//

//也可以使用运算符 | (OR)和 ^(XOR)来设定或清除特定位,下面是一个示例:

//int mask = OxC;

//a |= mask;              // 设定a的位2和位3

//a ^= mask;              // 求反a的位2和位3

//

//第二个转换使用相同的位掩码,它会将第一次转换的结果再反转一次。换句话说,b^mask^mask 会得到原来 b 的值。这个操作可以用于交换两个整数的值,而不需要使用第三个临时变量:

//a ^= b;                  // 等效于 a = a ^ b;

//b ^= a;                 // 将a原来的值赋值给b

//a ^= b;                 // 将b原来的值赋值给a

//

//本例中的前两个表达式等同于 b = b^(a^b)或 b = (a^b)^b。其结果等同于 b = a,副作用是 a 的值也被修改了,其修改后的值为 a^b。在这时,第三个表达式具有如下副作用 a = (a^b)^a 或 a = b(使用 a 和 b 的原始值)。

//移位运算符

//移位运算符将左操作数的位模式移动数个位置,至于移动几个位置,由右操作数指定。它们如表 3 列举。

//

//

//表3 移位运算符

//运算符 意义 示例 结果

//<< 向左移位 x << y x 的每个位向左移动 y 个位

//>> 向右移位 x >> y x 的每个位向右移动 y 个位

//

//移位运算符的操作数必须是整数。在实际移位操作之前,两个操作数都要进行整数提升(promotion)。右边操作数不可以为负值,并且必须少于左边操作数在整数提升之后的位长。如果不符合这些条件,程序运行结果将无法确定。

//

//移位运算结果的类型等于左操作数在整数提升后的类型。下面示例的移位表达式具有 unsigned long 类型。

//unsigned long n = 0xB,     // 位模式: 0 ... 0 0 0 1 0 1 1

//result = 0;

//result = n << 2;          //              0 ... 0 1 0 1 1 0 0

//result = n >> 2;          //              0 ... 0 0 0 0 0 1 0

//

//在向左移位运算时,右边多出来的位用 0 来填充。移动超出左边边界的位则直接抛弃。向左移动 y 个位置,就等同于将左操作数乘以 2 ^ {y}:如果左操作数 x 是无符号类型,那么表达式 x << y 的结果等于表达式 x×2^{ y } 的值。因此,在前面的例子,n << 2 的值为 n×4,也就是 44。

//

//在向右位移运算时,如果左操作数是无符号类型,或者左操作数是带符号类型但为非负值,则左边多出来的位用 0 来填充。在这种情况下,表达式 x >> y 的结果等效于表达式 x / 2 ^ {y} 的值。如果左操作数是负值,那么由编译器决定用于填充至左边多出来的位的内容,可能是 0,也可能是符号位。

//纯文本复制

//// 函数setBit()

//// 设定掩码m中p位置的位。

//// 使用定义在limits.h中的CHAR_BIT,存储一个字节内的位的数目。

//// 返回值: 完成位设定的新掩码,其中p位置已设定好

////              如果p不是有效的位置,则返回原始掩码。

//unsigned int setBit(unsigned int mask, unsigned int p)

//{

// if (p >= CHAR_BIT * sizeof(int))

//  return mask;

// else

//  return mask | (1 << p);

//}


//void test()

//{

// int i = 0;

// i++;

// printf("%d ", i);

//}

//int main()

//{

// int i = 0;

// for (i = 0; i < 10; i++)

// {

//  test();

// }

// return 0;

//}




//void test()

//{

// //static修饰局部变量

// static int i = 0;

// i++;

// printf("%d ", i);

//}

//int main()

//{

// int i = 0;

// for (i = 0; i<10; i++)

// {

//  test();

// }

// return 0;

//}



//int g_val = 2018;

////test.c

//int main()

//{

// printf("%d\n", g_val);

// return 0;

//}

//代码2

//add.c

//static int g_val = 2018;

////test.c

//int main()

//{

// printf("%d\n", g_val);

// return 0;

//}


//static int Add(int x, int y) {

// return x + y;

//}

////test.c

//int main()

//{

// printf("%d\n", Add(2, 3));

// return 0;

//}




////define定义标识符常量

//#define MAX 1000

////define定义宏

//#define ADD(x, y) ((x)+(y))

//

//int main()

//{

// int sum = ADD(2, 3);

// printf("sum = %d\n", sum);

//

// sum = 10 * ADD(2, 3);

// printf("sum = %d\n", sum);

//

// return 0;

//}


//int main()

//{

// int num = 10;

// &num;//取出num的地址

// //注:这里num的4个字节,每个字节都有地址,取出的是第一个字节的地址(较小的地址)

// printf("%p\n", &num);//打印地址,%p是以地址的形式打印

// return 0;

//}


//int main()

//{

// int num = 10;

// int *p = &num;

// *p = 20;

// printf("%p\n", p);

// return 0;

//}


//int main()

//{

// char ch = 'w';

// char* pc = &ch;

// *pc = 'q';

// printf("%c\n", ch);

// return 0;

//}



//struct Stu

//{

// char name[20];//名字

// int age;      //年龄

// char sex[5];  //性别

// char id[15]; //学号

//};

////打印结构体信息

//struct Stu s = { "张三", 20, "男", "20180101" };

////.为结构成员访问操作符

//printf("name = %s age = %d sex = %s id = %s\n", s.name, s.age, s.sex, s.id);

////->操作符

//struct Stu *ps = &s;

//printf("name = %s age = %d sex = %s id = %s\n", ps->name, ps->age, ps->sex, ps - >id);