变量
C语言基本数据类型
数组和指针
数组指针和指针数组
数组指针
数组指针,又称为行指针
例如
int (*ptr)[2]
,从形式上看,这是一个指针变量,指向包含两个元素的数组1
2
3
4
5
6
7
8int a[3][4] = {
{1, 11, 21, 31},
{2, 12, 22, 32},
{3, 13, 23, 33}
};
int (*p)[4] = a; // 定义了一个数组指针
p = a; // 指针p指向二维数组第0行的首地址
p++; // 此时,指针p指向二维数组第1行的首地址指针数组
指针数组,顾名思义,即为存放指针类型的数组。
二级指针int** p本质上就是一个指针数组,
1
2
3
4
5
6
7
8
9
10char str1[] = "Panda";
char str2[] = "Pikachu";
char str3[] = "Wangwangdog";
char str4[] = "Tortoise";
char *p[] = {str1, str2, str3, str4}; // 指针数组
for (int i = 0; i < sizeof(p) / sizeof(p[0]); i++) {
printf("%s\n", p[i]); // 等价于 printf("%s\n", *(p + i));
}程序运行结果为:
1
2
3
4Panda
Pikachu
Wangwangdog
Tortoise1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17int a[3][4] = {
{1, 11, 21, 31},
{2, 12, 22, 32},
{3, 13, 23, 33}
};
int *p[4];
/* int型指针数组的初始化 */
for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++) {
p[i] = a[i];
for (int j = 0; j < sizeof(a[i]) / sizeof(a[i][0]); j++) {
printf("%d ", *(p[i] + j));
}
printf("\n");
}程序运行结果为:
1
2
31 11 21 31
2 12 22 32
3 13 23 33
字符串
结构体
结构体对齐原则
#pragma pack(n)对齐数据结构大小的计算方法:
程序员可以通过预编译命令#pragma pack(n),n=1,2,4,8,16改变对齐系数;
结构体中每个数据都应满足:首地址%min{该数据自身长度,n} =0;
整个结构体长度对齐,即:(本条规则为个人总结,程序验证) 结构体总长度%min{ max{结构体中占用内存最大的数据类型的长度},n } =0;
例:struct Data数据元素在内存中的分布情况(以32位平台为例)
1
2
3
4
5
6
7
8struct Data{
char a;
short b;
int c;
double d;
char e;
char f;
};不同情形下Data元素在内存中的分布情况
#pragma pack(2) | #pragma pack(4) |
---|---|
![]() |
![]() |
输入输出
格式化输入输出
格式化字符串
sprintf函数
sprintf()是字符串格式化命令,函数声明为int sprintf (char *__stream, const char *__format, ...)
,所属头文件为stdio.h,功能主要是把格式化后的数据写入到__stream指向的内存空间。
示例:
1 |
|
程序运行结果为:
1 | Hello, everyone! My name is Panda. I am 18 years old. I like to play badminton. |
sscanf函数
sscanf()是读取格式化字符串命令,函数声明为int sscanf(const char *__source, const char *__format, ...)
,所属头文件为stdio.h,功能主要是把__source指向的字符串按照格式化进行分解操作;
sscanf()函数可以通过字符串匹配分解字符串,基本格式为%[set],一般有以下两种情况:
- %[^set] 表示需要在输入字符串中匹配不在set集合中的其他字符,遇见set集合中的字符时,匹配结束;
- %[set] 表示需要在输入字符串中匹配在set集合中的字符,遇见不属于set集合中的字符时,匹配结束;
- 此外,sscanf()常用的格式还包括%*[set],表示忽略set集合中的字符
示例:
1 |
|
程序运行结果为:
1 | Panda |