目录
九、指针
1.指针变量的定义和初始化
2.间接寻址符*
3.按值调用和按址调用
4.实例
5.函数指针
6.指针变量和其它类型变量的对比
十、字符串
1.字符串常量
2.字符串的存储
3.字符指针
4.字符串的访问和输入/输出
5.字符串处理函数
(1)strlen(计算字符串长度)
(2)strcpy(字符串复制)
(3) strcat(字符串连接)
(4)strcmp(字符串比较)
(5)实例
(6)其它函数
6.向函数传递字符串
7.自己实现字符串处理函数
(1)MyStrcpy
(2)MyStrlen
(3)MyStrcat
十一、 指针和数组
1.指针和一维数组的关系
2.指针和二维数组的关系
3.指针或数组参数传参注意
4.指针数组
gets和puts的使用
5.指针数组用来表示命令行参数
6.C程序的内存映像
7.动态内存分配函数
十二、结构体
1.结构体类型的声明
2.结构体变量的定义
3.用typedef定义数据类型
4.结构体变量的初始化
5.嵌套的结构体
6.结构体变量的引用
7.结构体所占内存的字节数
8.结构体数组的定义和初始化
9.结构体指针的定义和初始化
10.向函数传递结构体
十三、共用体
十四、枚举数据类型
九、指针
1.指针变量的定义和初始化
指针变量使用之前必须初始化
2.间接寻址符*
引用指针所指向的变量的值称为指针的解引用
3.按值调用和按址调用
指针变量作函数参数可以修改实参的值
4.实例
当函数需要给回主函数两个或两个以上参数时,无法使用return返回值进行返回,就可以采用指针变量传参的方式
5.函数指针
使用函数指针
6.指针变量和其它类型变量的对比
十、字符串
1.字符串常量
2.字符串的存储
3.字符指针
4.字符串的访问和输入/输出
对于scanf来说,空格、回车或制表(Tab)符是输入数据的分隔符,因而不能被读入,输入遇到这些字符时,系统认为字符串输入结束
例如:
fgets()
函数的最大读取大小是其“第二个参数减1
”,这是由于字符串是以’\0’
为结束符的,fgets()
为了保证输入内容的字符串格式
,当输入的数据大小超过了第二个参数
指定的大小的时候,fgets()
会仅仅读取前面的“第二个参数减1
”个字符,而预留1个字符
的空间来存储字符串结束符’\0’
5.字符串处理函数
(1)strlen(计算字符串长度)
结果是5
(2)strcpy(字符串复制)
(3) strcat(字符串连接)
(4)strcmp(字符串比较)
(5)实例
(6)其它函数
6.向函数传递字符串
7.自己实现字符串处理函数
(1)MyStrcpy
(2)MyStrlen
(3)MyStrcat
十一、 指针和数组
1.指针和一维数组的关系
数组名是一个常量指针,不能修改该指针的指向
指针可当数组名使用
2.指针和二维数组的关系
行地址
列地址
行指针
列指针
二维数组传入函数
3.指针或数组参数传参注意
4.指针数组
gets和puts的使用
1、gets() 的作用是从键盘上读取字符串,跟scanf() 相似,但又有所不同。
gets() 函数的用法:
gets(字符串的首地址);
例:
char str [20]; .
gets(str);
须要注意的是:
(1) gets() 可以接收空格、Tab键, 碰到回车键输入才结束;而scanf碰到空格、回车、Tab键 都会结束输入。
(2) gets() 和scanf() 都不能检测越界。
2、puts() 的作用是 向显示屏输出字符串并换行。
用法:
puts (字符串的首地址) ;
例:
char[]=" helloworld";
pus(str);
printf需要添加"\n'用来换行,而puts在 输出的时候会将字符串末尾的\0'自动换成\n'
5.指针数组用来表示命令行参数
6.C程序的内存映像
7.动态内存分配函数
malloc()
calloc
注意 :int (*p)[3]和int *p[3]的区别如下:
1. 声明的含义
-
int (*p)[3]:
- 这是一个指针,指向一个包含 3 个
int
元素的数组。 p
是一个指针,它所指向的数据类型是int[3]
(一个有 3 个int
元素的数组)。
- 这是一个指针,指向一个包含 3 个
-
int *p[3]:
- 这是一个数组,数组的元素是
int
类型的指针。 p
是一个数组,该数组包含 3 个元素,每个元素的类型是int*
(指向int
的指针)。
- 这是一个数组,数组的元素是
2. 内存布局和使用示例
-
int (*p)[3]:
-
#include <stdio.h> int main() { int arr[2][3] = {{1, 2, 3}, {4, 5, 6}}; int (*p)[3]; // 定义一个指针,指向一个包含 3 个 int 元素的数组 p = arr; // 让 p 指向 arr 的第一行 // 访问元素 for (int i = 0; i < 2; ++i) { for (int j = 0; j < 3; ++j) { printf("%d ", (*p)[j]); // 先解引用 p 得到数组,再通过 [] 访问元素 } p++; // 指向下一个 3 元素的数组 } return 0; }
- 在这个例子中,
p
是一个指针,它可以指向一个int[3]
类型的数组。当我们将p
指向arr
的第一行时,通过(*p)[j]
来访问元素。p++
操作会让p
指向下一个包含 3 个int
的数组(在二维数组中,即下一行)。
int *p[3]:
#include <stdio.h>
int main() {
int a = 1, b = 2, c = 3;
int *p[3]; // 定义一个数组,元素是 int 指针
p[0] = &a;
p[1] = &b;
p[2] = &c;
// 访问元素
for (int i = 0; i < 3; ++i) {
printf("%d ", *(p[i])); // 先通过 [] 获取指针,再解引用
}
return 0;
}
- 这里
p
是一个数组,存储了 3 个int
指针。p[0]
、p[1]
和p[2]
分别存储了a
、b
和c
的地址,通过*(p[i])
来访问它们指向的int
元素。
3. 指针运算和内存地址
-
int (*p)[3]:
- 当对
p
进行指针运算(如p++
)时,p
的地址会增加3 * sizeof(int)
,因为它指向的是一个包含 3 个int
元素的数组,每次移动到下一个这样的数组。
- 当对
-
int *p[3]:
- 对于
p[i]
(其中i
从 0 到 2),p[i]
是int*
指针,当对p[i]
进行指针运算时,其地址会增加sizeof(int)
,因为它们指向的是单个int
元素。
- 对于
4. 总结
int (*p)[3]
强调的是一个指针,该指针专门指向包含 3 个int
元素的数组,适合用于处理二维数组,其中第二维大小固定为 3。int *p[3]
是一个数组,其中存储的元素是int
指针,可存储 3 个不同int
变量的地址,可指向不同位置的int
元素,使用更灵活,可指向不同长度的int
数组或不同的int
元素。
十二、结构体
1.结构体类型的声明
这时还没有声明结构体变量
2.结构体变量的定义
3.用typedef定义数据类型
4.结构体变量的初始化
5.嵌套的结构体
6.结构体变量的引用
7.结构体所占内存的字节数
8.结构体数组的定义和初始化
9.结构体指针的定义和初始化
10.向函数传递结构体
例题
十三、共用体