在C99中,通常使用char*
数据类型初始化字符串,因为没有原始的“字符串”数据类型。这通过在变量中存储第一个char的地址来有效地创建一个字符数组:
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.
编译器如何知道char* s
是一个字符串,而不仅仅是单数char
的地址?如果我使用int*
,它只会允许一个int
,而不是它们的数组。为什么不同?
我的主要关注点是了解指针,引用和解引用是如何工作的,但整个char*
一直在弄乱我的脑袋。
答案 0 :(得分:16)
编译器如何知道
char* s
是一个字符串,而不仅仅是一个单数字符的地址?
没有。就“编译器”而言,char* s
是指向char的指针。
另一方面,有许多库函数假设char*
指向null-terminated sequence of char
的元素(例如参见strlen
,strcmp
等。 )。
请注意fwrite
没有做出这个假设。它要求你告诉它你要写多少字节(并且这个数字不会超出第一个参数所指向的缓冲区的范围。)
如果我使用
int*
,它只允许一个int,而不是它们的数组。为什么不同?
这是不正确的。 C语言没有char*
的特例。 int*
也可以指向int
数组的元素。实际上,您可以编写一个使用0
或其他标记值来表示int
序列结束的库,并使用它与char*
中的 onNext: function(tab, navigation, index)
{
if ($('#validateSubmitForm').validate().form())
{
return true;
}
else
{
return false;// prevent moving on if the form is invalid
}
..............
$(function()
{
// validate form on keyup and submit
$("#validateSubmitForm").validate({
rules: {
firstname: "required",
lastname: "required",
username: {
required: true,
minlength: 2
},
................
一样使用它约定。
答案 1 :(得分:7)
在您的代码中
fwrite(s, 12, 1, out);
相当于写作
写入12个大小为1字节的元素,位置从地址
s
开始到out
指向的文件。
下面。 char
完全是一个字节,因此您可以获得所需的输出。
编译器如何知道
char* s
是一个字符串,而不仅仅是单数char
的地址?
嗯,它没有(也不需要)。您要求(从s
读取)并写入12个字节,因此它会这样做。如果内存不可访问,那就是编程错误。 fwrite()
本身不会处理。
<强>当心强>:
s
没有分配到s[11]
(技术上)访问的内存,则它将是undefined behaviour。程序员可以将有效值作为参数传递给它。 如果是int
,则大小为4
字节(通常在32位系统上),逐字节打印不会给您提供所需的结果。
在这种情况下,您需要使用fprintf()
来打印格式化的输出。
答案 2 :(得分:0)
编译器除了char *之外没有任何想法是一个角色的地址。我们可以通过递增第一个字符的地址来读取下面的字符。这种情况类似于任何指针int *,long *等,编译器只是将指针视为指向其类型地址的东西。