C语言 “指向整数的指针”和“指向整数数组的指针”之间的区别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2397792/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 04:46:02  来源:igfitidea点击:

Difference between "pointer to int" and "pointer to array of ints"

c

提问by Sandip

int main()
{
    int (*x)[5];                 //pointer to an array of integers
    int y[6] = {1,2,3,4,5,6};    //array of integers
    int *z;                      //pointer to integer

    z = y;
    for(int i=0;i<6;i++)
        printf("%d ",z[i]);

    x = y;
    for(int i=0;i<6;i++)
        printf("%d ",(*x)[i]);

    return 0;
}

Both the above printfs print numbers 1 through 6.
If both "pointer to array of integers" and "pointer to integer" can do the same thing, do they have the same internal representation?
EDIT: This code does give warnings when compiled as pointed out by the answers below, however it does print the values correctly both the time on my x86_64 machine using gcc

上面的 printfs 都打印数字 1 到 6。
如果“指向整数数组的指针”和“指向整数的指针”都可以做同样的事情,它们是否具有相同的内部表示?
编辑:此代码在编译时确实会发出警告,如下面的答案所指出的那样,但是它确实在我的 x86_64 机器上使用 gcc 正确打印了值

采纳答案by AnT

Firstly, your code will not compile. The array has type int[6](6 elements), while the pointer has type int (*)[5]. You can't make this pointer to point to that array because the types are different.

首先,您的代码将无法编译。数组具有类型int[6](6 个元素),而指针具有类型int (*)[5]。你不能让这个指针指向那个数组,因为类型不同。

Secondly, when you initialize (assign to) such a pointer, you have to use the &on the array: x = &y, not just a plain x = yas in your code.

其次,当您初始化(分配给)这样的指针时,您必须&在数组上使用: x = &y,而不仅仅是x = y代码中的普通。

I assume that you simply typed the code up, instead of copy-pasting the real code.

我假设您只是输入代码,而不是复制粘贴真正的代码。

Thirdly, about the internal representation. Generally, in practice, you should expect all data pointers to use the same internal representation. Moreover, after the above assignments (if written correctly), the pointers will have the same numerical value. The difference between int (*)[5]and int *exists only on the conceptual level, i.e. at the level of the language: the types are different. It has some consequences. For example, if you increment your zit will jump to the next member of the array, but if you increment y, it will jump over the whole array etc. So, these pointers do not really "do the same thing".

第三,关于内部代表。通常,在实践中,您应该期望所有数据指针都使用相同的内部表示。此外,在上述赋值之后(如果写得正确),指针将具有相同的数值。int (*)[5]和之间的区别int *只存在于概念层面,即语言层面:类型不同。它有一些后果。例如,如果你增加你的z它会跳到数组的下一个成员,但如果你增加y,它会跳过整个数组等等。所以,这些指针并没有真正“做同样的事情”。

回答by AraK

The short answer: There is a difference, but your example is flawed.

简短的回答:有区别,但你的例子有缺陷。

The long answer:

长答案:

The difference is that int*points to an int type, but int (*x)[6]points to an array of 6 ints. Actually in yourexample,

区别在于int*指向一个int类型,但int (*x)[6]指向一个6个int的数组。实际上在你的例子中,

x = y;

is undefined** behavior, you know these are of two different types, but in C you do what you want. I'll just use a pointer to an array of six ints.

是 undefined** 行为,你知道它们有两种不同的类型,但在 C 中你可以做你想做的。我将只使用一个指向六个整数数组的指针。

Take this modified example:

以这个修改过的例子为例:

int (*x)[6];                 //pointer to an array of integers
int y[6] = {1,2,3,4,5,6};    //array of integers
int *z;                      //pointer to integer
int i;

z = y;
for(i = 0;i<6;i++)
    printf("%d ",z[i]);

x = y; // should be x = &y but leave it for now!

for(i = 0;i<6;i++)
    printf("%d ",x[i]); // note: x[i] not (*x)[i]

First,

第一的,

1 2 3 4 5 6

Would be printed. Then, we get to x[0]. x[0] is nothing but an array of 6 ints. An array in C is the address of the first element. So, the address of ywould be printed, then the address of the nextarray in the next iteration. For example, on my machine:

会被打印出来。然后,我们到了x[0]。x[0] 只不过是一个 6 个整数的数组。C 中的数组是第一个元素的地址。因此,y将打印 的地址,然后next是下一次迭代中数组的地址。例如,在我的机器上:

1 2 3 4 5 6 109247792 109247816 109247840 109247864 109247888 109247912

As you can see, the difference between consecutive addresses is nothing but:

如您所见,连续地址之间的区别无外乎:

sizeof(int[6]) // 24 on my machine!

In summary, these are two different pointer types.

总之,这是两种不同的指针类型。

** I think it is undefined behavior, please feel free to correct my post if it is wrong.

** 我认为这是未定义的行为,如果有误,请随时更正我的帖子。

回答by jamesdlin

To answer your question from the title, from the comp.lang.c FAQ: Since array references decay into pointers, if arr is an array, what's the difference between arr and &arr?

从标题中回答您的问题,来自 comp.lang.c 常见问题解答:由于数组引用衰减为指针,如果 arr 是一个数组,那么 arr 和 &arr 之间有什么区别?

However, the code you've posted has other issues (you're assigning y, not &yto x, and yis a 6-element array, but *xis a 5-element array; both of these should generate compilation warnings).

但是,你已经发布的代码有其他问题(你分配y,不&yx,并y有6个元素的数组,但*x有5个元素的数组,这两个应该产生编译警告)。

