C高级笔记总结

GCC :

1、gcc 组件

	(1)分析器:分析语法结构,将C语言编译汇编语言。.s
	(2)汇编器:将汇编代码编译成二进制文件
	(3)链接器:链接目标文件以及库文件,生成可执行代码。
	(4)标准C库:提供核心的C库函数。scanf  printf 

2、gcc编译过程:

	(1)预处理:   宏替换和头文件展开.c - > .i 。
		gcc -E test.c  -o test.i
	(2)编译:     将经过预处理后的文件.i,编译成汇编文件.s
		gcc -S test.i  -o test.s
	(3)汇编:     将汇编文件.s 编译成目标文件.o 二进制码
		gcc -c test.s  -o test.o
	(4)链接:     将一个或多个目标文件,及库链接成为可执行二进制文件
		gcc   test.o  -o a.out
		
	gcc  -g test.c    生成可执行文件,同时附加调试信息,以便于GDB工具使用
	
	gcc -O    编译时需要使用编译优化。
		-O1  O2 
		
	gcc -I头文件路径      指定头文件的搜索路径

	gcc -l第三方库名      指定链接的其他库 


第一类∶标点符号,符号错误

第二类∶头文件错误

第三类∶档案库错误

第四类∶未定义符号

GDB :调试工具

1、调试的程序,编译时必须加 -g 选项
	gcc -g  C文件  
2、gdb  程序名
	gdb ./a.out
	
GDB调试模式:
1、退出   q

2、l 查看源码
3、b 行号      设置断点
4、info b      查看设置 的断点
5、del  断点号     删除断点
6、r           全速运行
7、n       	   单步执行 
8、p  变量名   查看变量的值
9、c  恢复运行    全速运行到下一断点或程序结束

栈回溯命令  backtrace

用于定位段错误位置。

打印法调试。

变量:

对存储空间的抽象,内存空间命名        

数据类型:int char double float 
	本质:空间的大小,空间使用的方式

存储方式:
	全局变量 : 整个文件,及文件外都可以使用: 				作用域
				从程序开始到结束,变量空间一直有效:		生命周期
				存放位置									静态区
				
	局部变量 :  当前代码块 {}        						作用域
				代码块开始到该块结束						生命周期
				存放位置 									栈区		
					
	静态变量  :
		static 修饰的局部变量:  静态局部变量
			当前代码块 {}        						作用域
			从程序开始到结束,变量空间一直有效:		生命周期
			存放位置									静态区
	
	在静态区的变量。只能被初始化一次。

		static  修饰全局变量  : 静态全局变量
			整个文件,限制在文件外的使用: 				作用域
			从程序开始到结束,变量空间一直有效:		生命周期
			存放位置									静态区
	
		static 函数:   静态函数:限制函数的作用域
	
	常量 
		const 修饰的变量

	寄存器变量
		register 修饰的变量 

指针:

什么是指针变量: 一个4字节空间,存放的是内存地址。   32位 - 4字节   64位 - 8字节

指针变量的定义:
int *p;
指针指向的数据类型   * 指针变量名;

指针的赋值:指针的类型   必须类型一致才可以赋值   p=&a;
	将某个空间的地址写入到指针变量的空间
	物理意义:给指针变量建立指向关系。

野指针,空悬指针:没有建立指向关系的指针;
空指针:一个指向0地址的指针,该指针不能进行除赋值以及关系运算以外的任何操作。


指针的使用:   前提:1、指针必须建立指向关系;

	1、取指针指向的内容;
		(* 指针变量名); 代指指向的内容
	int a[10]; int * p = a;   p -> a[0]    
	
	p-> a;  p 数组指针  int (*p)[];    a[][];     p = a;    p -> a[0]
	        int **p  a[][];    p - > a[0];    (*p) ++;
			
			int **p  int *a[];   p -> a[0]  
	
	
	2、指针运算 ,必须满足物理意义。
		(1)算数运算:  +1  -1  ++  --  +n 
				本质:地址的移动;  
				对p移动的字节单位 =   n * 数据类型(*p)字节单位
									
				指针进行算数运算后,仍然是一个指针;
				int *p;
				p=p+1;   p+1;  p++;
				
				*p++; *(p+1); *p +1;
				
				
		一级指针和一维数组:
		int  a[10];
		int *p =a ;
			a:数组名 1、代指这个数组。 2、代指数组首地址
			数组名 不能赋值
			p++;  (*P)
		
							int **p;  int *p[3];  int (*p)[3];
							
