网站开发语言 asp,字体设计软件免费,wordpress 支付宝接入,wordpress 分类图片尺寸欢迎来CILMY23的博客喔#xff0c;本期系列为【C语言】指针练习篇#xff08;上#xff09;#xff0c;深入理解指针---指针数组练习题和sizeof#xff0c;strlen的对比【图文讲解,详细解答】#xff0c;图文讲解指针和数组练习题#xff0c;带大家更深刻理解指针的应用… 欢迎来CILMY23的博客喔本期系列为【C语言】指针练习篇上深入理解指针---指针数组练习题和sizeofstrlen的对比【图文讲解,详细解答】图文讲解指针和数组练习题带大家更深刻理解指针的应用感谢观看支持的可以给个赞哇。 前言 作为指针系列的番外练习篇本篇主要以数组练习题为主本期博客将用sizeof和strlen的对比开头并且以做题的视角带入进行深刻理解指针练习题中不同用法区别。 目录
一、sizeof和strlen的对比 1.1sizeof操作符 1.2strlen
1.3表格总结
1.4sizeof题目
二、指针数组笔试题
2.1一维数组
2.2 字符数组 一、sizeof和strlen的对比 1.1sizeof操作符 sizeof 计算变量所占内存内存空间大小的单位是字节如果操作数是类型的话计算的是使用类型创建的变量所占内存空间的大小。sizeof 只关注占用内存空间的大小不在乎内存中存放什么数据并且在计算变量的时候括号可以省略。额外说明size_t就是为sizeof设计的。
就比如以下代码
#includestdio.hint main()
{int a 23;printf(%d\n, sizeof(a));printf(%d\n, sizeof a);printf(%d\n, sizeof(int));return 0;
} 我们可以看到结果都是4。 1.2strlen
strlen是C语言库函数函数功能原型如下 size_t strlen ( const char * str ); strlen字符串长度统计的是从形参str中这个地址开始向后,\0之前字符串中字符的个数。如果没有找到\0,那么strlen函数会在内存中⼀直向后找\0字符直到找到\0为止所以可能存在越界查找。
就比如下面这段代码
#includestdio.h
#includestring.hint main()
{char arr[] SILMY23;char arr1[] { S,I,L,M,Y };printf(%d\n, strlen(arr));printf(%d\n, strlen(arr1));return 0;
}
由于前面有\0,后面没有\0,那么第二个原本的长度应该是五但存在越界查找所以长度必然不为5.
结果如下 1.3表格总结
sizeofstrlen性质操作符是库函数使用需要包括头文件#includestring.h功能计算操作数所占内存的大小单位是字节求字符串长度特点不关注内存中存放什么数据关注内存中是否有\0如果没有\0 就会持续往后找可能会越界查找
1.4sizeof题目
请思考以下代码L和S的值
#includestdio.hint main()
{short S 4;int I 2;int L sizeof(S I 23);printf(%d \n, L);printf(%d \n, S);return 0;
}
结果如下 在上述代码中SI23其实是没有参与计算的因为在sizeof中的操作数如果是一个表达式表达式就不参与计算所以最后的S还是4。其次sizeof计算其实是按照操作类型来推理的比如上述中S是short两个字节的短整型所以L是两个字节。
二、指针数组笔试题
2.1一维数组
如果你不理解数组名可以跳转至http://t.csdnimg.cn/6zjW4观看第二点 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));这是在32位环境和64位环境下的结果 2.1解析 printf(%d\n, sizeof(a)); a单独放在sizeof后面是整个数组计算的是整个数组的大小所以大小为16 printf(%d\n, sizeof(a 0)); a0a没有单独放在sizeof里面也没有所以是数组首元素地址既然是数组首元素地址那么a0 a是地址大小就为4/8字节。 printf(%d\n, sizeof(*a)); a没有单独存放在sizeof后面所以是数组首元素地址解引用*a a[0],所以计算的是数组第一个元素的大小即为4个字节 printf(%d\n, sizeof(a 1)); a 1同理上面的 a0 即为4/8字节 printf(%d\n, sizeof(a[1])); a[1] *(a 1)计算的是数组第二个元素的大小即为4个字节 printf(%d\n, sizeof(a)); a, 因为a前面有操作符所以这里取出的是整个数组的地址既然为地址那么就为4/8字节 printf(%d\n, sizeof(*a)); 把整个数组的地址解引用后sizeof计算的是整个数组的大小即为16个字节 printf(%d\n, sizeof(a 1)); a 1,计算的是跳过数组大小的地址是地址就为4/8字节 printf(%d\n, sizeof(a[0])); a[0]表示取出的是数组首元素的地址大小为4/8字节 printf(%d\n, sizeof(a[0] 1)); a[0] 1表示的是数组第二个元素的地址大小为4/8字节 2.2 字符数组 2.2.1 char arr[] {S,I,L,M,Y};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));结果如下 2.2.1解析 printf(%d\n, sizeof(arr)); arr单独放在sizeof后面计算整个数组大小所以为5个字节 printf(%d\n, sizeof(arr 0)); arr0表示是数组首元素地址是地址就为4/8字节 printf(%d\n, sizeof(*arr)); *arr将数组首元素地址解引用sizeof计算首元素的大小大小为1字节 printf(%d\n, sizeof(arr[1])); arr[1]表示数组第二个元素sizeof计算第二个元素大小大小为1字节 printf(%d\n, sizeof(arr)); arr表示取出整个数组的地址是地址大小为4/8字节 printf(%d\n, sizeof(arr 1)); arr 1 表示跳过数组大小指向数组末尾后面的地址大小为4/8字节 printf(%d\n, sizeof(arr[0] 1)); arr[0] 1 表示数组第二个元素的地址是地址大小为4/8字节 2.2.2 char arr[] { S,I,L,M,Y };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));
32位结果如下 64位结果如下 2.2.2解析 printf(%d\n, strlen(arr)); arr表示数组首元素地址因为数组中没有明确给出字符\0,所以会导致strlen在内存中不断寻找直到找到第一个\0 为止因此是随机值 printf(%d\n, strlen(arr 0)); arr0也表示数组首元素地址因为没有\0,所以和第一种情况一样也是随机值 printf(%d\n, strlen(*arr)); *arrarr是数组首元素地址解引用后得到是SS对应的ASCII码值是83strlen把八十三当成一个地址造成非法访问所以错误 printf(%d\n, strlen(arr[1])); arr[1]表示数组第二个元素I对应的ASCII码值是73同样的也是非法访问。 printf(%d\n, strlen(arr)); arr表示取出整个数组的地址从arr的首元素开始算起直到找到第一个\0为止所以是随机值 printf(%d\n, strlen(arr 1)); arr 1 表示跳过数组大小的地址也就是从Y后面开始算起同样因为没有\0,所以会是一个随机值但它和arr会相差五个元素一个数组大小。 printf(%d\n, strlen(arr[0] 1)); arr[0] 1 表示从数组第二个元素开始因为没有\0所以也会是一个随机值但它和arr相比会差一个元素 2.2.3 char arr[] SILMY23;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)); 结果如下 2.2.3解析 printf(%d\n, sizeof(arr)); arr单独放在sizeof后面所以计算的是整个数组的大小因为字符串后面自带一个\0字符所以sizeof在计算大小的时候会把\0算进去也就是八个字节。 printf(%d\n, sizeof(arr 0)); arr 0 ,表示数组首元素的地址那是地址大小就是4/8 printf(%d\n, sizeof(*arr)); *arr是数组首元素地址解引用得到的是Ssizeof单独计算一个S的大小字节为1 printf(%d\n, sizeof(arr[1])); arr[1],表示数组的第二个元素计算大小是为1字节 printf(%d\n, sizeof(arr)); arr,表示取出整个数组的地址是地址大小为4/8字节 printf(%d\n, sizeof(arr 1)); arr 1 表示跳过整个数组指向数组末尾的地址是地址大小为4/8字节 printf(%d\n, sizeof(arr[0] 1)); arr[0] 1 表示数组第二个元素的地址是地址大小就为4/8字节。 2.2.4 char arr[] SILMY23;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));
32位结果如下 64位结果如下 2.2.4解析 printf(%d\n, strlen(arr)); arr表示数组首元素地址strlen计算的是到\0之前的字符所以是7个字节 printf(%d\n, strlen(arr 0)); arr0表示数组首元素地址7个字节 printf(%d\n, strlen(*arr)); arr表示数组首元素地址但是解引用后访问的是S的ASCII码地址83非法访问 printf(%d\n, strlen(arr[1])); arr[1] 表示数组第二个元素解引用后访问的是I的ASCII码地址73非法访问 printf(%d\n, strlen(arr)); arr,表示整个数组的地址也是指向数组起始位置的那因为有\0,所以计算的是到\0之前的地址所以是7个字节 printf(%d\n, strlen(arr 1)); arr 1 ,表示跳过整个数组指向数组末尾的地址由于找不到\0所以会在内存中寻找\0,因此是随机值 printf(%d\n, strlen(arr[0] 1)); arr[0] 1,表示数组第二个元素的地址计算后的大小为6. 2.2.5
char* p SILMY23;printf(%d\n, sizeof(p));printf(%d\n, sizeof(p 1));printf(%d\n, sizeof(*p));printf(%d\n, sizeof(p[0]));printf(%d\n, sizeof(p));printf(%d\n, sizeof(p 1));printf(%d\n, sizeof(p[0] 1));
32位结果如下图 64位结果如下图 2.2.5解析 printf(%d\n, sizeof(p)); p是个char* 的指针变量指向的对象数据类型是char是指针变量大小就为4/8字节 printf(%d\n, sizeof(p 1)); p 1表示字符I的地址本身还是指针变量大小就为4/8字节 printf(%d\n, sizeof(*p)); *pp本身存储的是S的地址解引用后获得S那么S对应的类型是char所以大小为1字节 printf(%d\n, sizeof(p[0])); p[0],表示*p0 *p所以大小为1字节 printf(%d\n, sizeof(p)); p,表示的是指针变量p的地址所以大小为4/8字节 printf(%d\n, sizeof(p 1)); p 1 ,表示跳过一个指针变量的大小的地址是地址大小为4/8 printf(%d\n, sizeof(p[0] 1)); p[0] 1,表示指向I的地址是地址大小为4/8 2.2.6 char* p SILMY23;printf(%d\n, strlen(p));printf(%d\n, strlen(p 1));printf(%d\n, strlen(*p));printf(%d\n, strlen(p[0]));printf(%d\n, strlen(p));printf(%d\n, strlen(p 1));printf(%d\n, strlen(p[0] 1));
32位结果如下 64位结果如下 2.2.6解析 printf(%d\n, strlen(p)); p是char* 的指针变量指向的是S这个起始位置末尾有\0计算大小为7 printf(%d\n, strlen(p 1)); p 1 指向的是I这个起始位置末尾有\0计算大小为6 printf(%d\n, strlen(*p)); *pp表示字符串S地址但是解引用后访问的是S的ASCII码地址83非法访问 printf(%d\n, strlen(p[0])); p[0] *(p0) *p, 同样是非法访问 printf(%d\n, strlen(p)); p,表示的是p的地址那从p的起始地址开始往后找\0,因为不确定\0在哪所以是随机值 printf(%d\n, strlen(p 1)); p 1 ,表示跳过一个指针变量的大小的地址从p的末尾开始查找因为不确定\0在哪,所以是随机值 printf(%d\n, strlen(p[0] 1)); p[0] 1,表示指向I的地址计算的大小为6 感谢各位同伴的支持本期指针练习篇(上)就讲解到这啦还有指针练习篇(下)如果你觉得写的不错的话可以给个赞若有不足欢迎各位在评论区讨论。