C++ 理解'&';操作人员
据我所知,&运算符返回内存中操作数的基址 让我们想象以下场景(在我的机器上):C++ 理解'&';操作人员,c++,c,C++,C,据我所知,&运算符返回内存中操作数的基址 让我们想象以下场景(在我的机器上): sizeof(int)=4个字节 sizeof(float)=4字节 sizeof(char)=1字节 现在,如果我这样写: void main() { int i = 5411; int *ip = &i; char *c = &i; printf("%d",*ip); printf("%c",*c); } 第一个printf()应该是5411。谈到第二个printf(),i的基址
- sizeof(int)=4个字节
- sizeof(float)=4字节
- sizeof(char)=1字节
void main() {
int i = 5411;
int *ip = &i;
char *c = &i;
printf("%d",*ip);
printf("%c",*c);
}
第一个printf()应该是5411。谈到第二个printf(),i的基址包含10101001(对于char类型指针,高阶8位=1字节)。
因此*c应该给我169,当转换为%c时,它是一个无效字符
但是编译器给了我“#”或其他一些有效的输出。为什么会这样?有什么意见吗
编辑(摘自作者对其中一个答案的评论):
那只是一个假箱子,因为我离开了真正的机器。
实际情况是i=5411
ASCII仅定义最多127个字符。除此之外,您真正想做的是打印与
*c
中的值相对应的数字,这也可以使用%d
printf("%d",*c);
…应显示您期望的数字。由于您已将c分配给&i,因此*c的地址是i的地址。然后它将取最高或最低(取决于尾端)并打印该字符 您似乎很难理解整数是如何存储在内存中的。以5411为例
5411 = 1010100100011
但是,由于int
是32位的,因此该数字13个二进制数字必须为32位
5411 = 00000000 00000000 00010101 00100011
在little endian机器(x86,默认情况下为ARM)上,最低有效字节存储在前端,因此在内存中:
00100011 00010101 00000000 00000000
^
c c + 1 c + 2 c + 3
ip
因此,
*c
应该返回00100011,即35(“#”
)。为了了解整数的编码,您应该做一些实验
printf("0x%X, %X|%X|%X|%X\n",
i,
i & 0xFF,
(i >> 8) & 0xFF
(i >> 16) & 0xFF
(i >> 24) & 0xFF
);
然后对
c[0]
、c[1]
等和其他格式字符串执行相同的操作,如%c
首先,您的程序格式不正确。C和C++都不允许用<代码> int *<代码>值初始化<代码> char */COD>指针。在初始化c
指针时需要显式强制转换
其次,原始整数i
的哪个字节(高阶或低阶)位于其“基址”是实现定义的。几乎没有endian体系结构,其中较低的顺序可以通过*c
看到(在8位char
机器上具有值130
,而不是114
)。还有big-endian体系结构,其中的高阶但是可以通过*c
看到(在8位char
机器上是0
)。因此,您应该期望使用%c
格式说明符打印代码为130
的字符或代码为0
的字符
第三,在一个典型的实现中,通常没有“无效字符代码”这样的东西。对于任何代码,通常都会以这种或那种方式打印某些内容。我不明白您是如何设法从代码中获得输出的。这是您正在运行的真实代码吗?在任何情况下,如果您尝试“打印”一个“字符”,它将显示为字符,而不是相应的整数代码。我猜可能与使用的字符编码有关。是的,我也同意这一点。但从最后一个printf()获取“#”值肯定有原因。这不是一个垃圾值。它不应该是130而不是144吗?@Gaurav Kalla:事实上,不能保证你会得到114。你指望endienness()得到144,但并不是所有的系统都是小endian。那只是一个虚构的例子,因为我远离了实际的机器。实际情况为i=5411.%c给出“#”,而%d给出35(而不是169)@Guarav:ASCII仍然只定义最多127个字符,而您真正想要的似乎是打印数字,所以打印数字,而不是字符。@Gaurav——为什么您期望169个字符?在小endian机器上,应该是35。在big-endian机器上,它应该是0.-1表示“扩展ASCII”,而不是指定字符编码。没有“扩展ASCII”这样的东西。i=5411的大小写是将“#”打印为字符。35(10101001)的ASCII码,既不是高8位也不是低8位。@Gaurav--35在二进制中是00100011。*c不会被截断,因为字符指针足够大,可以容纳内存位置的整个值。@Gaurav Kalla:为什么你在原来的帖子中说它是
1154
,而在评论中说它是5411
1154和5411是两个不同的数字,如果你注意到的话。我很抱歉:那只是一个假象,因为我不在实际的机器上。嘿,非常感谢!!这正是我要找的:-)5411从哪里来?OP的代码使用1154
对i
进行了清晰的初始化@AndreyT:请参阅OP对其他答案的评论。有问题编辑权限的人应该编辑问题。@PigBen:好的,我这样做了。很抱歉造成了一点混乱嗨,安德烈。1->代码正在编译。那么,我是否应该关注明确的演员阵容。。。2->是的,我不知道这一点,肯尼特回答说。。。3->我提到过,它是一个假人code@Gaurav卡拉:编译成什么?您为问题[C]和[C++]添加了标签。此代码不会被任何自重的C++编译器编译为C++。带有过度宽松错误检查的C编译器可能允许这样做(带有警告),但即使是作为C,代码仍然是非法的,因此如果您关心编写有效的C代码,则需要强制转换。