网站开发需要证书吗,优秀网页欣赏,wordpress二级菜单调用,wordpress会自动更新目录
一.sizeof和strlen对比
1.sizeof
2.strlen
3.strlen 和sizeof的对比
二.数组和指针笔试题目详解 回顾#xff1a;数组名的理解
1.一维数组
2.字符数组
代码1#xff1a; 代码2#xff1a; 代码3#xff1a;
代码4#xff1a;
代码5#xff1a;
代码6数组名的理解
1.一维数组
2.字符数组
代码1 代码2 代码3
代码4
代码5
代码6
3.二维数组
总结 一.sizeof和strlen对比
1.sizeof
sizeof既是一种关键字也是一个操作符。sizeof的作用是计算变量和类型的所占内存空间的大小单位是字节返回size_t类型的值。sizeof只关注所占用内存空间的大小不在乎内存中存放的什么数据。
比如
#includestdio.h
int main()
{int a 10;printf(%d\n,sizeof(a));printf(%d\n,sizeof a );printf(%d\n,sizeof(int));return 0
}
sizeof在使用时可以不用括号这证明了它不是一个函数但是在计算类型比如int就不行必须加括号。
打印结果都是4size_t类型的值应该用%zd打印但是这里也可以使用%d,只不过编译器会发出警告但是影响不大。
sizeof不关注括号中的数据只关注存放内存的大小。比如
#includestdio.h
int main()
{int a 10;int size sizeof(a);printf(%d\n,size);printf(%d\n,a);return 0;
}
输出结果是4 10
很明显sizeof括号中的表达式是没有计算的。
2.strlen
strlen是C语言库函数在使用时需要包含头文件string.h
函数原型
size_t strlen(const char *str);
这个函数会返回字符串中字符数但是不包括\0也就是返回的是\0之前的字符数。如果没有\0就会出现越界查找的情况。
比如
#includestdio.h
int main()
{char arr1[] {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;
}
打印结果是 随机值 3 3 4.
第一个是随机值的原因就是没有\0strlen会一直查找直到遇到\0才终止。
第二个因为是常量字符串包含\0所以是3。
第三个计算的是数组arr1中所占内存的大小只有三个字符也就是3个字节。
第四个arr2中有\0所以是4个字节。
3.strlen 和sizeof的对比
sizeofstrlen sizeof是操作符。sizeof计算的是操作数所占内存空间的大小单位是字节。不关注内存中存放的什么数据。 strlen是库函数使用的头文件是string.h。strlen是求字符串长度的统计的是\0之前的字符个数。strlen关注内存中是否有\0如果没有\0,就会继续往前找可能会出现越界的情况。
二.数组和指针笔试题目详解 回顾数组名的理解 数组名是数组首元素的地址。
但是有两个的特殊情况
sizeof(数组名) sizeof中单独放数组名这里的数组名表示的是整个数组计算的是整个数组的大小单位是字节。数组名这里的数组名代表的是整个数组取出的是整个数组的地址。整个数组的地址虽然和数组首元素的地址是相同的但是指针变量的类型是不同的。
1.一维数组
#includestdio.h
int main()
{int a[] { 1,2,3,4 };printf(%d\n, sizeof(a));//1printf(%d\n, sizeof(a 0));//2printf(%d\n, sizeof(*a));//3printf(%d\n, sizeof(a 1));//4printf(%d\n, sizeof(a[1]));//5printf(%d\n, sizeof(a));//6printf(%d\n, sizeof(*a));//7printf(%d\n, sizeof(a 1));//8printf(%d\n, sizeof(a[0]));//9printf(%d\n, sizeof(a[0] 1));//10return 0;
}
序号解析答案1 a是数组名sizeof中单独放数组名计算的是整个数组的大小单位字节。162sizeof中没有单独放数组名a所以这里的数组名就是数组首元素的地址地址就是指针变量。在不同环境下大小不同。4 || 83a是数组首元素的地址解引用后得到数组首元素。所以计算的是整形变量的大小。44a表示数组首元素的地址地址就是指针类型是int*,指针加1跳过4个字节也就是一个整形元素也就是第二个元素的地址。4 || 85a[1]表示数组第二个元素46a是整个数组的地址地址就是指针变量.4 || 87a是整个数组的地址解引用后就是整个数组。所以sizeof计算的是整个数组的大小和*可以相互抵消168a是整个数组的地址1跳过了整个数组虽然这个地址并没有指向这个数组了但是我们并没有越界访问所以不影响sizeof计算这个指针变量的大小。4 || 89a[0]得到的是数组首元素的地址.4 || 810a[0]1跳过一个元素得到的是数组第二个元素的地址。4 || 8
2.字符数组
代码1
char arr[] {a,b,c,d,e,f};
printf(%d\n, sizeof(arr));//1
printf(%d\n, sizeof(arr0));//2
printf(%d\n, sizeof(*arr));//3
printf(%d\n, sizeof(arr[1]));//4
printf(%d\n, sizeof(arr));//5
printf(%d\n, sizeof(arr1));//6
printf(%d\n, sizeof(arr[0]1));//7
序号解析答案1arr单独放在sizeof中计算的是整个数组的大小。单位字节62arr没有单独放在数组中arr表示的是数组首元素的地址4 || 83arr表示的是数组首元素的地址解引用后得到的是数组首元素。14arr[1]表示数组首元素。15arr表示整个数组的地址地址就是指针变量4 || 86 a是整个数组的地址1跳过了整个数组虽然这个地址并没有指向这个数组了但是我们并没有越界访问所以不影响sizeof计算这个指针变量的大小。 4 || 87arr[0]表示数组首元素的地址1跳过一个元素表示数组第二个元素的地址4 || 8 代码2
char arr[] {a,b,c,d,e,f};
printf(%d\n, strlen(arr));//1
printf(%d\n, strlen(arr0));//2
printf(%d\n, strlen(*arr));//3
printf(%d\n, strlen(arr[1]));//4
printf(%d\n, strlen(arr));//5
printf(%d\n, strlen(arr1));//6
printf(%d\n, strlen(arr[0]1));//7
序号解析答案1arr是数组首元素的地址strlen计算的是\0之前的字符个数但是这个数组中并没有\0所以会出现越界的情况故无法出现准确的值的情况。随机值2这里的arr也是数组首元素的地址0并没有跳过任何字节与序号1同理也是不确定情况。两个值应该是一样的随机值3strlen的参数是const char *类型的。*arr得到的是数组首元素将这个作为参数传给strlen是不行的这里程序会崩溃。error4arr[1]表示数组第二个元素将其作为参数传给strlen是不行的。error5arr表示整个数组的地址虽然是一个数组指针变量但是传参会进行强制类型转换为char*类型值和数组首元素的地址相同所以和序号1和2相同值一样的。随机值6 a是整个数组的地址1跳过了整个数组也就是跳过了6个字节。但是因为没有\0也会出现随机的情况 随机值比序号125小67arr[0]表示数组首元素的地址1跳过一个元素表示数组第二个元素的地址只跳过了1个字节。随机值比序号125小1
输出结果以下是随机值不是特定情况。 序号3和4已被注释掉了。 代码3
char arr[] abcdef;
printf(%d\n, sizeof(arr));//1
printf(%d\n, sizeof(arr0));//2
printf(%d\n, sizeof(*arr));//3
printf(%d\n, sizeof(arr[1]));//4
printf(%d\n, sizeof(arr));//5
printf(%d\n, sizeof(arr1));//6
printf(%d\n, sizeof(arr[0]1));//7
序号解析答案1sizeof(数组名)计算的是整个数组的大小字符串末尾是有一个\0的只不过没有显示出来我们可以通过调试观察所以这个字符串中有7个字符。72这里的arr也是数组首元素的地址0并没有跳过任何字节是一个指针变量。4 || 83*arr的到的数组首元素。14arr[1]表示数组第二个元素.15arr表示整个数组的地址是一个指针变量。4 || 86 a是整个数组的地址1跳过了整个数组但是还是一个指针变量 4 || 87arr[0]表示数组首元素的地址1跳过一个元素表示数组第二个元素的地址是一个指针变量4 || 8
序号1
我们可以看到数组中分别放着不同的字符字符前面是它们的ASCII码值arr[6],也就是数组的第7个元素存放着\0字符。
代码4
char arr[] abcdef;
printf(%d\n, strlen(arr));//1
printf(%d\n, strlen(arr0));//2
printf(%d\n, strlen(*arr));//3
printf(%d\n, strlen(arr[1]));//4
printf(%d\n, strlen(arr));//5
printf(%d\n, strlen(arr1));//6
printf(%d\n, strlen(arr[0]1));//7
序号解析答案1sizeof计算的是\0之前的地址有6个字符62sizeof计算的是\0之前的地址有6个字符63*arr的到的数组首元素。不应该作为参数传给strlenerror4arr[1]表示数组第二个元素.不应该作为参数传给strlenerror5arr表示整个数组的地址,sizeof计算的是\0之前的地址有6个字符.66 a是整个数组的地址1跳过了整个数组故不知道什么时候会遇到\0所以是个随机值 随机值7arr[0]表示数组首元素的地址1跳过一个元素表示数组第二个元素的地址从第二个开始到\0有5个字节。5
输出结果
序号6就是经过了16个字符才遇到\0error情况已经注释掉了。
代码5
char *p abcdef;
printf(%d\n, sizeof(p));//1
printf(%d\n, sizeof(p1));//2
printf(%d\n, sizeof(*p));//3
printf(%d\n, sizeof(p[0]));//4
printf(%d\n, sizeof(p));//5
printf(%d\n, sizeof(p1));//6
printf(%d\n, sizeof(p[0]1);//7
序号解析答案1sizeof计算的是\0之前的地址有6个字符62sizeof计算的是\0之前的地址有6个字符63*arr的到的数组首元素。不应该作为参数传给strlenerror4arr[1]表示数组第二个元素.不应该作为参数传给strlenerror5arr表示整个数组的地址,sizeof计算的是\0之前的地址有6个字符.66 a是整个数组的地址1跳过了整个数组故不知道什么时候会遇到\0所以是个随机值 随机值7arr[0]表示数组首元素的地址1跳过一个元素表示数组第二个元素的地址从第二个开始到\0有5个字节。5
代码6
char *p abcdef;
printf(%d\n, strlen(p));//1
printf(%d\n, strlen(p1));//2
printf(%d\n, strlen(*p));//3
printf(%d\n, strlen(p[0]));//4
printf(%d\n, strlen(p));//5
printf(%d\n, strlen(p1));//6
printf(%d\n, strlen(p[0]1));//7
序号解析答案1sizeof计算的是\0之前的地址有6个字符62sizeof计算的是\0之前的地址1后跳过一个字节也就是一个元素有5个字符53*p的到的数组首元素。不应该作为参数传给strlenerror4p[0]表示数组第一个元素.不应该作为参数传给strlenerror5p表示字符指针的地址,sizeof计算的是\0之前的地址会产生随机值随机值6 p是字符指针的地址加1 跳过4 || 8个字节故不知道什么时候会遇到\0所以是个随机值 随机值7p[0]表示首首字符的地址1跳过一个元素表示第二个字符的地址从第二个开始到\0有5个字节。5
输出结果
3.二维数组
int a[3][4] {0};
printf(%d\n,sizeof(a));//1
printf(%d\n,sizeof(a[0][0]));//2
printf(%d\n,sizeof(a[0]));//3
printf(%d\n,sizeof(a[0]1));//4
printf(%d\n,sizeof(*(a[0]1)));//5
printf(%d\n,sizeof(a1));//6
printf(%d\n,sizeof(*(a1)));//7
printf(%d\n,sizeof(a[0]1));//8
printf(%d\n,sizeof(*(a[0]1)));//9
printf(%d\n,sizeof(*a));//10
printf(%d\n,sizeof(a[3]));//11
序号解析 答案 1数组名a单独放在sizeof中计算的是整个数组的大小。48 3 * 4 * sizeof(int)2a[0][0]表示数组第一行第一个元素。43 a[0]表示二维数组首元素地址也就是第一个一维数组的数组名a[0]就是单独存放在sizeof的数组名计算的就是第一个一维数组的大小.a[0]可以写成*a 0,a是二维数组的第一个一维数组的地址解引用就是第一个一维数组了.4 * sizeof(int) 164a[0]表示第一个一维数组的数组名并没有单独放在sizeof中,代表首元素的地址1跳过一个元素也就是a[0][1].4 || 85解引用后得到的是a[0][1]46a表示数组首元素的地址1就是第二个元素的地址也就是第二个一维数组的地址4 || 87解引用后就是第二个一维数组。168a[0]是第一行的数组名a[0]就是第一行的地址1后是第二行的地址地址就是指针4 || 89解引用后就是第二行计算的第二行的大小1610*a就是第一行计算的就是第一行的大小1611a[3]是第四行的数组名虽然没有第四行但是sizeof并没有进行访问所以并不是越界访问根据类型仍然可以计算第四行的大小4个整形变量。16
总结
数组名的意义 sizeof(数组名)这⾥的数组名表⽰整个数组计算的是整个数组的⼤⼩。 数组名这⾥的数组名表⽰整个数组取出的是整个数组的地址。除此之外所有的数组名都表⽰⾸元素的地址。