C语言
初识C语言
计算机语言
- 语言发展:二进制指令->汇编指令->B语言->高级语言
- 国际标准:ANSI C,C89,C90等
- 编译器主要有:Clang,GCC,WIN-TC,MSVC,Turbo C等
第一个程序
- c后缀为源文件,h后缀为头文件
- 主函数返回类型不用void(古老版本),而是int,该函数为程序入口
```
#include <stdio.h>
int main()
{
printf(“Hello world!\n”);
return 0;
}
### 数据类型
- 各个数据类型大小:
{% asset_img 1.jpg %}
### 变量和常量
- 不变的值使用常量描述,否则为变量(局部和全局)
- 局部和全局变量重复时,局部优先
{% asset_img 2.jpg %}
### 字符串+转义字符+注释
- 字符串结束标志是'\0',用strlen计算不包括‘\0’这个字符
#include <stdio.h>
int main()
{
char str[]=”ada”;
char str1[]={‘a’,’d’,’a’,’\0’};
printf(“%s\n”, str);
printf(“%s\n”, str1);
return 0;
}
```
- 转义字符:
- C语言注释风格/xxxxxx/,缺点是不能嵌套注释,而C++注释风格为//xxxxx。
选择语句
- if-else
循环语句
- while,for,dowhile
函数
- 封装一个功能成为函数
数组
- 一组相同类型值的集合
操作符
- 条件操作符:exp1?exp2:exp3
- 最后就是函数调用操作符:ADD(num1,num2)
常见关键字
- typedef:
- static:
-
①static修饰局部变量时,局部变量出作用域不销毁(改变了变量的存储位置)。
②static修饰全局变量时,其外部链接属性变成内部链接属性,其他源文件不能使用该全局变量。
③static修饰函数时,函数也无法被外部链接。 - define:
-
C语言初阶段
-
判断,循环,选择语句—省略。
函数-省略
- .h文件通常放函数声明,.c文件通常放函数定义。
- 递归和迭代:斐波那契,汉诺塔等。
数组
- 一组相同类型元素集合,数据地址连续且从小到大,数组名代表第一个元素的地址。
- 初始化:
- 二维数组:
-
操作符
- 移位操作符:移动的是二进制位(7为111,左移一位为1110=14)
左移移位移动的是整数的补码。
右移移位分为逻辑和算数移位(算术移位右边丢弃,左边补原符号位;逻辑移位右边丢弃,左边补0)。 - 位操作符:&,|,异或。按照二进制补码进行运算。
- 复合赋值符:+=,-=,*=,/=,%=,》》=,《《=,&=,|=等。
- 单目操作符:!,-,+,&,sizeof,~(二进制按位取反),–,++,*,类型转换。
- 关系操作符:>,>=,<,<=,!=,==。
- 逻辑操作符:||,&&
- 条件操作符:exp1?exp2:exp3
- 逗号操作符:从左向右依次执行表达式,整个结果是最后一个表达式的结果。
- 表达式求值:由操作符的优先级决定。
指针详解
- 指针是内存中最小单元的编号,也就是地址,指针变量就是存放内存地址的变量。
- 指针变量大小取决于运行机器位数32/64。指针大小在32位平台(x86)是4字节,64位(x64)中则是8字节。
- 指针变量大小(4字节)和指针指向内容大小(int为4字节,char为1字节)没有关系
- int* p = &a,p为变量名,其存储的是a的地址,数据类型为int,p=20,修改的是a的值。
- 指针运算:指针可以加减整数,减指针(指向同一块内存的指针相减等于相差的空间数)。
- 指针与数组:数组名代表第一个对象的地址。可以用指针变量增减来指向数组中的第n个对象。
- 二级指针:指向指针的指针。
- 指针数组:数组里全部是一致类型的指针。
-
结构体
- 为了描述复杂类型而设计的结构体。成员可以是不同类型变量。
- 可以直接在结构体声明后方声明变量,也可以常规声明。
- 结构体传参:传结构体对象(浪费空间)或者结构体指针(首选传结构体地址)。指针需要-》引用结构体内部变量,结构体需要.引用结构体内部变量。
C语言进阶
动态内存管理
- 声明开辟空间大小固定,且数组声明必须指定长度。
- malloc之后没有free并不是内存空间泄露,程序退出时会自动回收。但如果是持续运行的程序,一直不释放内存就会导致内存泄漏,在free(指针)之后把指针置NULL。
- 真正的动态分配内存:realloc,追加扩容。需要新声明的指针接收realloc防止申请失败。两种情况:原指针后方空间充足则指针地址不变,不足则就找一个新空间把旧数据拷贝进去。
- 常见错误:对动态开辟内存越界访问,对非动态开辟内存进行free,对动态开辟内存的非头指针进行free,对同一块内存多次释放,忘记释放(内存泄露),
- 柔性数组:结构体中柔性数组位于最后,不计入结构体内存,用malloc分配其内存。(柔性数组可以用指针代替,只是需要多次malloc,用完后还需要依次释放free)
-
编译