开发者

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

开发者 https://www.devze.com 2022-12-22 17:20 出处:网络
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
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


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.

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

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 z it 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".


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 your example,

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.

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 y would be printed, then the address of the next array in the next iteration. For example, on my machine:

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.


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.


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?

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


Who knows - this code exhibits undefined behavior:

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


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");         
      } 
}


#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

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.


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.

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 x is 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.

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 x is a pointer to an array having 6 integers. So (*x)[i] which is equivalent to *((*x)+i) will print ith index value of y.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号