char*char数组,但int*不是i​​nt数组?

jni*_*m78 7 c arrays string pointers

在C99中,通常使用char*数据类型初始化字符串,因为没有原始的"字符串"数据类型.这通过在变量中存储第一个char的地址有效地创建了一个chars数组:

FILE* out = fopen("out.txt", "w");
char* s = argv[1];
fwrite(s, 12, 1, out);
fclose(out);
//successfully prints out 12 characters from argv[1] as a consecutive string.
Run Code Online (Sandbox Code Playgroud)

编译器如何知道这char* s是一个字符串而不仅仅是单数的地址char?如果我使用int*它只会允许一个int,而不是它们的数组.为什么不同?

我的主要关注点是理解指针,引用和解引用是如何工作的,但整体char*仍然在弄乱我的脑袋.

jua*_*nza 16

编译器如何知道这char* s是一个字符串而不仅仅是单个字符的地址?

它没有.就"编译器"而言,char* s是指向char的指针.

另一方面,有许多库函数假设char*指向空终止序列char的元素(例如strlen,参见strcmp等).

请注意,fwrite这并不是这个假设.它要求您告诉它要写入多少字节(并且该数字不会超出第一个参数指向的缓冲区的范围.)

如果我使用int*它将只允许一个int,而不是它们的数组.为什么不同?

那是不对的.C语言没有特殊情况char*.An int*也可以指向数组的元素int.实际上,您可以编写一个使用0或另一个sentinel值的库来指示序列的结束int,并使用它与char*常规使用的相同.


Sou*_*osh 7

在你的代码中

fwrite(s, 12, 1, out);
Run Code Online (Sandbox Code Playgroud)

相当于写作

写12个大小为1字节的元素,位置从地址开始s到指向的文件out.

这里.a char恰好是一个字节,因此您可以获得所需的输出.

编译器如何知道这char* s是一个字符串,而不仅仅是一个单数的地址char

嗯,它不(并且不需要).你要求(读取s和)写入12个字节,所以它会这样做.如果内存不可访问,那就是编程错误.fwrite()本身不会处理.

当心:

  • 如果s没有分配要访问的内存s[11](技术上),它将是未定义的行为.程序员可以将有效值作为参数传递.

如果是int,大小是4字节(通常,在32位系统上),逐字节打印将无法提供所需的结果.

在这种情况下,您需要使用fprintf()打印格式化输出.