Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中的字符数组和字符串终止字符_C_Arrays_String_Printf - Fatal编程技术网

C语言中的字符数组和字符串终止字符

C语言中的字符数组和字符串终止字符,c,arrays,string,printf,C,Arrays,String,Printf,我知道在C中,\0终止字符串。 我们可以将字符串和字符数组都分配给字符数组 char c1[] = "hello"; char c2[] = {'h','e','l','l','o'}; 但是,我知道字符数组没有\0作为终止字符: printf("%d\n",sizeof(c1)); //6 printf("%d\n",sizeof(c2)); //5 但是,当我打印它们时,我会看到如下内容: printf("%s\n",c1); //hello printf("%s\n",c2); /

我知道在C中,
\0
终止字符串。 我们可以将字符串和字符数组都分配给字符数组

char c1[] = "hello";
char c2[] = {'h','e','l','l','o'};
但是,我知道字符数组没有
\0
作为终止字符:

printf("%d\n",sizeof(c1));  //6
printf("%d\n",sizeof(c2));  //5
但是,当我打印它们时,我会看到如下内容:

printf("%s\n",c1); //hello
printf("%s\n",c2); //helloV
问题1。如果我重新运行它,第二行有时打印
helloU
,有时打印
helloV
。为什么会这样

问题2。另外,字符数组可以包含终止字符串
\0
,也可以不包含终止字符数组
\0

char c1[] = "hello";
char c2[] = {'h','e','l','l','o'};
第三季度。我知道
printf
遇到
\0
时终止。当未遇到
\0
时,
printf
的行为如何

  • c2
    不是字符串,因此将其传递给
    printf
    %s
    具有未定义的行为。未定义的行为是未定义的。从技术上讲,它不需要打印任何内容。它也可以删除你所有的文件或进入无限循环或
  • 并非所有字符数组都是字符串。只要不将其传递给需要字符串的函数,就可以在字符数组中存储所需的任何内容
  • 它有未定义的行为

  • printf
    遇到
    \0
    时停止读取内存。在使用
    c2
    的示例中,您不知道
    printf
    何时停止读取,因为您不知道下一个
    \0
    在内存中的位置
    printf
    确实在读取随机内存,这解释了为什么您无法预测屏幕上会打印什么。最终,您可能会开始读取不属于您的程序的内存。如果发生这种情况,大多数操作系统将立即终止您的程序

    想想这个简单的例子:

    int a;
    printf("%d", a);
    

    您无法预测
    a
    将包含什么内容,因此无法预测屏幕上将打印什么内容。在您的示例中发生了完全相同的情况,您不知道第二个数组中的
    'o'
    后面是什么。

    1-未定义的行为;2-ok(因为不是每个字符数组都是字符串);3-未定义的行为#1,未定义的行为。Printf正在寻找尾随的0,它不在那里,它一直在寻找,直到找到一个(#3),但是为什么
    Printf
    只打印
    helloU
    helloV
    ,我的意思是为什么只打印
    U
    V
    为什么总是六个字符?为什么不更多?这取决于调试器/操作系统初始化内存的方式。在我的机器上(macOS Mojave,Xcode 10),我得到了
    hellohello
    。这种未定义的行为似乎总是遵循一种“模式”,这一事实并不意味着它不那么未定义。试着运行你的代码,你会得到不同的结果。另外,试着交换
    c1
    c2
    的声明。这将改变数组在内存中的布局方式,也可能会改变输出。但我仍然很好奇为什么
    printf
    只打印
    helloU
    helloV
    ,我的意思是为什么只打印
    U
    V
    ,为什么总是六个字符?为什么不更多?@anir这取决于平台/编译器的详细信息。您必须查看生成的代码、堆栈布局等。(1)“
    并非所有字符数组都是字符串。
    ”如何区分它们?使用
    \0
    终止与不使用
    \0
    终止相比。(2) “
    只要不将其传递给需要字符串的函数,就可以在字符数组中存储所需的任何内容。
    ”,您的意思是,如果不将字符数组传递给需要字符串的函数,就可以忘记在其中包含
    \0
    ,这样仍然可以吗?