sizeof运算与strlen函数的面试笔试题(排版很舒服)

简介: sizeof运算与strlen函数的面试笔试题(排版很舒服)

1.一维数组

大家可以先做一下,下面有解释。

#include "stdio.h"
 int main()
 {
     int a[] = {1,2,3,4};
     printf("%d\n",sizeof(a));
     printf("%d\n",sizeof(a+0));
     printf("%d\n",sizeof(*a));
     printf("%d\n",sizeof(a+1));
     printf("%d\n",sizeof(a[1]));
     printf("%d\n",sizeof(&a));
     printf("%d\n",sizeof(*&a));
     printf("%d\n",sizeof(&a+1));
     printf("%d\n",sizeof(&a[0]));
     printf("%d\n",sizeof(&a[0]+1));
     return 0;
 }



9bea205b24f743e3badbaf46edc4e6de.png


1.1  sizeof( a )

我们首先知道a是数组名,因为数组名代表首元素地址,但是a是在sizeof里,代表整个数组,也就是说sizeof计算的是整个数组的大小,数组a元素有4个,数据类型是int,所以结果为4*4=16字节。

1.2 sizeof( a + 0 )


我们首先看到sizeof里面是a+0,并不是单独的a,所以这里的a代表的是首元素地址,而不是整个数组,所以a+0还是首元素地址,既然sizeof里面是地址/指针。又因为指针占的是4/8字节,所以结果为4/8字节(32位机器是4字节,64位机器是8字节


1.3 sizeof( *a )

首先a是首元素地址,*a则是对首元素地址的解引用,取出来的是首元素,也就是a[0]是int类型,占4个字节,所以结果是4字节

1.4 sizeof( a + 1 )

sizeof里不是单独的a,所以a是首元素地址,a+1就是第二个元素的地址,也就是&a[1],是个指针,那结果就是4/8个字节


1.5 sizeof( a[1] )

这里a[1],很明显是第2个元素,数据类型是int,所以结果是4字节

1.6 sizeof( &a )

&a,a代表的是首元素地址,而我们取a的地址,则是代表了取了整个数组的地址,既然是地址/指针,那就是4/8字节


1.7 sizeof( *&a )

*&a    这个表示的是我先取了整个数组的地址,再解引用,那么得到的就是整个数组,结果就是4*4=16字节

另一种解释:*&a,*和&抵消了,剩个a,那么sizeof(a)代表的也是整个数组。


1.8 sizeof( &a + 1 )


我们要知道&是比+的优先级高的,所以&a先取了整个数组的地址,再加一,是跳过了整个数组,那也是地址,是地址就是4/8字节

即使我们取的地址是整个数组的地址,但是也会用首元素地址来表示,只不过我们在+1之后是跳过整个数组的大小,也就是16个字节。



b554f9a4a5a944b080dc4fe693c9c5ba.png

1.9 sizeof( &a[0] )

我们&a[0],取了首元素的地址,是地址就是4/8字节

1.10 sizeof( &a[0] + 1 )

我们&a[0]+1,先取首元素地址再加一,得到的是&a[1],是第二个元素的地址,是地址就是4/8字节


2.字符数组

#include "stdio.h"
#include "string.h"
 int main()
 {
     char arr[] = {'a','b','c','d','e','f'};
     printf("%d\n", sizeof(arr));
     printf("%d\n", sizeof(arr+0));
     printf("%d\n", sizeof(*arr));
     printf("%d\n", sizeof(arr[1]));
     printf("%d\n", sizeof(&arr));
     printf("%d\n", sizeof(&arr+1));
     printf("%d\n", sizeof(&arr[0]+1));
     printf("%d\n", strlen(arr));
     printf("%d\n", strlen(arr+0));
     printf("%d\n", strlen(*arr));//
     printf("%d\n", strlen(arr[1]));//
     printf("%d\n", strlen(&arr));
     printf("%d\n", strlen(&arr+1));
     printf("%d\n", strlen(&arr[0]+1));
     return 0;
 }


2.1 sizeof( arr )

这里的arr是单独放在sizeof中的,代表的就是整个数组,所以数组一共有6个元素,是char类型,则结果为6*1=6字节。


2.2 sizeof( arr + 0 )

在这里arr不是单独放在一起的,arr代表的是首元素的地址,所以arr+0就是首元素地址,既然是地址,就是4/8个字节。

2.3 sizeof( *arr )

*arr代表的是对首元素地址的解引用,是数组的首元素,也就是arr[0],数据类型是char,结果为1字节


2.4 sizeof( arr[1] )

arr[1]代表是arr这个数组的首元素,数据类型是char,char占的是一个字节,所以结果为1字节


2.5 sizeof( &arr )

&arr:代表的是取出的是整个数组的地址,既然是地址,那就是4/8个字节


2.6 sizeof( &arr + 1 )

&arr是取出整个数组的地址,加上一,依旧是个地址,我们需要明白他的本质,也就是数据类型是什么,是地址,地址就是指针,那就是4/8个字节。

2.7 sizeof( &arr[0] + 1 )

&arr [0]取出的是arr[0]的地址,也就是取数组首元素的地址,加上一,是下一个元素的地址,是地址,就是4/8字节


回忆strlen函数

我们先回忆一下strlen函数是用来干什么的?详解可以去我上一篇文章。

strlen函数是用来测字符型数组长度的,遇到\0结束,结果是\0之前的字符个数。

我们传入的实参是一个地址,也就是指针,strlen函数是根据你所传入的地址向后去寻找\0,直到找到\0,并返回之前的字符个数。

2.8 strlen( arr )

我们实参是arr,arr只有单独出现在sizeof里才是代表整个数组,在strlen里代表首元素地址,它会从首元素地址开始往后寻找,但是由于我们这个字符数组并不包括\0,我们就不知道\0在什么位置,所以测出来的长度是随机值。(只有写成字符串形式,末尾才会有隐藏的\0。)


2.9 strlen( arr + 0 )

arr + 0 相当于 arr 也就是首元素地址,同上还是随机值

2.10 strlen( *arr )

我们一定要明确strlen函数的实参必须是地址,*arr是首元素,arr[0]不是地址,是char类型的,这个是错误。


2.11 strlen( arr[1] )

同理,arr[1]也不是地址,数据类型是char,无法传输,也是错误。

2.12 strlen( &arr )

&arr是取到了整个数组的地址,整个数组地址和数组首元素地址是一样的,所以依旧是从数组首元素地址往后找\0,也是随机值


2.13 strlen( &arr + 1 )

&arr+1: 是在整个数组地址➕1,跳过的是整个数组字节数,也就是在这个位置向后访问,由于我们还是不知道\0的位置,依旧是随机值




2.14 strlen( &arr[0] + 1 )

&arr[0]取到了首元素地址,&arr[0]+1是取的第二个元素地址,之后往后寻找\0,还是随机值


相关文章
|
6天前
|
SQL Oracle 关系型数据库
[Oracle]面试官:你举例几个内置函数,并且说说如何使用内置函数作正则匹配
本文介绍了多种SQL内置函数,包括单行函数、非空判断函数、日期函数和正则表达式相关函数。每种函数都有详细的参数说明和使用示例,帮助读者更好地理解和应用这些函数。文章强调了字符串操作、数值处理、日期计算和正则表达式的使用方法,并提供了丰富的示例代码。作者建议读者通过自测来巩固学习成果。
11 1
[Oracle]面试官:你举例几个内置函数,并且说说如何使用内置函数作正则匹配
|
1月前
|
Serverless 编译器 C语言
【C语言】指针篇- 深度解析Sizeof和Strlen:热门面试题探究(5/5)
【C语言】指针篇- 深度解析Sizeof和Strlen:热门面试题探究(5/5)
|
3月前
|
Java
【Java基础面试十一】、int和Integer有什么区别,二者在做==运算时会得到什么结果?
这篇文章解释了Java中`int`基本数据类型和其包装类`Integer`之间的区别,并指出在进行`==`运算时,`Integer`会拆箱为`int`类型,然后比较它们的值是否相等。
【Java基础面试十一】、int和Integer有什么区别,二者在做==运算时会得到什么结果?
|
3月前
|
机器学习/深度学习
【机器学习】如何判断函数凸或非凸?(面试回答)
文章介绍了如何判断函数是凸函数还是非凸函数,包括凸函数的定义、几何意义、判定方法(一元函数通过二阶导数判断,多元函数通过Hessian矩阵的正定性判断),以及凸优化的概念和一些经典的凸优化问题。
152 1
【机器学习】如何判断函数凸或非凸?(面试回答)
|
3月前
|
JavaScript
【Vue面试题八】、为什么data属性是一个函数而不是一个对象?
这篇文章解释了为什么在Vue中组件的`data`属性必须是一个函数而不是一个对象。原因在于组件可能会有多个实例,如果`data`是一个对象,那么这些实例将会共享同一个`data`对象,导致数据污染。而当`data`是一个函数时,每次创建组件实例都会返回一个新的`data`对象,从而确保了数据的隔离。文章通过示例和源码分析,展示了Vue初始化`data`的过程和组件选项合并的原理,最终得出结论:根实例的`data`可以是对象或函数,而组件实例的`data`必须为函数。
【Vue面试题八】、为什么data属性是一个函数而不是一个对象?
|
3月前
|
算法
聊聊一个面试中经常出现的算法题:组合运算及其实际应用例子
聊聊一个面试中经常出现的算法题:组合运算及其实际应用例子
|
4月前
|
安全 Android开发 Kotlin
Android经典面试题之Kotlin中常见作用域函数
**Kotlin作用域函数概览**: `let`, `run`, `with`, `apply`, `also`. `let`安全调用并返回结果; `run`在上下文中执行代码并返回结果; `with`执行代码块,返回结果; `apply`配置对象后返回自身; `also`附加操作后返回自身
57 8
|
3月前
|
安全 编译器 C++
【剑指offer】2.2编程语言(p22-p25)——面试题1:string赋值运算函数
【剑指offer】2.2编程语言(p22-p25)——面试题1:string赋值运算函数
|
4月前
|
Android开发 Kotlin
Android面试题之kotlin中怎么限制一个函数参数的取值范围和取值类型等
在Kotlin中,限制函数参数可通过类型系统、泛型、条件检查、数据类、密封类和注解实现。例如,使用枚举限制参数为特定值,泛型约束确保参数为Number子类,条件检查如`require`确保参数在特定范围内,数据类封装可添加验证,密封类限制为一组预定义值,注解结合第三方库如Bean Validation进行校验。
69 6
|
6月前
|
算法
【一刷《剑指Offer》】面试题 21:包含 main 函数的栈
【一刷《剑指Offer》】面试题 21:包含 main 函数的栈