Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I assign an array to pointer directly in C?

Tags:

c

pointers

I have the following program. However, I can't understand why I have to pass the address of the array. When they are both pointing to the same address. Which is the address of the first element of the array of int's.

I get a warning when I try and do this "assignment from incompatible pointer type":

ptr = var;

Complete source code:

void print_values(int (*ptr)[5])
{
    size_t i = 0;
    for(i = 0; i < 5; i++) {
        printf("%d: [ %d ]\n", i, (*ptr)[i]);
    }
}

int main(void)
{
    /* declare a pointer to an array integers */
    int (*ptr)[5] = NULL;
    /* array of integers */
    int var[] = {1, 2, 3, 4, 5};
    /* assign the address of where the array is pointing to (first element) */
    ptr = &var;
    /* Both are pointing to the exact same address */
    printf("var  [ %p ]\n",(void*)var);
    printf("&var [ %p ]\n", (void*)&var);

    print_values(ptr);
    return 0;
}

I compile the code with gcc 4.4.4 c89 -Wall -Wextra -O0

like image 367
ant2009 Avatar asked Aug 17 '10 16:08

ant2009


People also ask

Can arrays be directly assigned to pointers in C?

You cannot assign a new pointer value to an array name. The array name will always point to the first element of the array.

How do you assign the address of an array to a pointer?

To assign a pointer to the array we can use the following declaration... int a[10]; int *pa = &a[0]; Basically this assigns the memory address of a[0] the first element in array a to pointer of type int .

Why can't we increment an array like a pointer?

It's because array is treated as a constant pointer in the function it is declared. There is a reason for it. Array variable is supposed to point to the first element of the array or first memory instance of the block of the contiguous memory locations in which it is stored.

Can you declare an array as a pointer?

An array is a pointer, and you can store that pointer into any pointer variable of the correct type. For example, int A[10]; int* p = A; p[0] = 0; makes variable p point to the first member of array A.


2 Answers

It's purely a type issue.

In most expression contexts the name of an array (such as var) decays to a pointer to the initial element of the array, not a pointer to the array. [Note that this doesn't imply that var is a pointer - it very much is not a pointer - it just behaves like a pointer to the first element of the array in most expressions.]

This means that in an expression var normally decays to a pointer to an int, not a pointer to an array of int.

As the operand of the address-of operator (&) is one context where this decay rule doesn't apply (the other one being as operand of the sizeof operator). In this case the type of &var is derived directly from the type of var so the type is pointer to array of 5 int.

Yes, the pointers have the same address value (the address of an arrays first element is the address of the array itself), but they have different types (int* vs int(*)[5]) so aren't compatible in the assignment.

ISO/IEC 9899:1999 6.3.2.1/4:

Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type "array of type" is converted to an expression of type "pointer to type" that points to the initial element of the array object and is not an lvalue. ...

like image 109
CB Bailey Avatar answered Oct 16 '22 11:10

CB Bailey


var itself is a (*int) pointing to the first element in your array. Pointers and arrays in C extremely similar. Change int (*ptr)[5] = NULL; to int* ptr = NULL; and ptr = &var; to ptr = var;

like image 20
Ian Wetherbee Avatar answered Oct 16 '22 11:10

Ian Wetherbee