sizeof();  计算类型的字节大小    sizeof(p) 8  sizeof(*p)  24
参数:1、数据类型
	  2、变量名,指,计算该变量的类型的大小。

指针与指针的算数运算:  1、只能进行减法操作 2、必须大-小  3、两指针的类型必须一致

	计算的结果 = 两指针间相距的类型个数。

指针的关系运算:  <   >  ==  <=  >=   != 
	本质:指针的位置关系。两指针的类型必须一致

字符数组和字符串;

const  修饰指针:
1、 const int *p;
	const 修饰* ,表示  *p 只读,不能写。 p 指针变量本身,不受此限制。
2、 int * const p;
	const 修饰p, 表示  p  只读,不能赋值。  *p 不受此限制。
3、 const int * const p;
	都不能修改,全部只读;

void 修饰指针;

void *p;  万能指针
	表示,先定义这样一个指针容器,指向的内容的类型不明确。
		一个地址,地址指向的内容类型不明确。


1、指针实现  strcpy();  字符串拷贝
	char *strcpy(char *dest, const char *src);

2、指针实现  字符串拼接
	char *strcat(char *dest, const char *src);

3、字符串倒序
	char *str(char *a); 

指针数组:和二级指针
本质:一个数组,里面的元素是指针。

定义:指针数据类型* pa[10];
	int  *p[10];

二级指针变量:
	本质:地址空间,存放地址,该地址指向一个指针变量。

定义:数据类型 **指针变量名;


数组指针的数组名  与二级指针可以直接赋值,其类型与表示的物理意义完全一致。
例:
	int  *a[3];
	int **p = a;
	
	
	其中对 a ,不能进行赋值操作,因为a是一个数组。
	对 p 可以进行所有的指针操作
	(*p)  是数组a中的一个元素,该元素是一个指针类型,
		因此,可以对(*p) 进行指针的所有操作
		但,注意,在(*p)进行赋值操作后,指向的新位置,
		要确认是否有权限进行*操作。

异或方式交换两个数;

a  = 1111 0101   = 0x f5        1111 0000
b  = 0011 1100	 = 0x 3c        1111 0000     a b

a = a ^ b                        

a = 1100 1001					0000 0000    = '\0'
b = 0011 1100				    0000 0000
b = a ^ b 

b = 1111 0101					0000 0000
a = 1100 1001					0000 0000

a = a ^ b 

a = 0011 1100
b = 1111 0101

数组指针:与二维数组

数组指针:
	本质是一个指针,指针指向一个数组

定义:   数组指针
int	(*p)[n];   

元素类型   (* 指针名 )[数组的元素个数];

二维数组:
	数组名 1、代指这个数组。 2、代指数组首地址

二维数组的数组名 可以使用一个数组指针来存放;
例:
	int a[3][4];
	int (*p)[4] = a;
p++;  1 * a[0] 4*4
		a[1]

对p 可以使用指针的所有操作,也可以当二维数组来使用
(*p)  代指指向的数组,所以,不能进行赋值操作  

总结: 指针变量,
	指针和数组 (1) 指针数组   (2)数组指针

函数:

(1)、函数的定义
返回值类型   函数名(形参列表) { 函数体 }
指针函数:  返回值是指针类型的函数;

(2)、函数的声明
返回值类型   函数名(形参列表);

(3)、函数的调用
函数名 (实参列表);

(4)、参数的传递:   
	1、复制实参传递
	
	int func(int a,int b)

	func(x,y);

	2、实参地址方式传递
	
	int func(int *a,int *b)

	func(&x,&y);

(5)、函数指针
	本质:一个指针,指向一个函数。

	函数名 :1、代指这个函数   2、函数代码块的首地址

	函数指针的定义:
	返回值类型     (* 指针变量名) (形参列表) ;

	函数指针操作: 1、赋值,建立指向关系  2、取指向的函数
	
	 p = 函数名。  p 指向函数

	void func1(  void (*fp)(void) , char a ); 回调函数

数组   函数  指针 

函数指针数组:
	本质是数组,数组元素是指针,指针指向函数;   void  (int)
	
定义: void    (*fpa[])(int);

递归函数:

自己调用自己,每次调用缩小规模,到达临界值,确定的临界值,依次返回;

本质: 对栈区内存的使用;


求 1+2 .... n;  和?
使用递归求解。
int sum(int n)
{
	if(n == 1) return 1;
	if(n > 1)  return n+ sum(n-1);
}	
n (返回值) 
int  sum(int n)  an+a(n-1)+sum(n-2) .... sum(n-n+1) + 1  临界值	
1、n!

