c语言Tips:
理论
1. 关于printf。
可以有返回值,为打印计数(包括空格)。用于检查非屏幕打印
打印内容过长时,可在两行间,暂时用一对双引号断开。
当要求输出”/n”时,将强制清空缓冲区,在屏幕输出
2. 关于scanf。
默认时,遇到[空格]、[tab]或[换行符]停止当此输入
可用数字表示最大宽度。
如:%10S,代表最多扫描10个字符就结束。但如果中间遇到空格等还是要提前结束
返回值是成功读入的项目计数。
输入control + z,即为EOF, 值为-1
当读入格式与要求格式不同时,打断。
如:要求%d,而输入为字符,则返回空。且下次扫描时,仍然从该字符开始。
重要!!-----关于缓冲区
当这些扫描输入的函数需要输入时,它们首先去检查缓冲区,如果有内容,就直接取。如果没有,则中断,要求用户输入。此事,无论用户输入多少内容,当且仅当用户输入“回车”时,才会一次性把刚刚输入的内容push进缓冲区。(此时是系统调用,程序处于“阻塞”状态)
3. “逗号”运算符
在for语句中,使用逗号运算符隔开两句,可一次进行两次动作。
例如:for(i=1, j=1; i<=10; j++);
逗号运算得最终取值为右边得表达式。 注:附值符号返回值为左值。
如:i = ( 40, 50); 此时i被附值为50 。
4.
5. 关于getchar
从用户输入回车的那一刻起,每次抓取一个字符,什么都抓!
包括[回车][tab]等!(注:scanf和gets会忽略回车等)
可以被用作清空缓冲区(因为什么都抓嘛)
6. 关于gets
每次抓一整行字符,不包含末尾的回车
7. 关于char类型
占1个字节
可以等同与int操作,例如两个字符可以直接比大小,不用直接转为ASCII码
9. 未定义变量的默认值:
堆栈内变量默认值全为c,静态变量、全局变量默认值全0
10.深入理解++i 和 i++
亲,不要去考虑优先级。即使++i的优先级是最高的,也不会每次都最优先运行。
请看范例:int j = 1;,i = j - ++j;,运算结束后,i=-1,说明左++并没有在整个式子中最优先,仅表示在使用后一个j时,先把j增1,而已。
同样的,i = j++ -j;,结果i也等于-1。说明并不是在整个式子结束以后再j增1,其实是在把j放入式子以后立马给j增1。
从硬件角度考虑,怎么解释呢?有待研究。
11. main函数的参数
main函数的规范申明:int main(int argc, char const *argv[]),其中:
argv[o]指向该文件的绝对路径
argv[1]、argv[2]....分别是终端中输入的参数,string * 类型,以“空格”分开。
例: test.exe hello world 其中,hello是argv[1],world是argv[2]
argc暂时不明
12. 关于数组在函数中的参数传递
数组在参数传递中,默认传递的就是指针(地址),并100%丢失数组长度信息。
例如:func(int a[])等价于func(int * a)等价于func(int a[10])
值得注意的是:int a[10]; sizeof(a); 得40
而如果a作为参数传递到函数中时,sizeof(a);得4。 (int的长度)(说明长度信息丢失)
另外,二维和三维数组定义为形参数时,除第一维外都需显示指定,如func(a[][10])
13. 指向数组的指针
定义: int (* name)[MAX],其中MAX为指向的数组长度。
如何使用:
name++相当于二维数组跳到下一行。
name[1]指向第二行的首元素,类型为int *!!!即指向int的指针。
14. 指向指针的指针
定义:int * (*name)
如何使用:一般在需要在调用函数后返回指针时定义在形参中,调用该函数时,传入指针的地址即可。
15. 关于static
用法一:
作用于函数 和全局变量时,表示该全局变量变量、函数仅对本文件有效
用法二:
作用于局部变量时,表示该局部变量在函数调用结束后仍然不销毁。
16. 多文件的全局变量申明
由于include的特性,全局变量的定义在被include两次后会报错(重复定义)。需要把定义改为申明。
用法:在头文件中,extern int name。 在主文件中:int name = 1即可。
17. 关于malloc
malloc的空间在堆内,系统不会自动释放。局部变量在栈,调用完函数后自动销毁。全局变量在系统常量区。