开发者

Pointers to arrays problem in C

开发者 https://www.devze.com 2023-03-16 14:38 出处:网络
I have this function that takes a pointer of an array (in order to modify it from within the function)

I have this function that takes a pointer of an array (in order to modify it from within the function)

int func_test(char *arr[]){开发者_如何学编程
    return 0;
}

int main(){
  char var[3];
  func_test(&var);

  return 0;
}

When I try to compile this I get :

passing argument 1 of ‘func_test’ from incompatible pointer type

Why is this problem, and how I pass a pointer to that array in this case?


char * arr[] is not a pointer to an array; it is an array of pointers. Declarations in C are read first from the identifier towards the right, then from the identifier towards the left. So:

    char * arr[];
//         ^ arr is...
//            ^ an array of...
//       ^ pointers to...
//  ^ char


A pointer to an array is a type (*varname)[], in your case, a char (*arr)[].


You are passing the address of a pointer. I think you want this:

int func_test(char arr[]){
    arr[0] = 'a';//etc.
    return 0;
}

int main(){
  char var[3];
  func_test(var);

  return 0;
}


char var[3] is an array that holds 3 characters, not 3 pointers to characters - char *arr[] denotes an array that holds pointers to characters.

So you can go like this:

char *var[3];
func_test(var);

Note that the ampersand is not needed because array identifiers automatically decay to pointers of the corresponding type, in this case char **.


That's because the name of an array is already a pointer to it, so use func_test(var).

&var will have type char**


This is an array of pointers

char *arr[]

This is an address of a pointer

&var

So you are passing something different to what the function expects


C's treatment of arrays is a little confusing at first.

Except when it's an operand of either the sizeof or unary & operators, or when it's a string literal being used to initialize another array in a declaration, an expression with type "N-element array of T" will be implicitly converted to type "pointer to T", and its value will be the address of the first element in the array.

Assume the following declaration:

int x[10];

The type of the expression x is "10-element array of int". However, when that expression appears as, say, a parameter to a function:

foo(x);

the type of x is implicitly converted ("decays") to type "pointer to int". Thus, the declaration of foo needs to be

void foo(int *p);

foo receives an int *, not an int [10].

Note that this conversion also occurs for something like

i = x[0];

Again, since x isn't an operand of sizeof or &, its type is converted from "10-element array of int" to "pointer to int". This works because array subscripting is defined in terms of pointer arithmetic; the expression a[n] is equivalent to *(a+n).

So for your code, you'd write

int func_test(char *arr) { return (0); }

int main(void)
{
  char var[3];
  func_test(var); // no & operator
  return 0;
}

Postfix operators like [] have higher precedence than unary operators like *, so a declaration like T *a[N] is interpreted as T *(a[N]), which declares an array of pointer to T. To declare a pointer to an array, you have to use parentheses to explicitly group the * operator with the array name, like T (*a)[N].

Here's a handy table of array declarations, expressions, and types:

Declaration: T a[N];          // a is an N-element array of T

Expression     Type           Decays To
----------     ----           ---------
         a     T [N]          T *
        &a     T (*)[N]       
      a[i]     T
     &a[i]     T *

Declaration: T *a[N];         // a is an N-element array of pointer to T

Expression     Type           Decays To
----------     ----           ---------
         a     T *[N]         T **
        &a     T *(*)[N]     
      a[i]     T *
     *a[i]     T
     &a[i]     T *

Declaration: T (*a)[N]       // a is a pointer to an N-element array of T

Expression     Type           Decays To
----------     ----           ---------
         a     T (*)[N]
        &a     T (**)[N]     
        *a     T [N]          T *
   (*a)[i]     T
0

精彩评论

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

关注公众号