2、    1  2  3  5   8  13 .....   斐波那契数列
	n  1  2  3  4   5  6     n    n = 20

	an = a(n-1) + a(n-2);

结构体:

结构体:是一种构造数据类型。						基本数据类型  int char  *
	由一个或多个基本数据类型构造而成的数据类型

定义一个结构体类型:
struct 结构类型名
{
	成员1;   
	成员2;
	..
};

定义一个结构体类型变量:

struct 结构类型名
{
	成员1;   
	成员2;
	..
}结构体变量名;

给类型取别名:

typedef 原类型名  别名;

初始化:
struct 结构类型名
{
	成员1;   
	成员2;
	..
}结构体变量名 = {成员1的值,成员2的值,,....};




使用:
结构体不能整体使用,必须进入结构体,使用成员。
使用方法:
结构体名.成员

当两个结构体类型完全一致的变量,直接赋值;

结构体的数据存放:

1、按成员顺序依次存放。
2、满足字节对齐要求。   编译器决定
	开辟结构体空间时,最小的开辟单位,4字节对齐。   2字节对齐   单字节对齐。
	空间使用,遵循紧凑原则。

结构体指针:

本质:是一个指针,指向结构体;

定义:  结构体数据类型 *结构体指针变量名;
	struct  st *stp = &st1;

使用: 引用结构体成员
	方式1:  (*stp).成员;
	方式2:  结构体指针专用。
			stp -> 成员;

结构体数组:

本质:是数组,数组元素是结构体。

定义结构体数组:
struct st sta[3];

结构体指针数组:

本质:是一个数组,元素是结构体指针。
定义:
struct st *stpa[3];
使用:
(stpa[1])->成员;

结构体数组指针:

本质:是一个指针,指向数组,数组元素是结构体。

定义:
struct st	(*stap)[4];

((*stap)[0]).成员


数组   结构体 函数  指针;


结构体中有特殊的成员;
结构体指针;
结构体指针数组;

共用体:

跟结构体类似,存储空间共用。空间的大小由最大的成员决定。

定义共用体类型:
union   共用体类型名
{
	成员1;
	成员2;
	...
};

共用体使用:
跟结构体完全一致;

字节序:

对于多字节数据,超过一个字节的基本数据类型。  int short double float 
大端:数据的高位存放在内存的高地址,低位在低地址    PC x86架构 amd  CPU
小端:数据的高位存放在内存的低地址,低位在高地址    ARM 架构   
有CPU的架构决定。

网络编程。

堆区动态内存分配:

堆的特性:1、需要手动开辟和释放空间。
	2、堆区内存:
	生命周期:从你申请开始到释放或程序结束而结束。
	作用域:  得到指针的范围。

使用:

1、必须先手动申请才能使用。

	申请:
	头文件:#include <stdlib.h>
	
	void *malloc(size_t size);
函数5要素:
1、作用:申请堆区内存。
2、函数原型:
3、参数:
	size:表示要申请的堆区内存的大小,字节。
4、返回值:
	void *:万能指针,成功,返回一个指针,指向一片堆区空间。
		失败: NULL
5、注意事项;

2释放空间:

	void free(void *ptr);
		ptr = NULL;
	ptr:需要释放的堆区空间指针。
	注意事项:
		1、不能重复释放
		2、不能释放一部分。

内存泄漏:
	原因:申请的空间的指针丢失。


结构体指针数组[100]; 

动态内存:
	存放学生详细信息。


struct st* add(char *name,int ID,int high,float weight)
{
	malloc 
}

makefile 工程管理器:

规则文件:描述编译过程。 makefile  Makefile

格式:

目标:依赖
由依赖生成目标的规则

伪目标:
	不需要依赖的目标

变量:

变量定义的两种方式   自定义变量:
1、递归展开方式VAR=var
2、简单方式 VAR:=var
3、VAR?=var   变量若存在则不做任何操作。
	变量名+= 值  表示在变量的末尾追加值

自动变量:

	$*   不包含扩展名的目标文件名称   
	$+   所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件
	$<    第一个依赖文件的名称
	$?    所有时间戳比目标文件晚的的依赖文件,并以空格分开
	$@  目标文件的完整名称
	$^     所有不重复的目标依赖文件,以空格分开
	$%    如果目标是归档成员,则该变量表示目标的归档成员名称

make -f file 读入当前目录下的file文件作为Makefile

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值