C 字符到整数指针转换

C 字符到整数指针转换,c,pointers,C,Pointers,我知道整数指针增加2个字节,而字符指针增加1个字节。 这里,当int指针增加1时,只打印C(只考虑第一个字节)。是因为我们有%c说明符吗 此外,我无法理解17475是如何作为输出打印的。在第二种情况下,66是ASCII值B 有人能帮我吗?当指向integerptr的指针增加时,在您的情况下,它会增加2个字节。 例如,ptr+1指向“CDEFG”。 使用字符指针取消引用此位置时,只有第一个字节C被视为sizeof(char)是1 但当它被视为整数时,2个字节将被视为与您的情况相同的sizeof(i

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

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


有人能帮我吗?

当指向integer
ptr
的指针增加时,在您的情况下,它会增加2个字节。 例如,
ptr+1
指向
“CDEFG”
。 使用字符指针取消引用此位置时,只有第一个字节
C
被视为
sizeof(char)
1

但当它被视为整数时,2个字节将被视为与您的情况相同的
sizeof(int)
is
2

在您的机器中,位是(因为端性)

其中,上行是位,下行是一些索引,我将使用它们来表示各个位

位0-7是ASCII值为67的字符“C”的二进制表示形式。 位8-15是ASCII值为68的字符“D”的二进制表示形式

ptr+1
指向从位0开始的位置。当该值被视为整数(大小为2字节)时,将同时使用两个字节。 也就是说,使用“C”和“D”的二进制来查找整数的值

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


编辑:您的代码可能有未定义的行为,因为。

您的代码违反了严格的别名规则,从而导致未定义的行为。任何输出都是毫无意义的


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

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

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

但是,在特定的系统(您的系统)上,可以考虑为什么输出看起来像这样但请记住它不是有效的C代码。注意:正如Antti Haapala所指出的,代码语法是有效的-只是程序的行为没有定义

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

+----+----+----+----+----+----+---+---+---+---+---+---+---+---+---+---+
| 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 |
+----+----+----+----+----+----+---+---+---+---+---+---+---+---+---+---+
请注意,内存包含二进制值。十六进制、十进制、Ascii列只是相同二进制值的“人工”视图

您的指针
s
具有值
base
,即它指向保存值
0100 0001
(又称A)的内存位置

然后让
ptr
也指向
base

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

因此,本声明的第一部分:

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
打印一个
C
,即位于
base+2
位置的字符

第二部分

printf("%c %d\n",*(ptr+1),*(ptr+1));
        ^^       ^^^^^^^^
打印位于
base+2
处的整数值。(注意-这是非法的,因为这里没有整数,但让我们暂时忘记这一点)

在您的例子中,
int
是两个字节。因此,使用的字节将是
C
(十六进制:0x43)和
D
(十六进制:0x44)。打印的值将取决于系统的末端

Big-endian(MSB优先)将给出:

printf("%c %d\n",*(ptr+1),*(ptr+1));
           ^^             ^^^^^^^^
0x4344 which is 17220 in decimal
Little endian(LSB优先)将提供:

printf("%c %d\n",*(ptr+1),*(ptr+1));
           ^^             ^^^^^^^^
0x4344 which is 17220 in decimal
因此,从这个角度来看,你的系统似乎是小endian


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

可能重复的Huh。17475确实是使用ASCII编码、小端整数存储、
CHAR\u BIT==8
sizeof(int)==2
(违反最小
int\u MAX
的标准要求)的系统的打印值。您在哪里找到这个编译器?@Zephyr-原则上是的-是
%c
说明符导致了c的打印。但是,这是未定义的行为,不能仅从c标准解释输出。请参阅BTW-int的大小也因系统而异,因此int指针也不会增加2。更常见的是它们增加4。@Zephyr-我们决定用十进制、十六进制或二进制来写一个数字只是为了方便,即键入更少的字母,例如,我们写129(十进制)或81(十六进制),而不是
10000001
(二进制)。在计算机内部,一切都是二进制的。我使用十六进制是因为十进制很笨拙:十进制数“存储”在纸上的方式意味着每个数字都代表10的幂,而不必这样说。但是计算机并没有以这种格式存储整数——每个字节代表256的幂。在十进制中,为了解释字节序列
67 68
,我需要说
67+68*256
,因为字节存储的基数是256而不是10。用十六进制写它更方便,比如
0x4443
@4386427,那么改为“指向从位0开始的位置”怎么样?需要注意的一点是:这是非常有效的C代码,遵循标准的语法,可能