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值。
有人可以帮助我吗?
答案 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
个对象,所以所有的赌注都已关闭。