我对C中的int和chars有一点(大,愚蠢?)的问题。我从学习中记得“chars是小整数和反之亦然”,这对我来说没问题。如果我需要使用小数字,最好的方法是使用char类型。
但是在这样的代码中:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int i= atoi(argv[1]);
printf("%d -> %c\n",i,i);
return 0;
}
我可以使用我想要的每个数字作为参数。所以0-127我获得了预期的结果(标准的ASCII表),但即使有更大或更负的数字,它似乎也有用......
以下是一些例子:
-181 -> K
-182 -> J
300 -> ,
301 -> -
为什么呢?在我看来,它在ascii表周围循环,但我不明白如何。
答案 0 :(得分:5)
当您传递对应于“%c”转换说明符的int时,int将转换为unsigned char然后写入。
当您传递的值超出无符号范围(0到UCHAR_MAX)时,它们将被转换为不同的值。您正在使用的系统可能具有UCHAR_MAX == 255。
将int转换为unsigned char:
因此:
(unsigned char)-181 == (-181 + (255+1)) == 75 == 'K'
(unsigned char)-182 == (-182 + (255+1)) == 74 == 'J'
(unsigned char)300 == (300 - (255+1)) == 44 == ','
(unsigned char)301 == (301 - (255+1)) == 45 == '-'
答案 1 :(得分:2)
%c format参数将相应的值解释为字符,而不是整数。但是,当你对printf撒谎并在你告诉它是一个char时传递一个int时,它对值的内部操作(为了获得一个char,作为一个char通常作为一个int传递,无论如何,使用varargs)恰好产生你看到的价值观。
答案 2 :(得分:1)
我的猜测是%c获取所提供值的第一个字节并将其格式化为字符。在诸如运行Windows的PC之类的小端系统上,该字节将代表传入的任何值的最低有效字节,因此连续数字将始终显示为不同的字符。
答案 3 :(得分:0)
编辑:请忽略这个“答案”。
因为你在小端机器上:)
无论如何,这是一种未定义的行为。尝试将代码更改为printf("%d -> %c, %c\n",i,i,'4');
,然后看看会发生什么......
答案 4 :(得分:0)
你告诉它这个数字是一个字母,所以尽管它太大了,但它会尝试各种方式来对待它。 看看你得到了什么,因为J和K按顺序排列,我会说它使用整数%128来确保它符合法定范围。
答案 5 :(得分:0)
当我们在printf语句中使用%c时,它只能访问整数的第一个字节。 因此,大于256的任何东西都被视为n%256。
例如 i / p = 321产生op = A
答案 6 :(得分:-1)
atoi所做的是将字符串转换为数值,以便“1234”获得1234而不仅仅是字符串序数的序列。
示例:
char *x = "1234"; // x[0] = 49, x[1] = 50, x[2] = 51, x[3] = 52 (see the ASCII table)
int y = atoi(x); // y = 1234
int z = (int)x[0]; // z = 49 which is not what one would want