C 总结 | 复习注意点
- 1.1 C预处理
- 常见错误
- 预处理错误
- #include "" 和 <> 使用错误
- "No such....." 更改“” 或者<> 或指定 gcc -I
- 编译错误
- 语法错误 ; { } 中英文标点
- 没有声明定义
- 链接错误
- 原材料不够 collect错误
- 寻找标签是否实现了,链接时是否一起链接
- 如 undefined reference to “fun”
- 加函数等定义
- 加外部.c文件定义 常见工程
- 寻找标签是否实现了,链接时是否一起链接
- 原材料多了
- 多次实现标签,只保留一个标签实现
- 如头文件,函数重复定义等
- 原材料不够 collect错误
- 预处理错误
- 宏定义细节
- #include 包含头文件
- “” 在文件找 常自定义
- <> 系统找 常预定义
- #define 宏名 宏体 加括号
- #define abc (5+3)
- #define abc(x ) (5+(x))
- #ifndef #endif
- #ifdef #else #endif
- #ifndef #endif
- #include 包含头文件
- 条件预编译应用
- 分调试版本和发行版本
- #ifdef switch----------- # endif
- gcc - Dswitch 进入debug版本
- 分调试版本和发行版本
- 宏展开的# ##
- # 字符串化
- #define abc(x) #x 相当于加“ ”
- ## 连接符号
- #define DAY(x) myday ##x
- # 字符串化
- 常见错误
- 1.2 常用关键字及运算符结构基础
- 关键字 -- 预定义字符串 (32)
- 数据类型
- 基本数据类型 考虑溢出 字节大小
- char 如char a=300溢出
- int
- long short 如 lu
- unsigned signed
- float double 考虑 %7.2f
- void 无返回值
- 自定义数据类型
- struct 结构体 各个元素和 stuct myanc { int a ;unsigned int b}; 类似声明不分空间 顺序有要求
- union 共用体 共有起始地址 技巧性代码 union myabc{ };
- enum 枚举类型 类似常数集合 enum name {a=100,b,c}
- typedf 取外号 考虑跟#define 区别
- 基本数据类型 考虑溢出 字节大小
- 逻辑结果
- if else
- switch case default
- do while for
- continue break goto
- 类型修饰 (资源位置,作用域)
- auto 栈空间 可省略(默认)
- register 寄存器 (尽量安排)
- static 修饰函数内外变量,函数(函数main 有值)
- const 只读变量(其实可用指针更改)
- entern 外部声明
- volatile 告知编译器方式 不优化 (变量修改外部硬件更改)
- 其他
- sizeof ; sizeof (int) ,sizeof a
- return 返回一个变量 数组指针 结构体
- 数据类型
- 运算符
- 算术运算符
- + -
- * (cpu 多周期,软件模拟) /
- %(取范围 n%100+1 ;取个位数;循环数据结构下标)
- 逻辑运算符
- || &&
- > 、>=、 <、 =<
- ! 非 区别~按位取反
- ? : 三目运算
- 位运算符
- << 左移、>>右移 (注意unsigned int 否则可能死循环 )
- &按位与 (& 0 ---屏蔽某一些位;取出位数;清零a &(~(0xn<<M))) |按位或 (a|(0x<<N)保留高电平设置set ;
- ^异或 (算法 AES(wifi加密) SHA1(散列算法);交换a b )
- ~ 按位取反 ()
- 赋值运算
- ==
- += -= &=、.....
- 内存访问符号
- () 函数访问
- [] 内存(数组)访问
- {}函数体访问
- ->地址访问
- & * 地址访问
- 算术运算符
- 逻辑操作
- 顺序
- 分支
- 循环
- 关键字 -- 预定义字符串 (32)
- 1.3 内存空间访问
- 指针 保证合法性
- 指针变量 存放指针盒子(地址)
- 指针+修饰符
- const 常量 只读(不可变)
- const char * p = char const *p 字符串
- char * const p = char *p const 硬件资源
- const char * const p ROM
- [const] char *p="hello world" 不能修改段错误
- voloatile 跟硬件相关
- 防止优化指向内存地址
- typedef 取别名 什么类型 变量名字;
- const 常量 只读(不可变)
- 指针+运算符
- ++、--、+、-
- *p+10 * (p+10) p[10] (可以故意越界更改数据)
- p++ p-- 指针更新
- [] 变量 数组
- 逻辑运算符 判断有无值 同类型比较
- ++、--、+、-
- 多级指针
- 存放地址的地址空间
- char **p 将毫无相干的内存之间联系起来
- p[m] == NULL ->>结束
- 数组
- 数组定义及初始化
- 大小 读取方式 数组类型 数组名 [大小] int a[100] int a[-100]
- 越界
- 数组空间的初始化
- CPU不支持大空间复制,数组是一步一步拷贝 ,第一次初始化
- 数组初始化(库函数帮助)和变量初始化不一样
- char a[10] = {'a',...'\0'} char a[10] = {"abs"} char a[10] = "dsa"
- 第二次初始化赋值只能逐步拷贝
- 字符空间及内存空间分布
- strcpy(buf,“hello”), 容易内存泄漏
- strncpy
- 字符空间(ASC11码,\0结束)和非字符空间(char buf []--->>string , unsigned char -->>data)
- 拷贝三要素 src dest 个数
- memcpy(buf, sersor_buf, 10) 拷贝非字符空间
- 指针跟数组
- int str[10] int *p
- 指针数组 --- 多级指针 二维指针不等于二维数组,无关
- int a[5][6] -->> int (*p)[6] int a[2][3][4]-->>int (*p)[3][4]
- 数组定义及初始化
- 结构体
- 字节对齐
- char a; int b; ? 5 事实上=8
- 牺牲空间换时间,最终结构体大小是4的字数
- 顺序不一样结构体大小不一样
- 位域
- 字节对齐
- 内存分布
- 概念:大小 在哪里
- 栈空间 局部变量 返回自动销毁 运行是出现
- 堆空间 malloc 运行才有 自由分配和释放空间 生存周期由程序员决定
- 分配 int *p= (int *)malloc(5*sizeof(int))
- 释放 free(p)
- 数据段
- BSS数据段 全局/静态变量 (初始化,未初始化或者初始化为0)
- DATA数据段 初始化后的全局或静态变量
- .data和.bss在加载时合并到一个Segment(Data Segment)中,这个Segment是可读可写的。 变量data被分配在data段,而被初始化为0的no_data被分配在了BSS段。.bss是不占用.exe文件空间的,其内容由操作系统初始化(清零);而.data却需要占用,其内容由程序初始化
- 代码段 TEXT 代码主体 ,函数主体 二进制
- .rodata段:存放只读数据,比如printf语句中的格式字符串和开关语句的跳转表。也就是你所说的常量区。例如,全局作用域中的 const int ival = 10,ival存放在.rodata段;再如,函数局部作用域中的printf("Helloworld %d\n", c);语句中的格式字符串"Hello world %d\n",也存放在.rodata段。
- rodata是在多个进程间是共享的,这可以提高空间利用率。
- 工具 size build /string build
- 段错误分析
- 指针 保证合法性
- 1.4 函数的使用
- 函数概述 复用 输入输出
- 三要素:函数名(地址) 输入参数 返回值
- 指针保存函数 char (*p)(int,int,char)类似数组 int(*P)[5]
- 定义函数,调用函数
- 调用例子1:
- 指针地址调用指针函数 p = (int (*)(const char *...))0x804838;
- 调用例子2:
- switch case 用指针数组调用指针函数 效率高
- 调用例子1:
- 输入函数 函数返回 函数名 (接收数据) 形参 - 实参(可以大一点) -- 拷贝
- 值传递 形参不能改变形参 (拷贝后更改 保护)
- 地址传递 子函数通过地址更改主函数的数据
- 作用: 调用者让下层子函数修改空间
- swp(&a,&b)
- 连续空间传递 考虑地址传递
- 数组
- 实参fun(abc) 形参:void fun(int p)//void fun(abc[10])
- 结构体变量
- 实参fun(a) fun(&a ) 形参void fun(stuct abc a1) void fun(stuct abc &a1)
- 空间的读写 void fun(char * p)可修改 void fun(const char* p)只读空间
- 作用:
- 1修改
- 2空间传递
- 子函数查看空间情况 const 如 void fun(char/int *p)
- 子函数修改上层内容 没有const
- 空间 //错误处理 +//内存处理 从头到尾
- 字符空间 strlen strcpy int *
- 空间:首地址+结束标志 (0x00) while(p[i]=='\0') { p[i]操作 ;i++;}
- 遍历
- 非字符空间 char * void *
- 0x00 不是 结束字符, 结束标志式数量 B(空间大小)或者特殊符号
- unsigned char *p
- void fun (unsigned char *p ,int len)
- 字符空间 strlen strcpy int *
- 数组
- 返回值
- 基本语法 返回类型 函数名 (输入类型)
- return 基本类型/地址(连续空间)
- 调用者 a=fun() 被调者 return num
- 返回基本数据类型 char int ...
- 不能返回数组 ,返回地址(指针) 返回结构体造成冗余
- int fun(void ) { a = fun()} 有返回接收 |void fun(int * p){fun(&a)} 无返回告知门牌号修改| int fun(int *p)两种空间 返回接收+修改 | int *fun( void){ int*p=fun() } 返回地址 void fun(int **p){ int *p ; fun(&p } 二级指针
- 返回连续空间类型
- 指针作为空间返回唯一数据类型,int *fun();指向空间(不是局部变量)合法性:使用者使用int*p=fun()
- 基本数据类型,先写框架:基本数据类型:
- static 静态变量
- 基本语法 返回类型 函数名 (输入类型)
- 函数概述 复用 输入输出
本文为博主原创文章,未经博主允许不得转载