个人主页:熬夜学编程的小林

系列专栏:【C语言详解】【数据结构详解】

指针

1、sizeof和strlen的对比

1.1、sizeof

1.2、strlen

1.3、sizeof 和 strlen的对比

2、数组和指针笔试题解析

2.1、⼀维数组

2.2、二维数组

总结


1、sizeof和strlen的对比

1.1、sizeof

在学习操作符的时候,我们学习了 sizeof sizeof 计算变量所占内存空间大小的单位是 字节,如果操作数是类型的话,计算的是使用类型创建的变量所占内存空间的大小。 sizeof 只关注占注内存空间的大小,不在乎内存中存放什么数据。 比如:

#include int main(){int a = 10;printf("%d\n", sizeof(a));printf("%d\n", sizeof a);printf("%d\n", sizeof(int));return 0;}

注:变量可以不加括号,类型必须加圆括号(小括号)。

1.2、strlen

strlen 是C语言库函数,功能是求字符串长度。函数原型如下:

size_t strlen ( const char * str );

注:strlen需要包含头文件#include,可以在cplusplus旧版本搜索,前面函数章节有详细讲解查库函数的两个工具。 统计的是从 strlen 函数的参数 str 中这个地址开始向后, \0 之前字符串中字符的个数。 strlen 函数会⼀直向后找 \0 字符,直到找到为止,所以 可能存在越界查找。

#include#include int main(){ char arr1[3] = {'a', 'b', 'c'}; char arr2[] = "abc"; printf("%d\n", strlen(arr1)); printf("%d\n", strlen(arr2));printf("%d\n", sizeof(arr1)); printf("%d\n", sizeof(arr2)); return 0;}

为什么strlen(arr1)是15呢?按照我们正常思维是不是应该为3呢?

听小林娓娓道来,首先需要知道strlen是如何进行计算的,计算的是首地址到’\0’直接的字符个数,arr1数组是通过单引号进行初始化的,初始化几个元素就是几个元素,其中没有包含\0,因此在计算字符串长度时,遇到’\0’才停止,但是此处不知道什么为’\0’,所以该长度为随机值(编译器不同答案就可能不一样)。

那有uu会说为什么strlen(arr2)就是3呢?

这就考到我们之前需要字符串时讲的一个知识点,双引号包裹的字符串在末尾会自动加上’\0’,因此在计算arr2的长度时,在字符c之后遇到’\0’就会停止,也就能计算正确字符串长度。

为什么sizeof(arr2)是4呢?按照正常思维是不是应该为3呢?

首先我们需要知道sizeof是如何进行计算的,sizeof计算的是占用内存空间的大小,单位为字节,上述我们刚刚讲到双引号包裹的字符串在末尾会自动加上’\0’,因此arr2中的元素有abc\0四个,根据数组不加大小的原则,实际为几个字节那么数组就占用几个字节,因此arr2占用的大小为4字节,即sizeof(arr2)为4。

1.3、sizeof 和 strlen的对比

sizeof strlen
1. sizeof是操作符 2. sizeof计算操作数所占内存的大小, 单位是字节 3. 不关注内存中存放什么数据 1. strlen是库函数,使用需要包含头⽂件 string.h 2. srtlen是求字符串长度的,统计的是 \0 之前字符的个数 3. 关注内存中是否有 \0 ,如果没有 \0 ,就会持续往后找,可能会越界

2、数组和指针笔试题解析

2.1、⼀维数组

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));

sizeof计算操作数所占内存的大小, 单位是字节

int a[] = {1,2,3,4};
printf(“%d\n”,sizeof(a));

//数组名单独放在sizeif内部代表的是整个数组大小(数据类型大小*数据个数),因此为16字节
printf(“%d\n”,sizeof(a+0));

//数组名不是单独放在sizeof内部,因此数组名为数组首元素地址,+0还是此地址,地址在x64(64位)环境为8字节,x86(32位)环境为4字节。
printf(“%d\n”,sizeof(*a));

//数组名为首元素地址,*a则为数组第一个元素,类型为int,因此为4字节
printf(“%d\n”,sizeof(a+1));

