C语言思维导图
2022-05-06 10:46:37 31 举报
AI智能生成
c
作者其他创作
大纲/内容
指针
指针概念
操作系统给每个存储单元分配了一个编号,从0x00 00 00 00 ~0xff ff ff ff
这个编号咱们称之为地址
这个编号咱们称之为地址
指针变量:是个变量,是个指针变量,即这个变量用来存放一个地址编号
在32位平台下,地址总线是32位的,所以地址是32位编号,所以指针变量是32位的即4个
字节
在32位平台下,地址总线是32位的,所以地址是32位编号,所以指针变量是32位的即4个
字节
指针与变量的关系
在程序中,引用变量的方法
1:直接通过变量的名称
int a;
a=100;
2:可以通过指针变量来引用变量
int *p;//在定义的时候,*不是取值的意思,而是修饰的意思,修饰p是个指针变量
p=&a;//取a的地址给p赋值,p保存了a的地址,也可以说p指向了a
*p= 100;//在调用的时候*是取值的意思,*指针变量 等价于指针指向的变量
1:直接通过变量的名称
int a;
a=100;
2:可以通过指针变量来引用变量
int *p;//在定义的时候,*不是取值的意思,而是修饰的意思,修饰p是个指针变量
p=&a;//取a的地址给p赋值,p保存了a的地址,也可以说p指向了a
*p= 100;//在调用的时候*是取值的意思,*指针变量 等价于指针指向的变量
数组元素与指针的基本关系
变量存放在内存中,有地址编号,咱们定义的数组,是多个相同类型的变量的集合,
每个变量都占内存空间,都有地址编号
指针变量当然可以存放数组元素的地址
每个变量都占内存空间,都有地址编号
指针变量当然可以存放数组元素的地址
数组元素的引用方法‘
方法1: 数组名[下标]
int a[10];
a[2]=100;
方法2:指针名加下标
int a[10];
int *p;p=a;
p[2]=100;//因为p和a等价
int a[10];
a[2]=100;
方法2:指针名加下标
int a[10];
int *p;p=a;
p[2]=100;//因为p和a等价
方法3:通过指针运算加取值的方法来引用数组的元素
int a[10];
int *p;
p=a;
*(p+2)=100;//也是可以的,相当于a[2]=100
解释:p是第0个元素的地址,p+2是 a[2]这个元素的地址。
对第二个元素的地址取值,即a[2]
int a[10];
int *p;
p=a;
*(p+2)=100;//也是可以的,相当于a[2]=100
解释:p是第0个元素的地址,p+2是 a[2]这个元素的地址。
对第二个元素的地址取值,即a[2]
指针的运算’
指针可以加一个整数
往下指几个它指向的变量,结果还是个地址
前提:指针指向数组的时候,加一个整数才有意义
往下指几个它指向的变量,结果还是个地址
前提:指针指向数组的时候,加一个整数才有意义
两个相同类型指针可以比较大小前提:只有两个相同类型的指针指向同一个数组的元素的时候,比较大小才有意义
指向前面元素的指针 小于 指向后面 元素的指针
指向前面元素的指针 小于 指向后面 元素的指针
两个相同类型的指针可以做减法
前提:必须是两个相同类型的指针指向同一个数组的元素的时候,做减法才有意义
做减法的结果是,两个指针指向的中间有多少个元素
前提:必须是两个相同类型的指针指向同一个数组的元素的时候,做减法才有意义
做减法的结果是,两个指针指向的中间有多少个元素
指针数组
指针和数组的关系
1:指针可以保存数组元素的地址
2:可以定义一个数组,数组中有若干个相同类型指针变量,这个数组被称为指针数组
指针数组的概念:
指针数组本身是个数组,是个指针数组,是若干个相同类型的指针变量构成的集合
注意:一般遇到这样的叠词,本质就是后者
1:指针可以保存数组元素的地址
2:可以定义一个数组,数组中有若干个相同类型指针变量,这个数组被称为指针数组
指针数组的概念:
指针数组本身是个数组,是个指针数组,是若干个相同类型的指针变量构成的集合
注意:一般遇到这样的叠词,本质就是后者
指针数组的分类
字符指针数组char *p[10]、短整型指针数组、整型的指针数组、长整型的指针数组
float型的指针数组、double型的指针数组
结构体指针数组、函数指针数组
字符指针数组char *p[10]、短整型指针数组、整型的指针数组、长整型的指针数组
float型的指针数组、double型的指针数组
结构体指针数组、函数指针数组
二级指针
指针的指针,即指针的地址,
字符串和指针
在文字常量区开辟了一段空间存放字符串,将字符串的首地址付给str
堆:
使用malloc函数在堆区申请空间,将字符串拷贝到堆区
堆:
使用malloc函数在堆区申请空间,将字符串拷贝到堆区
字符串的概念:
字符串就是以’\0’结尾的若干的字符的集合
字符串的存储形式: 数组、字符串指针、堆
1、 char string[100] = “I love C!”
定义了一个字符数组string,用来存放多个字符,并且用”I love C!”给string数组初始
化
,字符串“I love C!”存放在string中
2、 char *str = “I love C!”
定义了一个指针变量str,只能存放字符地址编号,
所以说I love C! 这个字符串中的字符不能存放在str指针变量中。
str只是存放了字符I的地址编号,“I love C!”存放在文字常量区
3、 char *str =(char*)malloc(10*sizeof(char));
动态申请了10个字节的存储空间,首地址给str赋值。
strcpy(str,"I love C");//将字符串“Ilove C!”拷贝到str指向的内存里
总结:
字符串就是以’\0’结尾的若干的字符的集合
字符串的存储形式: 数组、字符串指针、堆
1、 char string[100] = “I love C!”
定义了一个字符数组string,用来存放多个字符,并且用”I love C!”给string数组初始
化
,字符串“I love C!”存放在string中
2、 char *str = “I love C!”
定义了一个指针变量str,只能存放字符地址编号,
所以说I love C! 这个字符串中的字符不能存放在str指针变量中。
str只是存放了字符I的地址编号,“I love C!”存放在文字常量区
3、 char *str =(char*)malloc(10*sizeof(char));
动态申请了10个字节的存储空间,首地址给str赋值。
strcpy(str,"I love C");//将字符串“Ilove C!”拷贝到str指向的内存里
总结:
初始化:
字符数组、指针指向的字符串:定义时直接初始化
char buf_aver[]="hello world";
char *buf_point="hello world";
堆中存放的字符串不能初始化、只能使用strcpy、scanf赋值
char *buf_heap;
buf_heap=(char *)malloc(15);
strcpy(buf_heap,"hello world");
scanf(“%s”,buf_heap);
使用时赋值
字符数组:使用scanf或者strcpy
char buf_aver[128];
buf_aver="hello kitty"; 错误,因为字符数组的名字是个常量
strcpy(buf_aver,"hello kitty"); 正确
scanf("%s",buf_aver); 正确指向字符串的指针:
char *buf_point;
buf_point="hello kitty"; 正确,buf_point指向另一个字符串
strcpy(buf_point,"hello kitty"); 错误,只读,能不能复制字符串到buf_piont指向
的内存里
取决于buf_point指向哪里。
字符数组、指针指向的字符串:定义时直接初始化
char buf_aver[]="hello world";
char *buf_point="hello world";
堆中存放的字符串不能初始化、只能使用strcpy、scanf赋值
char *buf_heap;
buf_heap=(char *)malloc(15);
strcpy(buf_heap,"hello world");
scanf(“%s”,buf_heap);
使用时赋值
字符数组:使用scanf或者strcpy
char buf_aver[128];
buf_aver="hello kitty"; 错误,因为字符数组的名字是个常量
strcpy(buf_aver,"hello kitty"); 正确
scanf("%s",buf_aver); 正确指向字符串的指针:
char *buf_point;
buf_point="hello kitty"; 正确,buf_point指向另一个字符串
strcpy(buf_point,"hello kitty"); 错误,只读,能不能复制字符串到buf_piont指向
的内存里
取决于buf_point指向哪里。
数组指针
组指针的概念:
本身是个指针,指向一个数组,加1跳一个数组,即指向下个数组。
数组指针的作用就是可以保存二维数组的首地址
3、数组指针的定义方法:
指向的数组的类型(*指针变量名)[指向的数组的元素个数]int (*p)[5];//定义了一个数组指针变量p,p指向的是整型的有5个元素的数组
p+1 往下指5个整型,跳过一个有5个整型元素的数组
本身是个指针,指向一个数组,加1跳一个数组,即指向下个数组。
数组指针的作用就是可以保存二维数组的首地址
3、数组指针的定义方法:
指向的数组的类型(*指针变量名)[指向的数组的元素个数]int (*p)[5];//定义了一个数组指针变量p,p指向的是整型的有5个元素的数组
p+1 往下指5个整型,跳过一个有5个整型元素的数组
结构体
结构体概念
构造类型:
不是基本类型的数据结构也不是指针,它是若干个相同或不同类型的数据构成的集合
常用的构造类型有数组、结构体、共用体
数组用于保存多个相同类型的数据
结构体用于保存多个不同类型的数据
不是基本类型的数据结构也不是指针,它是若干个相同或不同类型的数据构成的集合
常用的构造类型有数组、结构体、共用体
数组用于保存多个相同类型的数据
结构体用于保存多个不同类型的数据
先定义结构体类型,再去定义结构体变量
struct 结构体类型名{
成员列表
};
struct 结构体类型名{
成员列表
};
在定义结构体类型的时候顺便定义结构体变量,以后还可以定义结构体变量
struct 结构体类型名{
成员列表;
}结构体变量1,变量2;
struct 结构体类型名 变量3,变量4;
struct 结构体类型名{
成员列表;
}结构体变量1,变量2;
struct 结构体类型名 变量3,变量4;
无名结构体的定义
在定义结构体类型的时候,没有结构体类型名,顺便定义结构体变量,
因为没有类型名,所以以后不能再定义相关类型的数据了
struct {
成员列表;
}变量1,变量2;
注意:无名结构体由于没有结构体名,所以定义完之后是无法在定义结构体变量的,只能在
定义类型的同时定义结构体变量
在定义结构体类型的时候,没有结构体类型名,顺便定义结构体变量,
因为没有类型名,所以以后不能再定义相关类型的数据了
struct {
成员列表;
}变量1,变量2;
注意:无名结构体由于没有结构体名,所以定义完之后是无法在定义结构体变量的,只能在
定义类型的同时定义结构体变量
给结构体类型取别名
通常咱们将一个结构体类型重新起个类型名,用新的类型名替代原先的类型
typedef struct 结构体名 {
成员列表;
}重新定义的结构体类型名A;
注意:typedef主要用于给一个类型取别名,此时相当于给当前结构体重新起了一个类型名
为A,
相当于 struct 结构体名,所以如果结构体要取别名,一般不需要先给结构体定义名字,定
义结构体变量时,直接使用A即可,不用加struct
通常咱们将一个结构体类型重新起个类型名,用新的类型名替代原先的类型
typedef struct 结构体名 {
成员列表;
}重新定义的结构体类型名A;
注意:typedef主要用于给一个类型取别名,此时相当于给当前结构体重新起了一个类型名
为A,
相当于 struct 结构体名,所以如果结构体要取别名,一般不需要先给结构体定义名字,定
义结构体变量时,直接使用A即可,不用加struct
结构体变量的初始化和使用
结构体变量的定义和初始化
结构体变量,是个变量,这个变量是若干个数据的集合
注:
(1):在定义结构体变量之前首先得有结构体类型,然后在定义变量
(2):在定义结构体变量的时候,可以顺便给结构体变量赋初值,被称为结构体的初始化
(3):结构体变量初始化的时候,各个成员顺序初始化
结构体变量,是个变量,这个变量是若干个数据的集合
注:
(1):在定义结构体变量之前首先得有结构体类型,然后在定义变量
(2):在定义结构体变量的时候,可以顺便给结构体变量赋初值,被称为结构体的初始化
(3):结构体变量初始化的时候,各个成员顺序初始化
在结构体中嵌套结构体
相同类型的结构体变量可以相互赋值
结构体数组
结构体数组是个数组,由若干个相同类型的结构体变量构成的集合
1、结构体数组的定义方法
1 struct 结构体类型名 数组名[元素个数]
1、结构体数组的定义方法
1 struct 结构体类型名 数组名[元素个数]
结构体数组元素的引用1 数组名[下标]
3、结构体数组元素对成员的使用
1 数组名[下标].成员
3、结构体数组元素对成员的使用
1 数组名[下标].成员
结构体指针
即结构体的地址,结构体变量存放内存中,也有起始地址
咱们定义一个变量来存放这个地址,那这个变量就是结构体指针变量。
咱们定义一个变量来存放这个地址,那这个变量就是结构体指针变量。
结构体指针变量的定义方法:
1 struct 结构体类型名 * 结构体指针变量名;
1 struct 结构体类型名 * 结构体指针变量名;
结构体指针变量对成员的引用
1 (*结构体指针变量名).成员
2 结构体指针变量名‐>成员
1 (*结构体指针变量名).成员
2 结构体指针变量名‐>成员
结构体内存分配
规则1:以多少个字节为单位开辟内存
给结构体变量分配内存的时候,会去结构体变量中找基本类型的成员
哪个基本类型的成员占字节数多,就以它大大小为单位开辟内存,
在gcc中出现了double类型的例外
(1):成员中只有char型数据 ,以1字节为单位开辟内存。
(2):成员中出现了short 类型数据,没有更大字节数的基本类型数据。
以2字节为单位开辟内存
(3):出现了int 、float 没有更大字节的基本类型数据的时候以4字节为单位开辟内存。
(4):出现了double类型的数据
情况1:
在vc里,以8字节为单位开辟内存。
情况2:
在gcc里,以4字节为单位开辟内存。
无论是那种环境,double型变量,占8字节。
(5):如果在结构体中出现了数组,数组可以看成多个变量的集合。
如果出现指针的话,没有占字节数更大的类型的,以4字节为单位开辟内存。
(6):在内存中存储结构体成员的时候,按定义的结构体成员的顺序存储。
规则2:字节对齐
(1):char 1字节对齐 ,即存放char型的变量,内存单元的编号是1的倍数即可。
(2):short 2字节对齐 ,即存放short int 型的变量,起始内存单元的编号是2的倍
数即可。(3):int 4字节对齐 ,即存放int 型的变量,起始内存单元的编号是4的倍数即
可
(4):long 在32位平台下,4字节对齐 ,即存放long int 型的变量,
起始内存单元的编号是4的倍数即可
(5):float 4字节对齐 ,即存放float 型的变量,起始内存单元的编号是4的倍数即
可
(6):double
a.vc环境下
8字节对齐,即存放double型变量的起始地址,必须是8的倍数,double变量
占8字节
b.gcc环境下
4字节对齐,即存放double型变量的起始地址,必须是4的倍数,double变量
占8字节。
注意:
当结构体成员中出现数组的时候,可以看成多个变量。
开辟内存的时候,从上向下依次按成员在结构体中的位置顺序开辟空间
给结构体变量分配内存的时候,会去结构体变量中找基本类型的成员
哪个基本类型的成员占字节数多,就以它大大小为单位开辟内存,
在gcc中出现了double类型的例外
(1):成员中只有char型数据 ,以1字节为单位开辟内存。
(2):成员中出现了short 类型数据,没有更大字节数的基本类型数据。
以2字节为单位开辟内存
(3):出现了int 、float 没有更大字节的基本类型数据的时候以4字节为单位开辟内存。
(4):出现了double类型的数据
情况1:
在vc里,以8字节为单位开辟内存。
情况2:
在gcc里,以4字节为单位开辟内存。
无论是那种环境,double型变量,占8字节。
(5):如果在结构体中出现了数组,数组可以看成多个变量的集合。
如果出现指针的话,没有占字节数更大的类型的,以4字节为单位开辟内存。
(6):在内存中存储结构体成员的时候,按定义的结构体成员的顺序存储。
规则2:字节对齐
(1):char 1字节对齐 ,即存放char型的变量,内存单元的编号是1的倍数即可。
(2):short 2字节对齐 ,即存放short int 型的变量,起始内存单元的编号是2的倍
数即可。(3):int 4字节对齐 ,即存放int 型的变量,起始内存单元的编号是4的倍数即
可
(4):long 在32位平台下,4字节对齐 ,即存放long int 型的变量,
起始内存单元的编号是4的倍数即可
(5):float 4字节对齐 ,即存放float 型的变量,起始内存单元的编号是4的倍数即
可
(6):double
a.vc环境下
8字节对齐,即存放double型变量的起始地址,必须是8的倍数,double变量
占8字节
b.gcc环境下
4字节对齐,即存放double型变量的起始地址,必须是4的倍数,double变量
占8字节。
注意:
当结构体成员中出现数组的时候,可以看成多个变量。
开辟内存的时候,从上向下依次按成员在结构体中的位置顺序开辟空间
0 条评论
下一页