1.实验代码
#include <stdlib.h>
#include <stdio.h>
#include <cstring>
int main() {
printf("-----------test1--------------\n");
char *p1 = "qwer";
printf("程序中直接给指针赋值:*p1=\"qwer\"\n");
printf("strlen(p1)==%d\tsizeof(p1)==%d\n\n", strlen(p1), sizeof(p1));
printf("-----------test2--------------\n");
char *p2 = (char *)malloc(sizeof(char) * 6);
printf("已申请6个char型地址,请手动赋值:");
scanf("%s", p2);
printf("strlen(p2)==%d\tsizeof(p2)==%d\n", strlen(p2), sizeof(p2));
char *p3 = (char *)malloc(sizeof(char) * 6);
printf("已申请6个char型地址,请手动赋值:");
scanf("%s", p3);
printf("strlen(p3)==%d\tsizeof(p3)==%d\n", strlen(p3), sizeof(p3));
char *p4 = (char *)malloc(sizeof(char) * 6);
printf("已申请6个char型地址,请手动赋值:");
scanf("%s", p4);
printf("strlen(p4)==%d\tsizeof(p4)==%d\n\n", strlen(p4), sizeof(p4));
printf("-----------test3--------------\n");
char s1[] = "qwer";
printf("程序中直接给数组赋值:s1[]=\"qwer\"\n");
printf("strlen(s1)==%d\tsizeof(s1)==%d\n\n", strlen(s1), sizeof(s1));
printf("-----------test4--------------\n");
// char s2[4] = "qwer"; 测试请解开注释
printf("程序中直接给数组赋值:s2[4]=\"qwer\"会报错!\n");
printf("错误信息为\"[错误] 初始化-string 对于 array of chars is too long\"\n\n");
printf("-----------test5--------------\n");
char s3[5] = "qwer";
printf("程序中直接给数组赋值:s3[5]=\"qwer\"\n");
printf("strlen(s3)==%d\tsizeof(s3)==%d\n\n", strlen(s3), sizeof(s3));
printf("-----------test6--------------\n");
char s4[6];
printf("已初始化s4[6],请手动赋值:");
scanf("%s", s4);
printf("strlen(s4)==%d\tsizeof(s4)==%d\n\n", strlen(s4), sizeof(s4));
char s5[6];
printf("已初始化s5[6],请手动赋值:");
scanf("%s", s5);
printf("strlen(s5)==%d\tsizeof(s5)==%d\n\n", strlen(s5), sizeof(s5));
char s6[6];
printf("已初始化s6[6],请手动赋值:");
scanf("%s", s6);
printf("strlen(s6)==%d\tsizeof(s6)==%d\n\n", strlen(s6), sizeof(s6));
return 0;
}
2.代码运行演示
-----------test1--------------
程序中直接给指针赋值:*p1="qwer"
strlen(p1)==4 sizeof(p1)==8
-----------test2--------------
已申请6个char型地址,请手动赋值:qwer
strlen(p2)==4 sizeof(p2)==8
已申请6个char型地址,请手动赋值:qwerty
strlen(p3)==6 sizeof(p3)==8
已申请6个char型地址,请手动赋值:qwertyu
strlen(p4)==7 sizeof(p4)==8
-----------test3--------------
程序中直接给数组赋值:s1[]="qwer"
strlen(s1)==4 sizeof(s1)==5
-----------test4--------------
程序中直接给数组赋值:s2[4]="qwer"会报错!
错误信息为"[错误] 初始化-string 对于 array of chars is too long"
-----------test5--------------
程序中直接给数组赋值:s3[5]="qwer"
strlen(s3)==4 sizeof(s3)==5
-----------test6--------------
已初始化s4[6],请手动赋值:qwer
strlen(s4)==4 sizeof(s4)==6
已初始化s5[6],请手动赋值:qwerty
strlen(s5)==6 sizeof(s5)==6
已初始化s6[6],请手动赋值:qwertyu
strlen(s6)==7 sizeof(s6)==6
--------------------------------
Process exited after 17.79 seconds with return value 0
请按任意键继续. . .
3.结论
- strlen函数会返回给的首地址到字符串结束符’\0’中间的所有字符数量。
- sizeof函数,如果给的参数是指针,那么返回4或8(取决于指针类型在该台电脑中占的字节数),如果给的参数是数组,那么返回数组的长度。
- %s:因为内存现实存在,程序会将输入的字符全部读入,不被指针分配空间与数组长度限制。因此建议输入时不要越界。
- 字符串若直接赋给指针(没有分配空间)或者数组(没有说明长度),那么程序会在后面自动补’\0’
4.演示验证说明
-
test1字符串直接赋值给指针,程序会在内存中申请一段字符串长度+1的空间(+1是为了在后面补’\0’),然后将这段空间的首地址赋值给指针。因此strlen得到4,至于sizeof因为我的电脑是64位所以返回8。
-
test2预先申请了6个char空间:
-
在赋值时只给4个字符,那么后面两个字符自动补’\0’,因此strlen=4,sizeof因为是指针所以返回8。
-
在赋值时通过%s格式化输入突破了输入限制,给到了6个字符和7个字符,实际上这不符合规范,虽然没有报错但是越界了。
这里因为此程序所用到的内存小,所以很幸运我们用到的内存后面紧接的内存系统默认为\0,所以strlen分别得到6与7。
如果所用到的内存后面紧跟着的内存也被程序使用了,那么这时strlen得到的就不是6和7了。sizeof因为是指针所以返回8。举个例子:
1.申请六个内存空间,且这六个后的内存空间也没有被使用:_ _ _ _ _ _ \0 \0 \0 …
输入qwer四个字符:q w e r \0 \0 \0 \0 \0 …,strlen得到4,没有问题。
输入qwerty六个字符:q w e r t y \0 \0 \0 …,strlen得到6,很幸运没有问题。
1.申请六个内存空间,且这六个后的内存空间被使用:_ _ _ _ _ _ a b \0 …
输入qwer四个字符:q w e r \0 \0 a b \0 …,strlen得到4,没有问题。
输入qwerty六个字符:q w e r t y a b \0 …,出问题了,strlen得到的结果为8!
-
-
test3将字符串直接赋值给数组(没有指定长度),与test1一样,程序申请一段字符串长度+1的空间,然后将首字母赋值给数组,因此输入qwer,得到strlen为4,又因为是数组,sizeof返回数组具体的长度,为5。
-
test4中体现,如果数组指定长度,并且你想给数组赋值,那么赋值的字符串长度一定要小于数组长度,至少留出一个给\0的空间,否则会报错。
-
test5比test4多预留了一个\0的空间,因此可以运行,运行结果strlen=4,siezof=5。
-
test6的情况与test3一样,使用%s格式化输入突破了数组长度的限制,strlen返回的情况与test3一致,而sizeof因为是数组,因此返回数组的长度。
5.总结
- 可以直接将字符串赋值给没有分配空间的指针或者没有指定长度的数组。
- 若指针已分配空间或者数组长度指定,那么填写的字符串应该预留一个位置。相应的,如果已有字符串数组要有指针或者数组保存,那么申请的空间应该多一个。