焦作电子商务网站建设实例,海南创作什么网站,安阳网课,电子商务网店设计文章目录 ▶️1.sizeof和strlen的对比#x1f4af;➡️1.1 sizeof是什么#xff1f;#x1f4af;➡️1.2sizeof用法举例#x1f4af;▶️1.3strlen是什么#xff1f;#x1f4af;▶️1.4 strlen函数用法举例#xff1a;#x1f4af;▶️1.5 strlen和sizeof的对比#… 文章目录 ▶️1.sizeof和strlen的对比➡️1.1 sizeof是什么➡️1.2sizeof用法举例▶️1.3strlen是什么▶️1.4 strlen函数用法举例▶️1.5 strlen和sizeof的对比 ▶️2. 数组和指针笔试题▶️2.1 整型数组和指针笔试题1:▶️2.1.1 整型数组和指针笔试题解析~▶️ 2.1.1.1 VS运行结果展示 ▶️2.2 字符数组和指针笔试题▶️2.2.1 字符数组和指针笔试题1▶️2.2.1 字符数组和指针笔试题解析▶️2.2.1.1 VS运行结果展示▶️2.2.2 字符数组和指针笔试题2▶️2.2.2 字符数组和指针笔试题解析▶️2.2.2.1 VS运行结果展示▶️2.2.3 字符数组和指针笔试题3▶️2.2.3字符数组和指针笔试题解析▶️2.2.3.1 VS运行结果展示▶️2.2.4 字符数组和指针笔试题4▶️2.2.4字符数组和指针笔试题解析▶️2.2.4.1 VS运行结果展示▶️2.2.5 字符数组和指针笔试题5▶️2.2.5字符数组和指针笔试题解析▶️2.2.5.1 VS运行结果展示▶️2.2.6 字符数组和指针笔试题6▶️2.2.6字符数组和指针笔试题解析▶️2.2.6.1 VS运行结果展示 在上一次介绍篇博客中: C语言-指针讲解(4) 我们给大家主要讲解了指针的进阶用法让我们来回顾一下讲了什么吧 回调函数是通过函数指针调用的函数以及回调函数用法举例。细致地讲解qsort函数的参数以及用qsort函数排序任意类型用法举例同时qsort函数是运用了快速排序的思想。改造普通的整型冒泡排序算法让它模拟实现成一个qsort函数然后用模拟实现的qsort函数对各种数据类型进行排序操作举例。 那么这次博主根据前面5讲的指针介绍给大家讲解C语言指针相关的笔试题 这次讲的内容如下 首先在讲解C语言指针笔试题前我们先对sizeof操作符以及strlen库函数进行详细的介绍。 ▶️1.sizeof和strlen的对比
➡️1.1 sizeof是什么 sizeof顾名思义它就是一种操作符。并且sizeof操作符是用来计算变量所占内存空间大小的单位是字节计算的是适用类型创建的变量所占内存空间的大小。 ➡️1.2sizeof用法举例 如下所示
#inculde stdio.h
int main()
{int a 10;printf(%d\n, sizeof(a));printf(%d\n, sizeof a);printf(%d\n, sizeof(int));return 0;
}vs编译结果如下 代码分析 1.我们通过上图发现用sizeof计算变量的大小或类型的大小只要它们的类型相同那么它们的大小也是相等的而且如果是计算创建变量a的大小是无需加上括号的反倒如果是计算int类型的大小,是需要对它加上一个括号的。 总结: sizeof只关注内存存放空间的大小不在乎内存中存放的数据。 ▶️1.3strlen是什么 strlen顾名思义就是C语言的库函数功能是求字符串长度。 它的函数原型如下
1 size_t strlen (const char * str);▶️1.4 strlen函数用法举例
如下代码所示:
#include stdio.h
int main()
{char arr1[3] { a, b, c };char arr2[] abc;printf(%d\n, strlen(arr1));printf(%d\n, strlen(arr2));return 0;
}
vs运行结果如下: 有同学可能会有疑问了为什么数组arr1和数组arr2存的内容都一样但为什么用strlen函数计算它们的长度却不相同呢? 代码分析 这是因为strlen函数本质上是统计参数str中这个地址开始往后\0之前的字符。strlen函数会一直向后找\0字符直到找到为止。所以这样有可能会导致数组越界访问。 如下所示 从上图我们发现arr1数组是一个一个字符一个字符地存放的如果我们不把\0存进数组中strlen函数会一直往后找\0。直到找到为止。反倒是strlen计算arr2数组就不一样了因为arr2数组是以字符串的形式存放在数组中而\0是字符串的结束标志因此如果我们以字符串的形式存放在数组,strlen函数会把arr2数组中‘\0’之前的字符个数都加起来。 ▶️1.5 strlen和sizeof的对比
我们把strlen函数和sizeof操作符区别做了张图总结 如下图所示: ▶️2. 数组和指针笔试题 再讲解数组和指针笔试题之前我们再来复习一下数组名的概念。 我们之前在这篇博客:C语言-指针讲解2讲过通常情况下数组名是数组首元素的地址。 但是有两个例外 1.sizeof(数组名)sizeof里面单独放数组名这里的数组名代表的是整个数组计算的是整个数组的大小。 2.arr表示整个数组是指取出整个数组的地址(整个数组的地址和数组首元素的地址还是有区别的。) ▶️2.1 整型数组和指针笔试题1:
题目如下
int main()
{int a[] {1,2,3,4};printf(%zd\n,sizeof(a));//1.输出结果是什么呢printf(%zd\n,sizeof(a0));//2.输出结果是什么呢printf(%zd\n,sizeof(*a));//3.输出结果是什么呢printf(%zd\n,sizeof(a1));//4.输出结果是什么呢printf(%zd\n,sizeof(a[1]));//5.输出结果是什么呢printf(%zd\n,sizeof(a));//6.输出结果是什么呢printf(%zd\n,sizeof(*a));//7.输出结果是什么呢printf(%d\n,sizeof(a1));//8.输出结果是什么呢printf(%d\n,sizeof(a[0]));//9.输出结果是什么呢printf(%d\n,sizeof(a[0]1));//10.输出结果是什么呢return 0;
}大家不妨先思考一下这些题看看它们的输出结果是什么 ▶️2.1.1 整型数组和指针笔试题解析~
1.由于是sizeof(数组名),计算的是整个数组的大小单位是字节。这里的整型数组有四个元素每个元素占4个字节那么也就是总共占16个字节。 2.这里的数组名并没有单独放在sizeof内部也没有,所以a就是数组首元素的地址是地址就是4/8个字节。需要注意的是这里的(a0) a[0]。 3.a就是数组首元素的地址aa[0],然后*a其实就是第一个元素也就是a[0],大小就是4个字节。 4.a就是数组首元素的地址(a[0]–int ),a1—a[1],a1就是第二个元素的地址。它的大小也就是4/8字节。 5.计算第2个元素的大小单位是字节 - 4 6.a虽然取出的是数组的地址但是数组的地址也是地址是地址大小就是4/8个字节。 7.16 8.a1是跳过整个数组后的地址是地址大小就是4/8个字节。 9.首元素的地址4/8 10.因为a[0] - int,那么1就是到第二个元素的地址,也就是a[1]的地址,大小是4/8个字节。
这里我们重点讲一下第七道和第八道题目: 7.这里我们有两种方法来分析这道题 1.这里的a -- int(*p)[4]a,也就是说这里的p指向的是一个大小为4的整型数组这里的 * p是指访问一个数组的大小,然后p1是跳过一个数组的大小。 a取出的是数组的地址数组的地址应该放到数组指针里面去然后它的数组指针类型是int( * )[4]。然后这里 * p是访问整个数组的大小也就是说这个数组占了16个字节。 2.这里的a就是取出整个数组的地址它的类型是个数组指针我们对数组指针进行解引用操作访问的不就是整个数组吗所以sizeof整个数组不就是16吗
8.如下图所示 虽然我们通过a1是个地址是地址就是4/8个字节。但是我们通过图中更能直观地发现a1指向的是第四个元素后面的地址。 ▶️ 2.1.1.1 VS运行结果展示
那我们分析的是否正确呢接下来我们分别用vs的x64环境和x86环境来测试一下运行结果~ x86环境 x64环境 ▶️2.2 字符数组和指针笔试题
▶️2.2.1 字符数组和指针笔试题1
题目如下
//字符数组1.1
#include stdio.h
int main()
{char arr[] { a,b,c,d,e,f };printf(%zd\n, sizeof(arr));//1.输出结果是什么printf(%zd\n, sizeof(arr 0));//2.输出结果是什么printf(%zd\n, sizeof(*arr));//3.输出结果是什么printf(%zd\n, sizeof(arr[1]));//4.输出结果是什么printf(%zd\n, sizeof(arr));//5.输出结果是什么printf(%zd\n, sizeof(arr 1));//6.输出结果是什么printf(%zd\n, sizeof(arr[0] 1));//7.输出结果是什么return 0;
}大家不妨先思考这几道题待会我们会统一讲解一下。 ▶️2.2.1 字符数组和指针笔试题解析
1.由于是sizeof(数组名),计算的是整个数组的大小单位是字节。这里的整型数组有六个元素每个元素占1个字节那么也就是总共占6个字节。 2.arr是数组首元素的地址arr0 还是首元素的地址 是地址大小就是4/8个字节。 3.arr是数组首元素的地址,*arr就是首元素,就占一个字符大小就是1个字节。 4.arr[1]就是数组的第二个元素大小是1个字节。 5.arr 是数组的地址数组的地址也是地址大小就是4/8。 6.arr1 是跳过整个数组指向f的后面 4/8。 7.arr[0]是首元素的地址arr[0]1就是第二个元素的地址 4/8。
▶️2.2.1.1 VS运行结果展示 我们不妨用vs来运行一下此代码看看我们分析得是否正确~ x64环境 x86环境 ▶️2.2.2 字符数组和指针笔试题2
题目如下
#include stdio.h
#include string.hint main()
{//字符数组1.2char arr[] { a,b,c,d,e,f };printf(%zd\n, strlen(arr));//1.输出结果是什么呢printf(%zd\n, strlen(arr 0));//2.输出结果是什么呢printf(%zd\n, strlen(*arr));//3.输出结果是什么呢printf(%zd\n, strlen(arr[1]));//4.输出结果是什么呢printf(%zd\n, strlen(arr));//5.输出结果是什么呢printf(%zd\n, strlen(arr 1));//6.输出结果是什么呢printf(%zd\n, strlen(arr[0] 1));//7.输出结果是什么呢return 0;
}大家不妨先思考这几道题待会我们会统一讲解一下。 ▶️2.2.2 字符数组和指针笔试题解析
1.如下图所示 我们发现这个arr数组它是没有\0的也就是说当这个strlen函数拿到首元素字符a的地址会一直往后找\0。 它有可能会在内存中的某个位置找到\0,然后统计\0之前的字符个数因此我们是不确定它的值是多少因此它是个随机值。 2.同样地这个输出结果也是随机值因为arr0,意思就是首元素地址跳过0个元素本质上还是首元素的地址。 所以strlen函数拿到的也是首元素a的地址然后向后面找\0但是arr数组里面没有\0因此它本质上还是个随机值。
如下图所示 3.我们从上面两张图中可以发现* arr就是把它首元素的地址进行解引用得到的是它的元素aa的ASCLL码值是97。我们知道strlen函数参数的是一个指针类型的我们把97它传过去的话它就把它当成一个地址。 97这个地址你说想访问就访问吗哪个地址你能说想访问就访问呢我们通过vs调试也发现0x00000061是访问异常也就是我们常说的非法访问。那么这个输出结果就会报错。 4.同样地,我们发现arr[1]就是数组的第二个元素。也就是传过去的是字符b字符b的ASCLL码值是98也就是传过去的地址是98。也会属于非法访问所以它的输出结果同样也会出现报错。
总结通过上面分析我们知道只能传给strlen地址。而不能胡传如果胡传strlen函数会误以为地址最终就会出现报错。
5.我们发现arr的类型是char (*p)[6],然后如果把它传到strlen函数里面的话它的参数类型就强制转换为char *。 站在strlen函数的角度它依然拿到的是arr起始位置的地址也就是从字符a向后数的数到的结果还是随机值。所以它的结果跟第一道题和第二道题输出结果是一样的都是随机值。
如下图所示 6.从上图我们发现arr1指向的是字符f后面的地址也就是从f后面的地址往后去找\0 所以从这里往后数那个内存放什么我们就更不知道了但是这个地方得到的随机值跟前面那些随机值是不一样的因为它们中间相差了几个字符。
如下图所示 7.从上图我们发现arr[0]1得到的是字符b的地址然后把b的地址传给strlen函数从b的位置一直往后数找\0所以它这里的输出结果依然是随机值。 只不过它的随机值跟第一题和第二题输出结果的随机值 少了个1。
综上所述 对于指针来说 我们要搞清楚它指向哪里才能知道它指向的内容是什么。
▶️2.2.2.1 VS运行结果展示 我们不妨用vs来运行一下此代码看看我们分析得是否正确~ 这里需要注意的是: 如果我们直接运行的话第三题和第四题输出结果是会报错的。那它会影响后面第五-第七题的输出结果因此我们要先将它的代码先注释掉再运行。 x64环境 x86环境 我们从x64环境和x86环境中也知道除了第三和第四题其他题的输出结果均为随机值。 说明我们的分析是正确的。 ▶️2.2.3 字符数组和指针笔试题3
题目如下
#include stdio.h
int main() {//字符数组2.1char arr[] abcdef;printf(%zd\n, sizeof(arr));//1.输出结果是什么printf(%zd\n, sizeof(arr 0));//2.输出结果是什么printf(%zd\n, sizeof(*arr));//3.输出结果是什么printf(%zd\n, sizeof(arr[1]));//4.输出结果是什么printf(%zd\n, sizeof(arr));//5.输出结果是什么printf(%zd\n, sizeof(arr 1));//6.输出结果是什么printf(%zd\n, sizeof(arr[0] 1));//7.输出结果是什么return 0;
}这里需要注意的是 由于arr里面存放的是字符串我们知道\0是字符串的结束标志所以里面默认存放的是有\0的。 如下所示 大家不妨先思考这几道题待会我们会统一讲解一下。 ▶️2.2.3字符数组和指针笔试题解析
1.我们知道sizeof(数组名是计算整个数组的大小。 那这里数组里面有7个元素而且该数组为char类型所以每个元素是占一个字节那这里就总共占了7个字节。 2.这里的arr0 表示arr跳过0个元素本质上还是首元素的地址所以大小就是4/8个字节。 3.arr表示数组首元素的地址,*arr就是首元素大小就是1字节 4.arr[1]是第二个元素大小也是1字节。 5.arr是数组的地址但是也是地址是地址大小就是4/8个字节。
这里我们重点详解一下第六题和第七题 如下图所示 6.从上图我们发现arr1指向的是\0后面的地址因此我们可以推导出arr1就是跳过整个数组的那个地址。大小为4/8个字节。
如下图所示 7.同样地我们从上图发现arr[0]1指向的是数组中第二个元素的地址所以它的大小为4/8个字节。
▶️2.2.3.1 VS运行结果展示
我们不妨用vs测试一下结果看看分析的是否正确~ x86环境运行结果 x64环境运行结果 ▶️2.2.4 字符数组和指针笔试题4
题目如下
int main() {//字符数组2.2char arr[] abcdef;printf(%d\n, strlen(arr));//1.输出结果是什么呢printf(%d\n, strlen(arr 0));//2.输出结果是什么呢printf(%d\n, strlen(*arr));//3.输出结果是什么呢printf(%d\n, strlen(arr[1]));//4.输出结果是什么呢printf(%d\n, strlen(arr));//5.输出结果是什么呢printf(%d\n, strlen(arr 1));//6.输出结果是什么呢printf(%d\n, strlen(arr[0] 1));//7.输出结果是什么呢return 0;
}大家不妨先思考这几道题待会我们会统一讲解一下。 ▶️2.2.4字符数组和指针笔试题解析
如下图所示 1.我们发现strlen(arr) 本质上就是把首元素的地址a传给strlen函数然后strlen就往后找\0,统计\0之前的个数从上图我们能直观地分析到\0之前有6个元素个数因此它的输出结果是6。 2.同样地我们发现arr0 还是首元素跳过0个元素本质上还是把首元素的地址传给strlen函数统计\0之前的字符个数所以它的输出结果依然是6。 3.这里我们前面已经介绍过* arr就是数组首元素a,它的Ascll码值为97当做地址传给strlen函数但是这个地址属于是非法访问因此会出现报错情况。 4.同样地arr[1]就是数组首元素a,它的Ascll码值为98当做地址传给strlen函数但是这个地址属于是非法访问因此会出现报错情况。 5.我们前面已经介绍过这里的arr本质上它的类型就是char (* p)[7]当我们把这个数组地址传入strlen函数内部会把它强转为char*类型。 站在strlen函数的角度它依然拿到的是arr起始位置的地址也就是从字符a的地址向后数的直到遇到\0为止所以它的输出结果也是6。
如下图所示 6.我们从上图发现arr1是指向\0的后面因此它后面内存放的是什么以及后面是否有\0,我们是不知道的。 因此它的输出是个随机值。
如下图所示 7.从上图我们更能直观地发现arr[0]1指向的是字符b的地址当我们把字符b的地址传入strlen函数 会统计字符b的地址到\0之间的字符个数。 所以它的输出结果就是5。
▶️2.2.4.1 VS运行结果展示
由于我们发现第三题和第四题的结果输出是报错的我们先用注释把它屏蔽掉再拿vs来运行此代码。 这里博主用x64环境下运行此代码 从上图我们发现第六题输出结果是26是个随机值。 另外虽然VS编译器中运行没有报错但是我们仔细查看的话会发现arr是一个数组指针类型它跟strlen函数参数const char * 指针类型不太一样所以这里有可能会出现被警告情况。 ▶️2.2.5 字符数组和指针笔试题5
题目如下
#include stdio.h
int main() {//字符数组3.1char* p abcdef;printf(%zd\n, sizeof(p));//1.输出结果是什么printf(%zd\n, sizeof(p 1));//2.输出结果是什么printf(%zd\n, sizeof(*p));//3.输出结果是什么printf(%zd\n, sizeof(p[0]));//4.输出结果是什么printf(%zd\n, sizeof(p));//5.输出结果是什么printf(%zd\n, sizeof(p 1));//6.输出结果是什么printf(%zd\n, sizeof(p[0] 1));//7.输出结果是什么return 0;
}如下图所示: 这里大家需要注意的是我们根据上图可以知道这里的abcdef本质上是一个常量字符串这里的常量字符串的首字符的地址是放到指针变量p里面去。假设a的地址为0x0012ff40,那么p的地址放的也是0x0012ff40,正因为有这个地址才能找到它。 大家不妨先思考这几道题待会我们会统一讲解一下。 ▶️2.2.5字符数组和指针笔试题解析
1.我们发现p是一个指针变量大小是4/8字节。 2.由于我们知道p指向的是a的地址那么p1指向的是a的地址假设p的地址是0xff12ff40那么p1指向的产生b的地址也就是0xff12ff41–‘b’,所以p1是字符b的地址大小同样是4/8个字节。 3.我们知道p指向的是a的地址那* p指向的是字符a,类型是char *, 所以 * p是首字符大小为1个字节。
如下图所示 4.这道题我们用两种方式来解读 一.我们从上图发现我们发现这个字符串画出来也像数组一样连续放到内存空间里面假设我们把这个常量字符串想象成一个数组 那它有下标a的下标为0b的下标为1c的下标为2以此类推可以得知f的下标为5。 数组名也是数组首元素的地址那么p可以理解为后面这个数组名那p[0]访问数组下标为0的元素。也就是字符a同样也是占了一个字节。 二.p[0]从计算的角度被转换为*(p0)是这个a的地址那(p0)也是这个位置的地址。 那解引用不就是对这个a访问吗也就是占了一个字节。
如下图所示
5.从上图我们知道p相当于是个二级指针是p的地址既然是地址那地址大小就是4/8个字节。
如下图所示 6.这道题我们先举个例子比如从上图我们得知* p是访问一个整型的大小p1是跳过一个整型。 接着看下图 然后我们知道p的类型其实是char *,那如果我们p我就会把这个地址放到 ** pp,那pp的类型就是char ** 类型的。
char *p;//1.
char ** ppp;//2.从上面第二行代码我们知道pp是一个char ** 类型的第二行代码中pp左边的那个* 代表pp是一个指针而前面的char *表示pp指向的对象是p它的类型为char *,而第一行的char *和第二行的 char *是一致的。 这足矣说明第二行的代码char * 表示p所指向的对象就是char * 。 那我们是不是能得出这个结论 p1pp1因为我们把p交给pp了所以p1pp1,那pp1要跳过几个字节是不是跳过一个char * 对象的大小那大家想象一下。 如上图红框所示如果说pp指向p的话p的地址是0x0012ff40。 那pp的地址也是0x0012ff40那pp要跳过一个char * 对象的话那此时p不就是char *类型的对象吗 那把char *对象跳过的话不是指向0地址处后面的地址吗实际上它就是跳过一个指针变量的大小从p所在空间的内部跳过去的因为这块空间用的是自己的地址那这1就整块空间到了p后面的地址。
总结因为p1也是地址p1是跳过p变量后的地址。那大小就是4/8个字节。
7.因为我们前面已经介绍过p[0]是首字符a那我们把它的地址取出来就是a的地址1那也就是b的地址对不对。 同样地它的大小是占4/8个字节。
▶️2.2.5.1 VS运行结果展示 我们用vs来测试一下看看我们分析的结果是否正确 我们分别以x64和x86环境来演示一下 x64环境 x86环境 ▶️2.2.6 字符数组和指针笔试题6
题目如下
#include stdio.h
#include string.hint main() {//字符数组3.2char* p abcdef;printf(%zd\n, strlen(p));//1.输出结果是什么printf(%zd\n, strlen(p 1));//2.输出结果是什么printf(%zd\n, strlen(*p));//3.输出结果是什么printf(%zd\n, strlen(p[0]));//4.输出结果是什么printf(%zd\n, strlen(p));//5.输出结果是什么printf(%zd\n, strlen(p 1));//6.输出结果是什么printf(%zd\n, strlen(p[0] 1));//7.输出结果是什么return 0;
}如下图所示 需要注意的是这里的内存布局跟上个题目是一样的同样指针变量p拿到的是字符串中首字符a的地址。 好了大家先思考这七道题的输出结果是什么等下我们会进行细致的讲解~ ▶️2.2.6字符数组和指针笔试题解析
如下图所示 1.由于我们知道abcdef是个常量字符串字符串中是有\0。 通过上图p中存放的a的地址然后从a的地址开始往后访问。所以它的字符串长度为6。 2.同样的道理因为我们已经知道p拿到的首元素a的地址那么p1相当于拿到的是字符b的地址然后往后找\0。
3.因为p是拿到字符a的地址那么 *p拿到的是a的字符。 但是我们前面已经讲过它会把字符a的Ascll码值作为地址传给strlen。这就属于是非法访问了因此会报错。 4.同样地我们之前讲过因为p[0] * (p0) * p,因为p拿到首字符a的地址那(p0)跳过0个元素同样也是拿到a的地址。 对其进行解引用也是拿到字符a如果把a的ascll码值传入strlen函数同样也会报错。 5.这道题估计很多同学会误以为它的字符串长度是6。 他们可能以为是从的首元素a的地址往后数。但实际上并不是。接下来我给大家解释一下 如下图所示: 它实际上是从p的内存空间往后数的那p这个内存空间放什么我们知道吗我们刚刚举的0x0012ff40这个地址我们都是假设的。 我们只是假设它放了这个地址但是具体编译器里面分配了什么地址我们是不知道的。当然这里的地址也不是随机的编译器一定会指派一个有效的地址但是它地址的值在内存存的是什么每个字节放的是什么我们是不知道的所以我们这里是不能确定答案的。 这里什么时候遇到\0,我们也是不可知的。 因此我们可以得出以下结论:p是p的地址它是从p的所占空间起始位置开始查找的因此它是个随机值。
当然有同学可能会有这个疑问要是p的内存中有00就不是随机值了 这个想法是错的我们来给大家解释一下: 我们在VS的x64环境通过调试然后观察p内存因为x64环境下指针变量是占8个字节的因此我们就调成8列每列分别是一个字节然后我们发现00是在第七个字节的位置才遇到的但是也有可能在前面第二个字节第三个字节遇到00是不是这个道理呀所以不一定是第七个。 所以这个随机值我们是无法预测的。 如下图所示 6.从图中我们可以看出p指向的是p的内存空间起始位置然后p1就相当于跳过一个p内存空间的地址它就指向下一个内存空间的起始位置。 那从这个位置往后它也是个内存空间啊那它内存是什么什么时候遇到\0我们同样也是不知道的那从这个位置往后数这也是不可控的。因此它也是个随机值。 需要注意的是 p所占的空间和字符串所占的空间根本就不是一回事因为p有p的空间字符串有字符串的空间只不过我把字符串的首字符地址放在p里面去所以这两块内存不一定是连续的也可能是无关的因此这是两个独立的空间。 7.p[0]是第一个元素那p[0]就是把它的地址取出来就是a的地址1就是从b的地址一直往后数,一直数到\0,所以它的长度是5。 ▶️2.2.6.1 VS运行结果展示
我们用vs来测试一下看看我们分析的结果是否正确 首先先把分析为报错结果的第三题和第四题的代码先注释掉。 然后分别以x64和x86环境来运行一下此代码 x64环境 如上图我们发现第五题和第六题的运行结果分别为6和30。 这里可能有同学对于第五题的运行结果有所疑问为什么在x64环境下 printf(%zd\n, strlen(p); 这行代码的运行结果是6但其实它这个是随机值。为什么呢 原因如下 如上图所示我们通过调试发现恰好那个\0刚好在内存空间p的第七个字节的位置所以它的字符串长度恰好为。 但是它跟字符串长度是没有任何关系的。 比如说我们将它那个常量字符串改为10它运行起来一样是为6的。 如下 x86环境 同样地我们拿x86环境下运行第五题和第六题运行结果同样是一个随机值。 总结: 这里我们三种不同类型的字符数组都进行了讲解分别是 1.拿多个字符来初始化一个字符数组的。这里面是没有\0。 2.拿一个字符串来初始一个数组的情况这里面的字符串是包括了\0。 3.拿一个字符指针来指向一个常量字符串的情况它里面虽然是有\0,但是p不是一个数组空间它是一个变量空间这个变量存放着p的地址。
希望博主讲的这三种类型的字符数组大家能理解透彻 另外博主这里只是讲一部分的数组和指针的笔试题还有一部分的笔试题留到下次的博客再讲解哦~ ** 如果觉得博主写的不错的话** 欢迎大家一键三连支持一下博主谢谢大家