字符串的输入:
char str[10] = {0};
scanf("%s",char*);
通过这样的方式是可以从缓存区中拿到字符串。
如果缓存区内的字符长度比字符数组的长度大,将会产生两个问题:
1、字符串结尾的 '\0' 字符会丢失
2、即使超出了字符数组的范围,还是会不断的往这个字符数组后面的内存继续写。这样就会破坏掉内存中的其他数据,很有可能会导致程序停止。
fgets(char*,int,stdin);
通过这样的方式也可以从缓存区中拿到字符串。
第一个参数:字符数组
第二个参数:数组大小
第三个参数:使用哪个设备输入(stdin)
如果缓存区中的字符串大小小于第二个参数规定的个数(这个数字不能超过数组大小,需要把这个规定个数减一,数组的最后以为会保留给'\0'),会把最后的'\n'字符也读取到字符数组。
如果缓存区中的字符串大小超出了第二个参数规定的个数。剩下的部分会滞留在缓存区中,程序的下一次读取动作将会先读取之前滞留在缓存区中的内容。
这样的情况是不合理的,我们希望每一次的读取都是新的内容,所以每次读取结束之后,我们需要对缓存区进行判断,并保证它是空的。
可以通过这次读取的最后一个字符是不是 '\n' ,来判断缓存区中的字符是否读取完毕。
之后再通过 scanf("%*[^\n"); 删除缓存区中,第一个'\n'字符前的内容。
通过 scanf("%*c"); 删除缓存区中的'\n'字符。
宏定义:
#define 宏名称 宏的值
宏名称不能带有任何控制字符(空格,tab,回车)
一般宏名称用全大写的英文字母表示
编译器再编译的时候会将源文件中,所有的宏名称,先替换成宏的值,然后再做下一步。
可以再编译过程中用以下形式设置宏的值:
gcc -D宏名称=值 源文件.c
宏定义可以定义一个计算过程,把计算过程中的未知数作为宏的参数。当程序调用宏的时候,会给出具体参数。
#define ADD(a,b) ((a) * (b))
程序中调用宏的时候,a有可能是一个复杂的表达式,如果不对a加括号,很有可能会导致最后计算的结果不是预期中的结果。
对整个计算过程加括号也是这个道理,因为程序调用宏的环境很有可能会修改宏的计算顺序。
带参数的宏,编译的过程如下:
先把源文件中的宏名称替换成宏的值,然后把宏的参数替换成程序给出的值。然后进行下一步。
传给宏的参数,如果宏对其进行了修改,修改的结果是生效的,程序在把参数传给宏时,宏并没有像函数一样为其创建一个副本,而是直接在这个参数的地址上工作。
在宏里最好不要使用递增或者递减的操作。
宏操作符:
#是一个宏操作符,可以把宏的参数变成字符字面值:#define STR(n) #n STR(1 + 2); ==> "1 + 2";
##可以把作为宏参数传递过来的标识符和宏的值中的其他部分相连接,变成一个新的标识符:#define STT(n) p_##n int* STT(num); ==>int* p_num;