-1

如果机器是 32 位 little-endianess 并且 sizeof(int) 是 4 字节。

给定以下程序:

 line1:  #include<stdio.h>
 line2:  {
 line3:      int arr[3]={2,3,4};
 line4:      char *p;
 line5:      p=(char*)arr;
 line6:      printf("%d",*p);
 line7:      p=p+1;
 line8:      printf("%d\n",*p);
 line9:      return 0;
         }

什么是预期的输出?

A: 2 3

B: 2 0

C: 1 0

D: 垃圾值

困扰我将整数指针转换为字符指针的一件事。

  1. 选角有多重要?

  2. 编译器在第 5 行做了什么?( p = (char *) arr;)

  3. 第 7 行发生了什么?( p = p + 1)

  4. 如果输出是20那么如何0打印出来?

4

3 回答 3

1
  1. (D),或特定于编译器的,因为sizeof(int)(以及字节序)是平台相关的。

选角有多重要?

作为一个整体,铸造是 C 语言的一个组成部分(双关语无意)。

编译器在第 5 行会做什么?

它获取第一个元素的地址arr并将其放入p.

在第 5 行之后,第 7 行发生了什么?

它递增指针,使其指向char该内存地址的下一个。

如果输出是 2 0 那么编译器是如何打印 0 的?

这是 endanness 和sizeof(int). 没有您机器的规格,我无法解释。

但是,假设小端和sizeof(int) == 4,我们可以看到以下内容:

// lets mark these memory regions: |A|B|C|D|
int i = 2; // represented as      0x02000000
char *ptr = (char *) &i; // now ptr points to 0x02 (A) 
printf("%d\n", *ptr); // prints '2', because ptr points to 0x02 (A) 
ptr++; // increment ptr, ptr now points to 0x00 (B)
printf("%d\n", *ptr); // prints '0', because ptr points to 0x00 (B)
于 2012-07-25T15:26:24.510 回答
1

(E) 以上都不是

但是,假设 (a) 您使用的是 little-endian 机器(例如 x86),并且 (b)sizeof(int) >= 2应该打印“20”(两者之间不打印空格)。

a)强制转换是“必要的”一次读取一个字节的数组,而不是一系列ints

b)这只是将第一个地址强制int转换为指向的指针char

c)将存储的地址递增psizeof(char)即1)

d) 机器表示的第二个字节int由第 8 行打印

于 2012-07-25T15:28:58.047 回答
0

1. 铸造的重要性:- char *p; 这一行声明了一个指向字符的指针。这意味着它的属性是它一次只能取消引用一个字节,并且位移也是一个字节。

p=(char*)arr; 2. 类型转换为 char * 只是为了避免编译器发出警告。如果你不那么也同样的行为。

  1. 作为指向一个字符的指针,因为我已经在 p=p+1 上面写了指向下一个字节

  2. printf("%d\n",*p); %d 将值格式化为十进制整数,因此此处显示的十进制格式 *p 使用,并且根据其属性,它只能取消引用一个字节。所以现在内存组织进入画面。那就是你的机器首先遵循小端/ LSB或大端/ MSB

    根据您的 ans,您的机器遵循 little endian。所以第一次您的 ans 为 0。然后下一个字节必须为零,因此输出为 0。二进制:2 表示为 00-00-00-02(按字节表示)但在内存中它像这样存储 02-00-00-00 四个字节

    在第一个内存字节 02 和第二个内存字节 00 中

于 2012-07-26T20:07:02.690 回答