//数组名不是单独放在sizeof内部,因此数组名为数组首元素地址,+1则向后移动一个int类型大小位置,但还是地址,地址在x64(64位)环境为8字节,x86(32位)环境为4字节。
printf(“%d\n”,sizeof(a[1]));

//a[1]为数组第二个元素,类型为int,因此为4字节
printf(“%d\n”,sizeof(&a));

//&a为整个数组的地址,但是实质还是地址,地址在x64(64位)环境为8字节,x86(32位)环境为4字节。
printf(“%d\n”,sizeof(*&a));

//&a为整个数组的地址,解引用则为整个数组,因此此处为整个数组大小,即16字节

//也可以理解为*和&可以相互抵消,就是数组名单独在sizeof内部
printf(“%d\n”,sizeof(&a+1));

//&a为整个数组的地址,+1即向后走整个数组大小步,但是实质还是地址,地址在x64(64位)环境为8字节,x86(32位)环境为4字节。
printf(“%d\n”,sizeof(&a[0]));

//a[0]为第一个元素,&a[0]为第一个元素的地址,地址在x64(64位)环境为8字节,x86(32位)环境为4字节。
printf(“%d\n”,sizeof(&a[0]+1));

//a[0]为第一个元素,&a[0]为第一个元素的地址,+1则向后走int类型大小步,但是实质还是地址,地址在x64(64位)环境为8字节,x86(32位)环境为4字节。

2.2、二维数组

int a[3][4] = {0};printf("%d\n",sizeof(a));printf("%d\n",sizeof(a[0][0]));printf("%d\n",sizeof(a[0]));printf("%d\n",sizeof(a[0]+1));printf("%d\n",sizeof(*(a[0]+1)));printf("%d\n",sizeof(a+1));printf("%d\n",sizeof(*(a+1)));printf("%d\n",sizeof(&a[0]+1));printf("%d\n",sizeof(*(&a[0]+1)));printf("%d\n",sizeof(*a));printf("%d\n",sizeof(a[3]));

sizeof计算操作数所占内存的大小, 单位是字节

int a[3][4] = {0};
printf(“%d\n”,sizeof(a));//数组名单独放在sizeof内部代表整个数组大小(数据元素类型大小*元素个数,即4*3*4),因此为48字节。
printf(“%d\n”,sizeof(a[0][0]));//a[0][0]为第一行第一列的元素,类型为int,因此大小为4字节。
printf(“%d\n”,sizeof(a[0]));//a[0]单独放在sizeof内部代表整行元素,大小为4*4字节
printf(“%d\n”,sizeof(a[0]+1));//a[0]为首行第一个元素地址,+1为第二行第一个元素地址,但实质还是地址,地址在x64(64位)环境为8字节,x86(32位)环境为4字节。
printf(“%d\n”,sizeof(*(a[0]+1)));//a[0]为首行第一个元素地址,+1为第二行第一个元素地址,解引用则为第二行首元素,int类型,4字节。
printf(“%d\n”,sizeof(a+1));//a为首元素地址,在二维数组中,首元素地址为首行地址,+1则为第二行地址,但实质还是地址,地址在x64(64位)环境为8字节,x86(32位)环境为4字节。
printf(“%d\n”,sizeof(*(a+1)));//a为首元素地址,在二维数组中,首元素地址为首行地址,+1则为第二行地址,解引用则为第二行元素大小,4*4字节。
printf(“%d\n”,sizeof(&a[0]+1));//&a[0]为首行的地址,+1位第二行的地址,但实质还是地址,地址在x64(64位)环境为8字节,x86(32位)环境为4字节。
printf(“%d\n”,sizeof(*(&a[0]+1)));//&a[0]为首行的地址,+1位第二行的地址,解引用则为第二行的大小,4*4字节。
printf(“%d\n”,sizeof(*a));//a为首元素地址,在二维数组中,首元素地址为首行地址,解引用则为首行的大小,4*4字节。
printf(“%d\n”,sizeof(a[3]));//a[3]为第四行的地址,单独放在sizeof内部代表整行元素,虽然越界了,但是sizeof只看类型,大小为4*4字节。

总结

本篇博客就结束啦,谢谢大家的观看,如果公主少年们有好的建议可以留言喔,谢谢大家啦!