char到整数指针转换

时间:2017-08-20 06:38:22

标签: c pointers

void main()
{
 char *s="ABCDEFG";
 clrscr();

 int *ptr=(int *)s;
 printf("%c %d\n",*(ptr+1),*(ptr+1));          //OP :- C 17475
 printf("%c %d\n",*(s+1),*(s+1));              //OP :- B 66

 getch();
}

我知道整数指针增加2个字节,而char指针增加1个字节。 这里当int指针递增1时,只打印C(只考虑第一个字节)。是因为我们有%c说明符吗?

另外,我无法理解17475是如何打印输出的。在第二种情况下,66是B的ASCII值。

有人可以帮助我吗?

3 个答案:

答案 0 :(得分:3)

首先,请注意您的代码有未定义的行为。这意味着我们只能通过参考C标准来谈论生成的输出。输出可能/将因系统而异,某些系统甚至可能无法执行代码。

问题是你有一些char(一个char数组)但你使用int指针访问它。这是不允许的。

但是,在特定系统(您的系统)上,可以考虑输出的原因。 但请记住它不是有效的C代码。 注意:正如Antti Haapala所指出的,代码语法是有效的 - 它只是程序的行为未定义< / em>的

字符串(又名字符数组)将放在内存中的某处,如:

Address |    Bin    | Hex | Dec | Ascii char
--------------------------------------------
 base   | 0100 0001 |  41 | 65  | A
 base+1 | 0100 0010 |  42 | 66  | B
 base+2 | 0100 0011 |  43 | 67  | C
 base+3 | 0100 0100 |  44 | 68  | D
 base+4 | 0100 0101 |  45 | 69  | E
 and so on

请注意,内存中包含二进制值。十六进制,十二月,Ascii列只是一个&#34;人类&#34;查看相同的二进制值。

您的指针s的值为base,即它指向包含值0100 0001(也称为A)的内存位置。

然后你也ptr指向base

打印时(即printf("%c %d\n",*(ptr+1),*(ptr+1));),ptr+1将指向一个取决于整数大小的位置(因系统而异)。由于int的大小为2,ptr+1的位置为base + 2,即0100 0011(又称C)。

所以本声明的第一部分:

printf("%c %d\n",*(ptr+1),*(ptr+1));
        ^^       ^^^^^^^^

打印C,即位置base+2处的字符。

第二部分

printf("%c %d\n",*(ptr+1),*(ptr+1));
           ^^             ^^^^^^^^

打印位于base+2的整数值。 (注意 - 这是非法的,因为那里没有整数,但让我们暂时忘记它。)

在您的情况下,int是两个字节。因此,使用的字节将是C(十六进制:0x43)和D(十六进制:0x44)。打印的值取决于系统的字节顺序。

Big endian(MSB优先)将给出:

0x4344 which is 17220 in decimal

Little endian(LSB优先)将给出:

0x4443 which is 17475 in decimal

所以从这看起来你的系统似乎是小端。

正如你所看到的,很多这些东西都是系统依赖的,从C标准的角度来看,不可能知道它会是什么。

答案 1 :(得分:0)

当指向整数ptr的指针递增时,在你的情况下它增加2个字节。 即,ptr+1指向"CDEFG"。 当您使用字符指针取消引用此位置时,只有第一个字节C被视为sizeof(char)1

但是当它被视为整数时,将考虑2个字节,因为在您的情况下sizeof(int)2

在你的机器中,这些位是(因为字节顺序)

+----+----+----+----+----+----+---+---+---+---+---+---+---+---+---+---+
| 0  | 1  | 0  | 0  | 0  | 1  | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 1 |
+----+----+----+----+----+----+---+---+---+---+---+---+---+---+---+---+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+----+----+----+----+----+----+---+---+---+---+---+---+---+---+---+---+

其中上排是位,下排是一些索引,我将用它来指代各个位。

比特0-7是角色的二进制表示&#39; C&#39;其ASCII值为67。 第8-15位是字符“D&#39;”的二进制表示。其ASCII值为68。

ptr+1指向从位0开始的位置。当该值被视为整数(大小为2个字节)时,将使用这两个字节。 即,“C&C”的二进制文件。和&#39; D&#39;用于查找整数的值。

这个二进制表示的十进制值是17475,这是你得到的值。

编辑:由于strict aliasing rule,您的代码似乎可能有未定义的行为。

答案 2 :(得分:0)

您的代码违反严格别名规则会导致未定义的行为。任何输出都没有意义。

使用int类型的表达式(即*(ptr+1))来访问内存。严格别名规则表明此内存必须具有{em>有效类型 int(或相关类型,如const int等)。但是内存实际上包含char个对象,所以所有的赌注都已关闭。