第16讲:深入理解指针(6)——sizeof vs strlen 与 指针笔试题深度解析
🧭 第16讲:深入理解指针(6)——sizeof
vs strlen
与 指针笔试题深度解析 🔍🧠
掌握内存计算本质,攻克C语言指针与数组的“面试杀手题”!
📚 目录
sizeof
与strlen
的对比:本质差异 ⚖️- 数组和指针笔试题解析:从一维到二维 🧩
- 指针运算笔试题解析:高阶指针迷宫 🌀
- 核心知识点总结 ✅
- 下一讲预告 🚀
sizeof
与 strlen
的对比:本质差异 ⚖️
🔢 sizeof` 示例代码
#include <stdio.h>int main() {int a = 10;printf("%d\n", sizeof(a)); // 输出: 4printf("%d\n", sizeof a); // 输出: 4printf("%d\n", sizeof(int)); // 输出: 4return 0;
}
📏 strlen
示例代码
#include <stdio.h>
#include <string.h>int main() {char arr1[3] = {'a', 'b', 'c'};char arr2[] = "abc";printf("%d\n", strlen(arr1)); // 未定义行为(越界)printf("%d\n", strlen(arr2)); // 输出: 3printf("%d\n", sizeof(arr1)); // 输出: 3printf("%d\n", sizeof(arr2)); // 输出: 4return 0;
}
数组和指针笔试题解析 🧩
📐一维数组
#include <stdio.h>int main() {int a[] = {1, 2, 3, 4};printf("sizeof(a) = %zu\n", sizeof(a)); // 16printf("sizeof(a+0) = %zu\n", sizeof(a+0)); // 4printf("sizeof(*a) = %zu\n", sizeof(*a)); // 4printf("sizeof(a+1) = %zu\n", sizeof(a+1)); // 4printf("sizeof(a[1]) = %zu\n", sizeof(a[1])); // 4printf("sizeof(&a) = %zu\n", sizeof(&a)); // 4printf("sizeof(*&a) = %zu\n", sizeof(*&a)); // 16printf("sizeof(&a+1) = %zu\n", sizeof(&a+1)); // 4printf("sizeof(&a[0]) = %zu\n", sizeof(&a[0])); // 4printf("sizeof(&a[0]+1) = %zu\n", sizeof(&a[0]+1)); // 4return 0;
}
🔤 字符数组
代码1:char arr[] = {'a','b','c','d','e','f'};
(无 \0
)
#include <stdio.h>int main() {char arr[] = {'a', 'b', 'c', 'd', 'e', 'f'};printf("sizeof(arr) = %zu\n", sizeof(arr)); // 6printf("sizeof(arr+0) = %zu\n", sizeof(arr+0)); // 4printf("sizeof(*arr) = %zu\n", sizeof(*arr)); // 1printf("sizeof(arr[1]) = %zu\n", sizeof(arr[1])); // 1printf("sizeof(&arr) = %zu\n", sizeof(&arr)); // 4printf("sizeof(&arr+1) = %zu\n", sizeof(&arr+1)); // 4printf("sizeof(&arr[0]+1) = %zu\n", sizeof(&arr[0]+1)); // 4return 0;
}
代码2:strlen(arr)
系列(⚠️ 危险!)
#include <stdio.h>
#include <string.h>int main() {char arr[] = {'a', 'b', 'c', 'd', 'e', 'f'};printf("strlen(arr) = %zu\n", strlen(arr)); // 未定义行为printf("strlen(arr+0) = %zu\n", strlen(arr+0)); // 未定义行为// printf("strlen(*arr) = %zu\n", strlen(*arr)); // 编译错误// printf("strlen(arr[1]) = %zu\n", strlen(arr[1])); // 编译错误printf("strlen(&arr) = %zu\n", strlen(&arr)); // 未定义行为printf("strlen(&arr+1) = %zu\n", strlen(&arr+1)); // 未定义行为printf("strlen(&arr[0]+1) = %zu\n", strlen(&arr[0]+1)); // 未定义行为return 0;
}
代码3:char arr[] = "abcdef";
(有 \0
)
#include <stdio.h>int main() {char arr[] = "abcdef";printf("sizeof(arr) = %zu\n", sizeof(arr)); // 7printf("sizeof(arr+0) = %zu\n", sizeof(arr+0)); // 4printf("sizeof(*arr) = %zu\n", sizeof(*arr)); // 1printf("sizeof(arr[1]) = %zu\n", sizeof(arr[1])); // 1printf("sizeof(&arr) = %zu\n", sizeof(&arr)); // 4printf("sizeof(&arr+1) = %zu\n", sizeof(&arr+1)); // 4printf("sizeof(&arr[0]+1) = %zu\n", sizeof(&arr[0]+1)); // 4return 0;
}
代码4:strlen(arr)
系列
#include <stdio.h>
#include <string.h>int main() {char arr[] = "abcdef";printf("strlen(arr) = %zu\n", strlen(arr)); // 6printf("strlen(arr+0) = %zu\n", strlen(arr+0)); // 6printf("strlen(&arr[0]+1) = %zu\n", strlen(&arr[0]+1)); // 5return 0;
}
代码5:char *p = "abcdef";
#include <stdio.h>int main() {char *p = "abcdef";printf("sizeof(p) = %zu\n", sizeof(p)); // 4printf("sizeof(p+1) = %zu\n", sizeof(p+1)); // 4printf("sizeof(*p) = %zu\n", sizeof(*p)); // 1printf("sizeof(p[0]) = %zu\n", sizeof(p[0])); // 1printf("sizeof(&p) = %zu\n", sizeof(&p)); // 4printf("sizeof(&p+1) = %zu\n", sizeof(&p+1)); // 4printf("sizeof(&p[0]+1) = %zu\n", sizeof(&p[0]+1)); // 4return 0;
}
代码6:strlen(p)
系列
#include <stdio.h>
#include <string.h>int main() {char *p = "abcdef";printf("strlen(p) = %zu\n", strlen(p)); // 6printf("strlen(p+1) = %zu\n", strlen(p+1)); // 5printf("strlen(&p) = %zu\n", strlen(&p)); // 未定义行为printf("strlen(&p+1) = %zu\n", strlen(&p+1)); // 未定义行为printf("strlen(&p[0]+1) = %zu\n", strlen(&p[0]+1)); // 5return 0;
}
📊 二维数组
#include <stdio.h>int main() {int a[3][4] = {0};printf("sizeof(a) = %zu\n", sizeof(a)); // 48printf("sizeof(a[0][0]) = %zu\n", sizeof(a[0][0])); // 4printf("sizeof(a[0]) = %zu\n", sizeof(a[0])); // 16printf("sizeof(a[0]+1) = %zu\n", sizeof(a[0]+1)); // 4printf("sizeof(*(a[0]+1)) = %zu\n", sizeof(*(a[0]+1))); // 4printf("sizeof(a+1) = %zu\n", sizeof(a+1)); // 4printf("sizeof(*(a+1)) = %zu\n", sizeof(*(a+1))); // 16printf("sizeof(&a[0]+1) = %zu\n", sizeof(&a[0]+1)); // 4printf("sizeof(*(&a[0]+1)) = %zu\n", sizeof(*(&a[0]+1))); // 16printf("sizeof(*a) = %zu\n", sizeof(*a)); // 16printf("sizeof(a[3]) = %zu\n", sizeof(a[3])); // 16return 0;
}
指针运算笔试题解析 🌀
🧩 题目1
#include <stdio.h>int main() {int a[5] = {1, 2, 3, 4, 5};int *ptr = (int *)(&a + 1);printf("%d,%d\n", *(a + 1), *(ptr - 1)); // 输出: 2,5return 0;
}
🧩 题目2(X86环境)
#include <stdio.h>struct Test {int Num;char *pcName;short sDate;char cha[2];short sBa[4];
};int main() {struct Test *p = (struct Test*)0x100000;printf("%p\n", p + 0x1);printf("%p\n", (unsigned long)p + 0x1);printf("%p\n", (unsigned int*)p + 0x1);return 0;
}
🧩 题目3
#include <stdio.h>int main() {int a[3][2] = {(0,1), (2,3), (4,5)};int *p;p = a[0];printf("%d\n", p[0]); // 输出: 1return 0;
}
🧩 题目4
#include <stdio.h>int main() {int a[5][5];int (*p)[4];p = (int (*)[4])a;printf("%p,%d\n", &p[4][2], &p[4][2] - &a[4][2]);return 0;
}
🧩 题目5
#include <stdio.h>int main() {int aa[2][5] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};int *ptr1 = (int *)(&aa + 1);int *ptr2 = (int *)(*(aa + 1));printf("%d,%d\n", *(ptr1 - 1), *(ptr2 - 1)); // 输出: 10,5return 0;
}
🧩 题目6
#include <stdio.h>int main() {char *a[] = {"work", "at", "alibaba"};char **pa = a;pa++;printf("%s\n", *pa); // 输出: atreturn 0;
}
🧩 题目7
#include <stdio.h>int main() {char *c[] = {"ENTER", "NEW", "POINT", "FIRST"};char **cp[] = {c+3, c+2, c+1, c};char ***cpp = cp;printf("%s\n", **++cpp); // POINTprintf("%s\n", *--*++cpp + 3); // ERprintf("%s\n", *cpp[-2] + 3); // RSTprintf("%s\n", cpp[-1][-1] + 1); // EWreturn 0;
}
✅ 核心知识点总结
主题 | 关键点 |
---|---|
sizeof vs strlen | sizeof 看大小,strlen 找 \0 ;sizeof 编译时,strlen 运行时 |
数组名本质 | 仅 sizeof(数组名) 和 &数组名 代表整个数组,其余皆为首元素地址 |
指针运算 | 指针加减基于其指向类型的大小;&数组名 与 数组名 地址同但类型异 |
二维数组 | a[i] 是一维数组,sizeof(a[i]) 计算一行大小 |
笔试题技巧 | 明确类型、地址、值三者关系;警惕越界与未定义行为 |
🎯 指针与数组是C语言的基石,也是面试的“试金石”。
你已系统掌握 sizeof
/strlen
差异与高阶指针运算,是时候挑战动态内存的深水区了!💪🔥
💬 需要本讲的 笔试题PDF版 / 动态内存预习资料 / 指针图解手册?欢迎继续提问,我为你准备!