为什么基本C代码抛出访问冲突

为什么基本C代码抛出访问冲突,c,exception,C,Exception,我是C编程新手。我正在努力学习。以下代码引发访问冲突。为什么会这样?请解释一下。如何修复它 char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' }; printf("%s", arr[0]); %s表示打印所有字符,直到找到空值为止。请将变量视为指针 %c表示只打印一个字符,将变量视为字符代码 对字符使用%s不起作用,因为该字符将被视为指针,然后它将尝试打印内存中该位置后面的所有字符,直到找到空值。%s表示打印C字符串,而“a”不是C字符串,而是字符,这是单

我是C编程新手。我正在努力学习。以下代码引发访问冲突。为什么会这样?请解释一下。如何修复它

char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
printf("%s", arr[0]);
%s表示打印所有字符,直到找到空值为止。请将变量视为指针

%c表示只打印一个字符,将变量视为字符代码

对字符使用%s不起作用,因为该字符将被视为指针,然后它将尝试打印内存中该位置后面的所有字符,直到找到空值。

%s表示打印C字符串,而“a”不是C字符串,而是字符,这是单引号分隔的

最终发生的情况是,您的arr被解释为C字符串,但由于它没有正确地以NUL终止,程序会从末尾进入无效内存,从而触发错误

修复方法是使用%c打印单个字符或终止数组:

char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f', 0 };

%s代表需要空终止的字符*,即“C-字符串”。在您的代码中,由于缺少空字符,您会收到错误,因为正在访问其他内存位置以查找空字符

char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f', '\0' };
printf("%s", &arr[0]);
%s格式说明符需要一个char*char指针作为输入,该指针指向以空结尾的字符数组的开头

arr本身可以被视为指向第一个元素的指针。 这意味着char arr[]被视为char*const arr。 区别在于sizeofarr在第一个示例中返回数组的实际大小(以字节为单位)

可能的解决办法

%s转换说明符要求相应的参数具有char*类型,并包含以0结尾的字符串中第一个字符的地址。您收到访问冲突,因为“a”ASCII 97不是有效地址

如果要打印单个字符a,请改用%c转换说明符:

printf( "%c\n", arr[0] );
如果要打印arr中包含的字符串,首先必须添加终止符:

char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f', 0 }; // or "abcdef";
然后使用%s转换说明符并按如下方式传递arr:

printf( "%s\n", arr ); // or &arr[0], which does the same thing

%s代表字符*。对char数据类型使用%c规范。“a”是整数值97,因此您告诉它以字符串形式打印在内存地址97处找到的任何内容,该地址可能是有效地址,也可能不是有效地址,即使是有效地址,也会有随机内容。我忘了添加,%s表示以null结尾的char*数据类型。@LeeDanielCrocker在大多数现代台式机上,整个零页(VM的前4k)被映射为无访问以触发此类结果您仍然需要指针,而不是值,即&arr[0]或arr。我的错误,这是一个印刷错误。
char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f', 0 }; // or "abcdef";
printf( "%s\n", arr ); // or &arr[0], which does the same thing