C中char数组的最后一个字符
last char of a char array in C
我正在学习 C,教程中的 char 数组的概念似乎与我观察到的有冲突。
#include <stdio.h>
int main(){
char input[64];
printf("%c is found for the last index\n", input[64]);
return (0);
}
根据教程,此 char 数组最多可容纳 63 个字符,并在 64 个字符的字符串末尾添加一个空字符。
但它输出( is found for the last index
,它既不是空的也不是显示的\0字符。为了理解,我在这里缺少什么?或者我的编译器是否表现不佳?
这个char数组又名字符串没有初始化,所以它只是指向一个长度为64字节的数据,供你使用,直到你为它设置一个值,它指向的数据就是它的“垃圾” " 随机数据。
如果你再运行它,你可能还会得到不同的结果。
注意,即使给字符串赋值后,最后一个字符后的下一个字符确实会是null,但null之后仍然是垃圾数据。
此外,正如我在其他评论中看到的那样,索引 64 超出范围,在跟踪其长度的容器中你会得到一个错误,最后一个字符是 size - 1
,意思是63.
但它输出 (
is found for the last index, which is not either empty or [=14=]
索引64
实际上是超出分配给数组input
的内存的一个内存位置。尝试访问不属于进程的内存区域会调用 undefined behavior
创建数组,例如:
char input[64];// 64 (unknown) char elements
数组括号表示数组的元素个数
当使用数组时,C
索引总是从0
到N - 1
,在这种情况下63
printf("%c is found for the last index\n", input[63]); // will return the last char in the array
在这种情况下可能是也可能不是 [=14=]
。
总是建议初始化数组:
char input[64] = {0};// 64 char elements, all initialized to zero (`[=12=]`)
首先,input[64]
超出范围。 C 使用 zero-based 数组,所以这里只有索引 0..63 是有效的。读取超出范围的元素会导致获取不可预测的数据,写入超出范围可能会导致程序数据和代码崩溃。 (顺便说一句,超出字符串缓冲区范围的访问是程序安全漏洞的一个非常常见的原因。)
其次,您使用的数组未初始化,因此您可能会得到任何元素的任何不可预测的(垃圾,随机)值。要用零初始化它,你可以写
char input[64] = {0};
第三,字符串和字符数组不是一回事。每个像 "Hello, world"
这样的字符串文字是 zero-terminated 包含 12 个字符串字符和 1 个零字符的字符串,正确调用每个标准字符串会将 zero-terminated 字符串保存到 char 数组中(先前分配的字符串缓冲区) .要将这样的字符串存储在缓冲区(数组)中,该数组应该为每个字符和零字符留出空间。但不是任何字符数组都应该包含一个字符串,它可能只是一个要以 zero-terminated 字符串以外的方式处理的任何字符的数组。要在示例中保存字符串,您可以使用
char input[64] = "Hello, world";
但只有 input[12]
会是 '[=15=]'
(零字符),input[13]
.. input[63]
仍未初始化。
我正在学习 C,教程中的 char 数组的概念似乎与我观察到的有冲突。
#include <stdio.h>
int main(){
char input[64];
printf("%c is found for the last index\n", input[64]);
return (0);
}
根据教程,此 char 数组最多可容纳 63 个字符,并在 64 个字符的字符串末尾添加一个空字符。
但它输出( is found for the last index
,它既不是空的也不是显示的\0字符。为了理解,我在这里缺少什么?或者我的编译器是否表现不佳?
这个char数组又名字符串没有初始化,所以它只是指向一个长度为64字节的数据,供你使用,直到你为它设置一个值,它指向的数据就是它的“垃圾” " 随机数据。 如果你再运行它,你可能还会得到不同的结果。
注意,即使给字符串赋值后,最后一个字符后的下一个字符确实会是null,但null之后仍然是垃圾数据。
此外,正如我在其他评论中看到的那样,索引 64 超出范围,在跟踪其长度的容器中你会得到一个错误,最后一个字符是 size - 1
,意思是63.
但它输出 (
is found for the last index, which is not either empty or [=14=]
索引64
实际上是超出分配给数组input
的内存的一个内存位置。尝试访问不属于进程的内存区域会调用 undefined behavior
创建数组,例如:
char input[64];// 64 (unknown) char elements
数组括号表示数组的元素个数
当使用数组时,C
索引总是从0
到N - 1
,在这种情况下63
printf("%c is found for the last index\n", input[63]); // will return the last char in the array
在这种情况下可能是也可能不是 [=14=]
。
总是建议初始化数组:
char input[64] = {0};// 64 char elements, all initialized to zero (`[=12=]`)
首先,input[64]
超出范围。 C 使用 zero-based 数组,所以这里只有索引 0..63 是有效的。读取超出范围的元素会导致获取不可预测的数据,写入超出范围可能会导致程序数据和代码崩溃。 (顺便说一句,超出字符串缓冲区范围的访问是程序安全漏洞的一个非常常见的原因。)
其次,您使用的数组未初始化,因此您可能会得到任何元素的任何不可预测的(垃圾,随机)值。要用零初始化它,你可以写
char input[64] = {0};
第三,字符串和字符数组不是一回事。每个像 "Hello, world"
这样的字符串文字是 zero-terminated 包含 12 个字符串字符和 1 个零字符的字符串,正确调用每个标准字符串会将 zero-terminated 字符串保存到 char 数组中(先前分配的字符串缓冲区) .要将这样的字符串存储在缓冲区(数组)中,该数组应该为每个字符和零字符留出空间。但不是任何字符数组都应该包含一个字符串,它可能只是一个要以 zero-terminated 字符串以外的方式处理的任何字符的数组。要在示例中保存字符串,您可以使用
char input[64] = "Hello, world";
但只有 input[12]
会是 '[=15=]'
(零字符),input[13]
.. input[63]
仍未初始化。