为什么要学习C语言?C语言有什么优势?
- C语言是计算机程序语言的基础,跟数据结构紧密相连,对理解如何构造数组、链表、树和图等结构有帮助。
- C语言的高效率,用于开发底层的东西,如驱动、通信协议类,高并发,嵌入式等不可或缺
- 静态static与非静态:全局变量、局部变量、静态全局变量、静态局部变量、静态函数、普通函数
- 作用域不同
- 全局变量有全局作用域,在一个源文件定义了,就可以作用于所有源文件。其他不包含该全局变量定义的源文件需用extern再次声明该全局变量。
- 局部变量只有局部作用域,只在函数执行期间存在,函数执行结束后,变量撤销,所占内存被回收。
- 静态全局变量,其作用域仅限于定义它的文件,如果程序包含多个文件,静态全局变量不能作用于其他文件。
- 静态局部变量,它只初始化一次,自从第一次被初始化知道程序运行结束都一直存在,它和全局变量的区别在于全局变量对所有函数可见,而静态局部变量只对定义自己的函数体始终可见。
- static静态函数也叫内部函数,只能被本文件中的函数调用,而不能被同一程序下的其他文件中的函数调用。
- extern修饰函数也叫外部函数,函数定义和声明默认情况是extern,就是该函数可供其他文件调用。
- 生命周期不同
- 内存空间分配不同
- 全局变量和静态全局变量内存空间分布一致,都在静态存储区。
- 局部变量和静态局部变量不同,静态全局变量都在静态存储区,局部变量在栈里分配空间。
- 静态函数会被自动分配在一个一直使用的存储区,知道应用程序退出,避免了调用函数时压栈出栈,速度快很多。
- 而外部函数是在栈里分配空间,调用时需要压栈出栈。
- 作用域不同
- const常量
- const 与#define的区别:const用于定义常量,与预编译命令#define作用类似,但#define只是对值进行简单替换,不做类型检查;const可保护被修饰的东西,防止意外篡改;编译器不会为const变量分配内存,而是将其保存在符号表中。
- const int n=5; 与 int const n=5;作用一样,表示n是常量。在定义时就要一起初始化,以后就不能修改了。n=10,就会报错。
- const char* str = 'hello'; 常量静态字符串,表示字符串指针str指向的字符串是常量,不可修改。str[0]='w'就会报错。
- const in *n = 10; 常量指针是指针指向的内容是常量,但可以修改该指针的值。
- int a=5;int const *n = &a; n是指针常量,该指针本身是常量,不能指向其他地址。区分指针常量与常量指针的关键在于星号的位置,以星号为界,如果const在星号的左边,则为常量指针;如果const在星号右边,则为指针常量;如果把星号读作指针,const读作常量正好吻合;* const 为指针常量, const *常量指针。
- const修饰函数返回值,函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const修饰的同类型指针。const char * GetString(void);
- volatile
- 提醒编译器它后面所定义的变量随时都有可能改变,防止编译器过度优化,使用暂存器中的值,如果该变量由别的程序更新的话,两个程序获取值不一致。
- i++, ++i
- n = i++, 先n=i,再i++;先赋值,再自增
- n = ++i. 先++i,在n=i
- heap与stack
- heap堆,是由程序员控制,通过malloc/free来分配和释放内存,空间很大
- stack栈,是有操作系统控制,空间较小
- 预编译
- 函数执行前的准备工作,用#来表示
- 用于不经常改动的大型代码体
- 程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下,可以将所有包含文件预编译为一个预编译头
- sizeof
- sizeof用于数组,只能测出静态数组的大小,无法检测实际占用的多少
- sizeof用于字符串,结果是实际大小+1,因为每个字符串都有一个结束符
- 算法
- 排序
- atoi
- fibonacci
- 数组逆序