简体   繁体   English

C printf 打印一个我没有要求的数组

[英]C printf prints an array that I didn't ask for

I have recently started learning C and I got into this problem where printf() prints an array I didn't ask for.我最近开始学习 C,我遇到了 printf() 打印一个我没有要求的数组的问题。 I was expecting an error since I used %s format in char array without the '\0', but below is what I got.我期待一个错误,因为我在没有'\0'的char数组中使用了%s格式,但下面是我得到的。

char testArray1[] = { 'a','b','c'};
char testArray2[] = { 'q','w','e','r','\0' };

printf("%c", testArray1[0]);
printf("%c", testArray1[1]);
printf("%c\n", testArray1[2]);

printf("%s\n", testArray1);

the result is结果是

abc
abcqwer

thanks谢谢

The format "%s" expects that the corresponding argument points to a string: sequence of characters terminated by the zero character '\0' .格式"%s"期望相应的参数指向一个字符串:由零字符'\0'终止的字符序列。

printf("%s\n", testArray1);

As the array testArray1 does not contain a string then the call above has undefined behavior.由于数组testArray1不包含字符串,因此上面的调用具有未定义的行为。

Instead you could write相反,你可以写

printf("%.*s\n", 3,testArray1);

or或者

printf("%.3s\n", testArray1);

specifying exactly how many elements of the array you are going to output.准确指定要输出的数组元素的数量。

Pay attention to that in C instead of these declarations注意 C 中的,而不是这些声明

char testArray1[] = { 'a','b','c'};
char testArray2[] = { 'q','w','e','r','\0' };

you may write你可以写

char testArray1[3] = { "abc" };
char testArray2[] = { "qwer" };

or that is the same或者是一样的

char testArray1[3] = "abc";
char testArray2[] = "qwer";

In C++ the first declaration will be invalid.在 C++ 中,第一个声明将无效。

Add zero at the end of first array:在第一个数组的末尾添加零:

char testArray1[] = { 'a','b','c', 0 };

Otherwise printf continues with memory after 'c' until zero byte and there is the second array.否则printf'c'之后继续使用内存,直到零字节并且有第二个数组。

PS: zero 0 is 100% identical to longer ASCII '\0' . PS:零0与更长的 ASCII '\0' 100% 相同。

%s indeed stop when encountered \0 , but testArray1 didn't have that \0 , so it keeps printing the following bytes in the memory. %s在遇到\0时确实停止了,但是testArray1没有那个\0 ,所以它会继续在内存中打印以下字节。

And the compiler magically(actually intentionally) places the testArray2 next to testArray1 , the memory is like:并且编译器神奇地(实际上是故意)将testArray1放在testArray2旁边,内存就像:

a b c q w e r \0
^                testArray1 starts here
      ^          testArray2 starts here

And the %s will print all of those chars above until it meets a \0 .并且%s将打印上面的所有这些字符,直到它遇到\0

You can validate that by:您可以通过以下方式验证:

printf("%d\n", testArray2 == testArray1 + 3);
// prints `1`(true)

As your question, there was no error because the a ... r \0 sequece in memory is owned by your process.作为您的问题,没有错误,因为内存中的a ... r \0序列归您的进程所有。 Only the program is trying to access an address not owned by it, the OS will throw an error.只有程序试图访问不属于它的地址,操作系统才会抛出错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM