首页 文章

了解'&'运算符

提问于
浏览
5

根据我对'&'运算符的了解,它返回内存中操作数的基址 .

让我们想象下面的场景(在我的机器上):

  • 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(高阶8位= 1字节用于char类型指针) . 因此* c应该给我169,转换为%c时是无效字符 .

但是编译器给了我'#'或其他一些有效的输出 . 为什么会这样?有什么输入?

EDIT (取自作者对其中一个答案的评论):

那只是一个虚拟案例,因为我离开了实际的机器 . 实际情况是i = 5411

5 回答

  • 3

    您似乎无法理解整数如何存储在内存中 . 以5411为例 .

    5411 = 1010100100011
    

    然而,这个13位二进制数字,因为 int 是32位,它必须填充到32位

    5411 = 00000000 00000000 00010101 00100011
    

    在一个小端机器上(默认情况下为x86,ARM),最低有效字节存储在前面,因此在内存中:

    00100011   00010101    00000000    00000000
    ^
    c          c + 1       c + 2       c + 3
    ip
    

    因此, *c 应返回00100011,即35( '#' ) .

  • 5

    ASCII只定义了最多127个字符 . 除此之外,你真正想要做的是打印与 *c 中的值对应的数字,这也是使用 %d 完成的...

    printf("%d",*c);
    

    ...应该显示您期望的数字 .

  • 24

    首先,你的程序是不正确的 . C和C都不允许使用 int * 值初始化 char * 指针 . 在初始化 c 指针时需要显式转换 .

    其次,原始整数 i 的哪个字节 - 更高阶或更低阶 - 位于其"base address"是实现定义的 . 有小端架构,其中低阶但通过 *c (在8位 char 机器上具有值 130 ,而不是 114 )可以看到 . 并且有大端架构,其中高阶但通过 *c (在8位 char 机器上是 0 )可以看到 . 因此,您应该期望使用代码 130 的字符或具有代码 0 的字符使用 %c 格式说明符进行打印 .

    第三,在一个典型的实现中,'s normally no such thing as 693107 . For any code something will usually be printed in one way or the other. I don't看到你如何设法获得 # 作为代码的输出 . 这是你运行的真实代码吗?

  • 1
    • c的地址是i的地址,因为您已将c分配给&i . 然后它将取最高或最低(取决于endian)并打印该字符 .
  • 1

    只是为了了解整数编码的一些内容,你应该尝试一下并做

    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 执行相同的操作 .

相关问题