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*常规使用的相同.
在你的代码中
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()打印格式化输出.