c语言 - 是否可以将字符存储在定义为整数的数组中?



定义为int数组如何存储字符串值?看看代码,arri[]被定义为整数但存储字符串值?此外,定义为字符的数组正在存储整数值。这怎么可能?

int main(void) {
int arri[] = {'1' , '2', 'a'};
int *ptri = arri;
char arrc[] = {11, 21 ,  31 };
char *ptrc = arrc;
printf("%d" , *arri);
printf("%d" , *ptri);
printf("%d" , *arrc );
printf("%d" , *ptrc);
return 0;
}

定义为 int 的数组如何存储字符串值?

您提供的代码段中没有字符串。

在本声明中

int arri[] = {'1' , '2', 'a'};

表示具有int类型的整数字符常量的初始值设定项用于初始化数组的元素。这些字符常量作为其代码在内部存储。例如,在 ASCII 字符表中,内部的整数字符常量具有相应的值 49、50 和 97。

这是一个演示程序

#include <stdio.h>
int main(void) 
{
int arri[] = {'1' , '2', 'a'};
const size_t N = sizeof( arri ) / sizeof( *arri );

for ( size_t i = 0; i < N; i++ )
{
printf( "'%c' = %d ", arri[i], arri[i] );
}

putchar( 'n' );

return 0;
}

程序输出为

'1' = 49 '2' = 50 'a' = 97 

当使用转换说明符%c时,函数printf尝试将它们输出为(图形)符号。

请注意,当转换说明符%d用于输出char类型的对象时,将执行整数提升,将类型char的对象提升为类型int的表达式。

在本声明中

char arrc[] = {11, 21 , 31 };

整数常量具有适合可存储在类型为char的对象中的值范围的值。

在这两种情况下,都没有截断或溢出。

首先要明确的是,不要将像'a'这样的字符实际存储在计算机内的任何地方。您实际上存储了一个数字。对于'a',该数字是十进制 97。计算机本身不知道这是一个'a'。计算机仅将其视为一个数字。只有当您将该号码发送到需要字符的设备(例如终端、打印机等)时,某些设备驱动程序才会更改数字以显示字符'a'

有关字符和数字之间映射的说明,请参阅 https://en.wikipedia.org/wiki/ASCII。

C 标准允许您使用字符,就好像它们是数字一样。编译器会自动将字符转换为相应的数字。因此

int x = 'a';

int x = 97;

和您的生产线

int arri[] = {'1' , '2', 'a'};

int arri[] = {49 , 50, 97};

如前所述,类型char只是存储数字 - 就像类型int一样。区别只是可以存储的数字范围。通常,char是 1 字节的内存,int是 4 个字节(但它取决于系统)。

所以这段代码

char arrc[] = {11, 21 ,  31 };

只需存储这 3 个十进制数字。通常为每个数字使用 1 个字节。

交错部分是这一行:

printf("%d" , *arrc );

这里*arrc是存储在 1 字节中的数字 11(通常)。那么如何使用期望int%d打印它呢?

答案是"默认参数提升"。对于可变参数函数(如printf),这意味着"小于"int的整数类型应在函数调用之前转换为int。请注意,char被视为整数类型,因此这也适用于char

因此,在您的情况下,存储在char(1 字节)中的数字 11 将自动转换为存储在int(4 字节)中的数字 11。因此,printf函数将收到一个int,并且能够打印出来。

在语句中

int foo = 3.14159;

double值将自动转换为int(3)[隐式转换]。没有什么可以禁止转换,所以同义("从doubleint")是可以的。

与您的示例相同

char foo = 65; // the int value is implicitly converted to type char
char bar[] = { 66, 67, 0 }; // 3 conversions ok
char baz = 20210914; // possibly erroneous conversion from int to char
// in this case the compiler will, probably, warn you
// 20210914 is beyond the range of char, so this is, technically, UB

请注意,

int a = 'b';

上面的'b'int类型的值,因此实际上没有转换。

char b = 'c'; // implicit conversion from int to char ok
int c = b; // implicit conversion from char to int ok

最新更新