回答by justanotherguy

Hope this code helps:

希望这段代码有帮助:

int main() {

    int arr[5] = {4,5,6,7,8};        
    int (*pa)[5] = &arr;
    int *pi = arr;

    for(int i = 0; i< 5; i++) {
        printf("\n%d %d", arr[i], (*pa)[i]);    
    }

    printf("\n0x%x -- 0x%x", pi, pa);
    pi++;
    pa++;
    printf("\n0x%x -- 0x%x", pi, pa);
}

prints the following:

打印以下内容:

4 4
5 5
6 6
7 7
8 8
0x5fb0be70 -- 0x5fb0be70
0x5fb0be74 -- 0x5fb0be84 

UPDATE:You can notice that pointer to integer incremented by 4 bytes (size of 32 bit integer) whereas pointer to array of integer incremented by 20 bytes (size of int arr[5] i.e. size of 5 int of 32 bit each). This demonstrates the difference.

更新:您可以注意到指向整数的指针增加了 4 个字节(32 位整数的大小),而指向整数数组的指针增加了 20 个字节(int arr[5] 的大小,即每个 32 位的 5 个 int 的大小)。这说明了差异。

回答by justanotherguy

Who knows - this code exhibits undefined behavior:

谁知道 - 此代码表现出未定义的行为:

printf("%d ",(*x)[i]);

回答by Shailesh Mangrulkar

Hope this code helps.

希望这段代码有帮助。



#include <stdio.h>
#include <stdlib.h>
#define MAXCOL 4
#define MAXROW 3

int main()
{      
      int i,j,k=1;
      int (*q)[MAXCOL];      //pointer to an array of integers

      /* As malloc is type casted to "int(*)[MAXCOL]" and every 
         element (as in *q) is 16 bytes long (I assume 4 bytes int), 
         in all 3*16=48 bytes will be allocated */

      q=(int(*)[MAXCOL])malloc(MAXROW*sizeof(*q)); 

      for(i=0; i<MAXROW; i++)
        for(j=0;j<MAXCOL;j++)
          q[i][j]=k++;


      for(i=0;i<MAXROW;i++){
        for(j=0;j<MAXCOL;j++)
          printf(" %2d ", q[i][j]);
        printf("\n");         
      } 
}

回答by Himanshu

#include<stdio.h>

int main(void)
{
    int (*x)[6];                 //pointer to an array of integers
    int y[6] = {11,22,33,44,55,66};    //array of integers
    int *z;                      //pointer to integer
    int i;

    z = y;
    for(i = 0;i<6;i++)
        printf("%d ",z[i]);
    printf("\n");

    x = &y;

    for(int j = 0;j<6;j++)
        printf("%d ",*(x[0]+j));

    return 0;
}

//OUTPUT::

//输出::

11 22 33 44 55 66

11 22 33 44 55 66

11 22 33 44 55 66

11 22 33 44 55 66

Pointer to an array are best suitable for multi-dimensional array. but in above example we used single dimension array. so, in the second for loop we should use (x[0]+j) with * to print the value. Here, x[0] means 0th array. And when we try to print value using printf("%d ",x[i]); you will get 1st value is 11 and then some garbage value due to trying to access 1st row of array and so on.

指向数组的指针最适合多维数组。但在上面的例子中,我们使用了一维数组。因此,在第二个 for 循环中,我们应该使用 (x[0]+j) 和 * 来打印值。这里,x[0] 表示第 0 个数组。当我们尝试使用 printf("%d ",x[i]); 打印值时;你会得到第一个值是 11,然后是一些垃圾值,因为试图访问数组的第一行等等。

回答by anand

One should understand the internal representation of (*x)[i]. Internally, it is represented as *((*x)+i), which is nothing but the ith element of the array to which x is pointing. This is also a way to have a pointer pointing to 2d array. The number of rows is irrelevant in a 2d array.

人们应该了解 的内部表示(*x)[i]。在内部,它表示为 *((*x)+i),它只是 x 指向的数组的第 i 个元素。这也是一种让指针指向二维数组的方法。二维数组中的行数无关紧要。

For example:

例如:

int arr[][2]={{1,2},{3,4}};
int (*x)(2);
x=arr; /* Now x is a pointer to the 2d array arr.*/

Here xis pointing to a 2d array having 2 integer values in all columns, and array elements are stored contiguously. So (*x)[0]will print arr[0][0](which is 1), (*x)[1]will print the value of arr[0][1](which is 2) and so on. (*x+1)[0]will print the value of arr[1][0](3 in this case) (*x+1)[1]will print the value of arr[1][1](4 in this case) and so on.

这里x指向一个在所有列中具有 2 个整数值的 2d 数组,并且数组元素连续存储。因此(*x)[0]将打印arr[0][0](即 1),(*x)[1]将打印arr[0][1](即 2)的值,依此类推。(*x+1)[0]将打印arr[1][0](本例中为3)(*x+1)[1]的值将打印arr[1][1](本例中为4 )的值,依此类推。

Now, a 1d array could be treated as nothing but a 2d array having only one row with as many columns.

现在,一维数组可以被视为只有一行和多列的二维数组。

int y[6] = {1,2,3,4,5,6};
int (*x)[6];
x =y;

This means xis a pointer to an array having 6 integers. So (*x)[i]which is equivalent to *((*x)+i)will print ith index value of y.

这意味着x是一个指向具有 6 个整数的数组的指针。所以(*x)[i]这相当于*((*x)+i)将打印 的第 i 个索引值y