C 语言指针与数组重点总结
1. 数组长度 vs 字符串长度
关键点:
- 数组长度
sizeof(arr)包含\0 - 字符串长度
strlen(p)不包含\0
示例:
char s[] = "china"; // sizeof(s)=6, strlen(s)=5
char *p = s; // strlen(p)=5
易错题:
// 38题:C选项错误原因
char s[] = "china";
char *p = s;
// 数组s长度=6,p指向的字符串长度=5 → 不相等
2. 二维数组与指针赋值
关键点:
- 二维数组名
a的类型是int (*)[N] - 不能直接赋给
int *类型指针
示例:
int a[4][10], *p;
p = a; // ❌ 错误:类型不兼容
p = a[0]; // ✅ 正确:a[0]是int*
p = &a[0][0]; // ✅ 正确
p = (int*)a; // ✅ 正确但需强制转换
易错题:
// 35题:A选项错误
int a[4][10], *p;
p = a; // ❌ 编译错误/警告
3. 指针数组与字符串常量
关键点:
char *a[]存放的是字符串常量的地址- 字符串常量以
\0结尾,长度要+1
示例:
char *a[2] = {"abcd", "ABCD"};
// a[0]存放"abcd"的首地址,字符串实际长度=5
易错题:
// 28题:C选项错误原因
char *a[2] = {"abcd", "ABCD"};
// "abcd"有5个字符(含\0),不是4个 → C错误
4. 函数指针的赋值
关键点:
- 函数名本身就是函数指针
&函数名和函数名等价- 直接使用函数名更常见
示例:
int max(int a, int b);
int (*p)(int, int);
p = max; // ✅ 常用写法
p = &max; // ✅ 语法正确但不常用
*p = max; // ❌ p未初始化
易错题:
// 12题:选A不选C的原因
int max(), (*p)();
p = max; // ✅ 标准答案
p = &max; // ✅ 语法对,但考试不选
5. 指针运算与输出
关键点:
p+2表示地址运算- 用
%d打印地址无意义,应用%p
示例:
char str[] = "abc", *p = str;
printf("%p\n", p+2); // ✅ 打印地址
printf("%c\n", *(p+2)); // ✅ 打印字符'c'
6. 字符串赋值操作
关键点:
- 字符数组需要空间足够(包含
\0) - 字符指针可直接指向字符串常量
示例:
char str[5] = "abcde"; // ❌ 空间不足(需要6字节)
char *str = "abcde"; // ✅ 正确
char *str; scanf("%s", str); // ❌ str未初始化
7. 复杂指针声明
关键点:
int (*p)[5]- 指向数组的指针int *p[5]- 指针数组
示例:
int (*p)[5]; // p指向包含5个int的数组
int *p[5]; // p是包含5个int指针的数组
记忆技巧
- 数组vs字符串长度:想象数组是"房子"(包含所有),字符串是"住的人"(不包含空房间)
- 二维数组指针:
a指向"一行",a[0]指向"一个元素" - 函数指针:函数名就是地址,取地址是多此一举
- 字符串常量:总是多一个
\0,声明数组时要预留空间
这些规则通过多做练习和调试会逐渐熟悉!