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,还是随机值


相关文章
|
1月前
|
存储 SQL 数据库
面试题20: 存储过程和函数的区别
面试题20: 存储过程和函数的区别
|
2月前
|
前端开发 UED
【面试题】async/await 函数到底要不要加 try catch ?
【面试题】async/await 函数到底要不要加 try catch ?
|
2月前
|
自然语言处理 前端开发
阿里面试官:如何给所有的async函数添加try/catch?
阿里面试官:如何给所有的async函数添加try/catch?
|
8天前
|
存储 编译器 程序员
近4w字吐血整理!只要你认真看完【C++编程核心知识】分分钟吊打面试官(包含:内存、函数、引用、类与对象、文件操作)
近4w字吐血整理!只要你认真看完【C++编程核心知识】分分钟吊打面试官(包含:内存、函数、引用、类与对象、文件操作)
|
2月前
|
算法 Java C++
数据结构与算法面试题:实现一个函数 fill(int[] a, int n, int v),使其将大小为 n 的数组 a 填满为 v。
数据结构与算法面试题:实现一个函数 fill(int[] a, int n, int v),使其将大小为 n 的数组 a 填满为 v。
13 0
|
2月前
|
算法 C++
数据结构和算法面试题:实现一个函数,将一棵二叉树转换为它的镜像。(递归或者非递归实现)
数据结构和算法面试题:实现一个函数,将一棵二叉树转换为它的镜像。(递归或者非递归实现)
9 0
|
2月前
|
算法 Java C++
数据结构与算法面试题:实现一个函数,判断一个链表是否为回文链表。(提示:反转后半部分链表比对前半部分)
数据结构与算法面试题:实现一个函数,判断一个链表是否为回文链表。(提示:反转后半部分链表比对前半部分)
16 0
|
2月前
|
Java Spring 容器
面试题:怎样为组件在创建的时候指定执行一个函数,在销毁的时候也先执行一个函数
面试题:怎样为组件在创建的时候指定执行一个函数,在销毁的时候也先执行一个函数
14 0
|
2月前
|
前端开发 UED
【面试题】 async/await 函数到底要不要加 try catch ?
【面试题】 async/await 函数到底要不要加 try catch ?
【面试题】 async/await 函数到底要不要加 try catch ?
|
2月前
|
前端开发 Java C++
【面试题】calc()计算函数的作用和理解
【面试题】calc()计算函数的作用和理解
【面试题】calc()计算函数的作用和理解

热门文章

最新文章