C语言深入理解指针(六):sizeof与strlen的那些事儿

宝子们,我们在指针的江湖已经驰骋了好多章啦,从指针基础、回调函数,到函数指针数组和 qsort 的模拟实现,一路升级打怪,相信大家对指针的理解已经越来越深入咯。今天这章,咱来点稍微轻松但又超实用的内容,聊聊 sizeof 和 strlen 这两个看似简单却很容易被误解的小家伙,再结合之前学的指针知识,把数组和指针、指针运算这些经典笔试题都搞定!新手友好,保证让你学完就能上场应对面试和考试!

 

 

sizeof 和 strlen:长得像却性格迥异的两兄弟

 

sizeof:内存空间的测量仪

 

sizeof 是个操作符,它的任务就是计算变量或数据类型所占的内存空间大小,返回值是 size_t 类型(一般就是 unsigned int)。它的重点在于“内存空间”,不管这空间里存的是啥数据,它都照单全收,直接告诉你这块地儿有多大。

 

比如常见的:

int a = 10;

printf("%zu\n", sizeof(a)); // 输出 int 类型变量的内存空间大小

printf("%zu\n", sizeof(int)); // 同样输出 int 类型的内存空间大小

 

这里,`sizeof(a)`和`sizeof(int)`输出的结果一样,因为 a 是 int 类型变量,它们都告诉你在你的系统里,一个 int 类型占多少字节的内存空间。这个大小通常是固定的,比如在大多数系统里 int 占 4 字节,char 占 1 字节,double 占 8 字节等。

 

strlen:字符串长度的计数员

 

strlen 可是标准库函数(定义在 string.h 里),它的任务是数一数字符串里到底有多少个字符,直到遇到终止符`\0`为止。它的重点在于“字符串的有效字符个数”,只关心从字符串开头到`\0`这段距离有多少个字符。

 

char str[] = "hello";

printf("%zu\n", strlen(str)); // 输出 5,因为 "hello" 有 5 个字符,不包括结尾的 '\0'

 

这里,`strlen(str)`不管 str 整个数组占多大内存,它只数到`\0`就停,告诉你有效字符的个数。

 

 

两兄弟的关键区别

• sizeof 是编译期就确定的,它直接计算类型或变量的内存占用大小。比如`sizeof(int)`,编译器直接根据系统设定的 int 类型大小(比如 4 字节)返回结果,和变量实际存的值无关。

 

• strlen 是运行时才干活的,它得一个字符一个字符地数,直到碰到`\0`。要是字符串里`\0`跑偏了,或者根本没`\0`,它就数错了。

 

char arr[10] = "hi";

printf("%zu %zu\n", sizeof(arr), strlen(arr)); // 输出 10 2

 

这里,`sizeof(arr)`是 10,因为 arr 是个能存 10 个字符的数组,不管里面实际写了多少字符。`strlen(arr)`是 2,因为"hi"两个字符后面跟着`\0`,计数停了。

 

数组和指针笔试题解析:那些年让我们头疼的选择题

数组和指针在笔试里总是爱“伪装”成各种陷阱题来考察大家。别怕,咱们用之前学的指针知识,把这些题都拿下!

 

题目 1:数组名到底是不是指针?

 

题目:`int arr[5];`中的 arr 是什么?是指针吗?

 

答:arr 是数组名,本质上是个指针常量,指向数组首元素的地址。但 arr 和普通指针变量有区别,arr 的值不能被修改(比如`arr++`是非法的),它天生就绑定在数组首元素的地址上。

 

 

题目 2:数组和指针做函数参数时有啥区别?

 

题目:下面两个函数定义有什么区别?

 

void func1(int arr[]);

void func2(int *p);

 

答:其实它们本质上是一样的!在函数参数里,`int arr[]`会退化成`int *p`,都是传递数组首元素的地址。但是,`int arr[]`的写法更像在提醒“这个指针和数组有关哦,可能会用到数组元素的连续性”。

 

题目 3:二维数组作为函数参数时的坑

 

题目:下面的函数定义哪些是对的?哪些是错的?

 

void func3(int arr[3][4]);

void func4(int arr[][]);

void func5(int *arr[4]);

 

答:`func3`是对的,它明确告诉编译器,每一行数组的列数是 4,这样在通过指针运算访问元素时,编译器能准确计算偏移量。`func4`是错的,因为 C 语言要求在多维数组参数中,除了第一维可以不写大小外,后面的维度大小必须写明,不然编译器不知道怎么算偏移。`func5`是对的,它定义的是一个指针数组,每个元素是指向 int 的指针,和二维数组有点像但不完全一样,主要用于存储一组指针。

 

指针运算笔试题解析:加减乘除的指针版

 

指针运算的笔试题最爱考察越界访问、指针类型和运算结果的关系等。咱们拿几个经典题来练练手。

 

题目 1:指针加减法的陷阱

 

题目:下面代码会输出什么?

 

int arr[] = {1,2,3,4,5};

int *p = arr;

p = p + 3;

p = p - 2;

printf("%d", *p);

 

答:`p = arr`后,p 指向第一个元素 1。`p = p + 3`后,p 向后移了 3 个 int 的位置,指向第 4 个元素 4。`p = p - 2`后,p 向前移了 2 个 int 的位置,指向第 2 个元素 2。所以输出 2。

 

题目 2:不同数据类型指针运算的差异

 

题目:下面代码会输出什么?

 

char c = 'A';

char *pc = &c;

int *pi = (int *)pc;

pi++;

printf("%d", (int)pc);

 

答:这里有点复杂。`pc`最初指向字符变量 c 的地址。`pi`被强制转换为 int 指针,和 pc 指向同一地址。`pi++`会让 pi 向后移动一个 int 的字节大小(假设是 4 字节),而`pc`如果也加 1,只会移动 1 字节。但题目最后问的是`pc`的原始地址值(没变),所以输出结果其实是 c 的原始内存地址,以 int 形式打印出来。

 

总结

宝子们,今天咱们把 sizeof 和 strlen 的区别、数组和指针的笔试题、指针运算的笔试题都梳理了一遍。sizeof 是内存空间测量仪,strlen 是字符串长度计数员,二者干的活儿完全不同。数组和指针在笔试里总爱伪装,但我们用指针的基本知识就能识破它们。指针运算看似简单,但涉及到不同数据类型时,得特别留意字节移动的差异。今天的内容都是笔试和面试里的常客,新手友好,学完就能上场应对啦。是不是感觉自己的 C 语言武功又精进了?面对笔试题的时候心里更有底啦!

 

宝子们,今天的内容是不是让你对 sizeof 和 strlen 的区别一下就明白了呢?有没有哪道笔试题让你曾经栽过跟头,现在终于想通了?或者你还有新的笔试题想分享给大家?别犹豫,赶紧到评论区和大家分享你的感悟和疑问吧!说不定你的问题,就是别人的心头大患呢!下次,咱继续在指针的江湖里闯荡,把剩下的宝藏知识都一网打尽!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值