繁体   English   中英

C中的指针,指向字符指针的整数指针

[英]Pointers in C, integer pointer to character pointer

当我运行此代码时:

int arr[3] = {2,3,4};
char *p;
p = (char*)arr;
printf("%d", *p);
p = p+1;
printf("%d", *p);

输出为2和0.第二个结果有点令人困惑。 有人可以解释为什么会这样吗?

让我们打破这个:

int arr[3] = {2,3,4};

创建一个包含3个整数的数组。 假设您的系统是32位小端,这就是它在内存中的外观:

02 00 00 00 03 00 00 00 04 00 00 00

char *p; p = (char*)arr;

p现在指向arr但是指向char*的指针。 换句话说, p指向02

printf("%d", *p);

您将作为int打印由p引用的位置。 因此,当您取消引用 p (通过写*p )时,您正在访问由p引用的char (因为pchar*类型)。 这是02

p = p+1;

p现在指向02之后的00 ,因为pchar* 因此,当您添加1时,它将在内存中移动1 * sizeof(char) = 1 * 1 = 1个字节。

printf("%d", *p);

您将作为int打印由p引用的位置。 因此,当您取消引用 p (通过写*p )时,您正在访问由p引用的char (因为pchar*类型)。 这是00

如果要打印3而不是0 ,则必须将指针类型更改为int*而不是char* ,使指针在内存中移动1 * sizeof(int) = 1 * 4 = 4个字节。

获得的结果取决于实现中int的大小及其endianness。

假设32位整数,8位字符和一个litte-endian环境(比如x86), arr在内存中会是这样的:

<  arr[0]  > <  arr[1]  > <  arr[2] >
02 00 00 00  03 00 00 00  04 00 00 00
^  ^         ^
p  p+1 ...   p+4

如果您使用char指针指向该内存的开头,并打印出第一个元素,则应输出2 如果递增该指针,则接下来将输出0。 你需要将它增加几倍才能“看到”3。

请注意,在具有相同类型大小的大端环境中,您的程序将输出两个零,因为布局将是:

<  arr[0]  > <  arr[1]  > <  arr[2] >
00 00 00 02  00 00 00 03  00 00 00 04
^  ^         ^
p  p+1 ...   p+4

这是因为称为字节序的东西。

当你创建一个类似int arr[3] = {2, 3, 4};的数组时int arr[3] = {2, 3, 4}; 它在内存中创建如下

Big endian:
    0   1   2     3      4   5   6      7     8   9  10     11 
  +---+---+---+--------+---+---+---+--------+---+---+---+--------+
  |   |   |   | ..0010 |   |   |   | ..0011 |   |   |   | ..0100 |
  +---+---+---+--------+---+---+---+--------+---+---+---+--------+

  <--       2       --><--       3        --><--        4      -->

Little endian:
       0     1   2    3    4   5   6      7     8       9  10   11 
  +--------+---+---+---+---------+---+---+---+--------+---+---+---+
  | ..0010 |   |   |   |  ..0011 |   |   |   | ..0100 |   |   |   |
  +--------+---+---+---+---------+---+---+---+--------+---+---+---+

  <--       2       --><--       3        --><--        4      -->

要了解更多信息,您需要按如下方式修改程序:

int main(void)
{

    int arr[3] = {2, 3, 4};
    char *p = (char*) arr;  
    int i;
    int size = (int)sizeof(arr);

    for (i=0; i<size ; i++) {
        printf("%d", *p);
        p++;
    }

    return 0;
}

并且,要检查硬件的字节顺序,可以使用以下功能。

void endian(void)
{
        int i = 1;

        if (*(char *) &i == 1)
                printf("Little endian \n");
        else
                printf("Big endian \n");

        return;
}

这是一个粘贴,可以让你更好地理解这个问题: http//codepad.org/ClrrwjKY

如您所见,连续整数的值以三个零分隔。 这是因为整数长度为4个字节,而char只有1个字节长。 因此,当int数组转换为char时,您将逐字节(或char by char)迭代它,而不是四个字节(int by int)。

这里'p'是一个字符指针.. p + 1将p的当前值递增1.由于数组是整数,为了逐个访问数组的每个值,你必须增加字符数组由2.如果整数数组的地址是1000,

  arr[0] is at 1000
  arr[1] is at 1002
  arr[2] is at 1004

而arr的值是arr [0]的地址; 所以最初

 p=arr=1000

当p递增时,p为1001而arr [1]为1002

..因此,为了访问所有值,您必须每次增加p值两次..

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM