目录
-
sizeof和strlen对比
• 核心区别与使用场景 -
数组与指针笔试题解析
• 一维数组
• 字符数组
• 二维数组 -
指针运算经典题目
• 指针偏移与地址计算
• 结构体指针运算
• 多维数组与复杂指针
一、sizeof和strlen对比
1.1 核心区别
sizeof | strlen |
---|---|
操作符,计算内存空间大小(字节) | 库函数,统计字符串长度(\0 前的字符数) |
不关心数据内容,仅计算内存占用 | 依赖\0 结束符,可能越界访问 |
操作数可以是变量或类型 | 参数必须是指向字符数组的指针 |
1.2 代码示例
#include <stdio.h>
#include <string.h>
int main() {
char arr[] = {'a', 'b', 'c'}; // 无结束符\0
char str[] = "abc"; // 隐含\0
printf("sizeof(arr) = %d\n", sizeof(arr)); // 输出3(数组总大小)
printf("strlen(arr) = %d\n", strlen(arr)); // 随机值(越界查找\0)
printf("sizeof(str) = %d\n", sizeof(str)); // 输出4(包含\0)
printf("strlen(str) = %d\n", strlen(str)); // 输出3
return 0;
}
二、数组与指针笔试题解析
2.1 一维数组
int a[] = {1, 2, 3, 4};
printf("%d\n", sizeof(a)); // 16(4个int,每个4字节)
printf("%d\n", sizeof(a+0)); // 4/8(数组退化为指针,地址大小)
printf("%d\n", sizeof(*a)); // 4(首元素的大小)
2.2 字符数组
代码1(无结束符\0
):
char arr[] = {'a', 'b', 'c', 'd', 'e', 'f'};
printf("%d\n", strlen(arr)); // 随机值(未遇到\0前持续越界)
代码3(含结束符\0
):
char arr[] = "abcdef";
printf("%d\n", sizeof(arr)); // 7(6字符+1个\0)
printf("%d\n", strlen(arr)); // 6
2.3 二维数组
int a[3][4] = {0};
printf("%d\n", sizeof(a)); // 48(3*4个int)
printf("%d\n", sizeof(a[0])); // 16(第一行数组的大小)
printf("%d\n", sizeof(a[0]+1)); // 4/8(a[0]退化为指针,+1偏移)
三、指针运算笔试题解析
3.1 题目1:指针偏移与数组名
int a[5] = {1, 2, 3, 4, 5};
int *ptr = (int*)(&a + 1); // &a是数组指针,+1跳过整个数组
printf("%d, %d\n", *(a+1), *(ptr-1)); // 输出2, 5
3.2 题目2:结构体指针运算
struct Test {
int Num;
char *pcName;
short sDate;
char cha[2];
short sBa[4];
} *p = (struct Test*)0x100000;
printf("%p\n", p + 0x1); // 0x100014(结构体大小20字节)
printf("%p\n", (unsigned long)p + 1); // 0x100001(整数+1)
printf("%p\n", (unsigned int*)p + 1); // 0x100004(int*步长4字节)
3.3 题目3:多维数组与复杂指针
int a[5][5];
int (*p)[4] = a; // p指向int[4]类型
// p[4][2] 相当于 *(*(p+4)+2)
// a[4][2] 的地址与p[4][2]的地址差为4字节(指针类型不同导致偏移差异)
printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]); // 输出-4(地址差为-4)
总结
-
数组名含义:
•sizeof(arr)
和&arr
中,arr
代表整个数组;其他情况下退化为首元素地址。 -
指针类型决定偏移步长:
•int*
每次偏移4字节,char*
偏移1字节,结构体指针偏移整个结构体大小。 -
strlen与sizeof:
•strlen
依赖\0
,sizeof
计算总内存(含\0
)。