开发者

C difference between *[] and **

This might be a bit of a basic question, but what is the difference between writing char * [] and char **? For example, in main,I can have a char * argv[]. Alternatively I can use char ** argv. I assume there's got to be 开发者_StackOverflow社区some kind of difference between the two notations.


Under the circumstances, there's no difference at all. If you try to use an array type as a function parameter, the compiler will "adjust" that to a pointer type instead (i.e., T a[x] as a function parameter means exactly the same thing as: T *a).

Under the right circumstances (i.e., not as a function parameter), there can be a difference between using array and pointer notation though. One common one is in an extern declaration. For example, let's assume we have one file that contains something like:

char a[20];

and we want to make that visible in another file. This will work:

extern char a[];

but this will not:

extern char *a;

If we make it an array of pointers instead:

char *a[20];

...the same remains true -- declaring an extern array works fine, but declaring an extern pointer does not:

extern char *a[]; // works

extern char **a;   // doesn't work


Depends on context.

As a function parameter, they mean the same thing (to the compiler), but writing it char *argv[] might help make it obvious to programmers that the char** being passed points to the first element of an array of char*.

As a variable declaration, they mean different things. One is a pointer to a pointer, the other is an array of pointers, and the array is of unspecified size. So you can do:

char * foo[] = {0, 0, 0};

And get an array of 3 null pointers. Three char*s is a completely different thing from a pointer to a char*.


You can use cdecl.org to convert them to English:

  • char *argv[] = declare argv as array of pointer to char

  • char **argv = declare argv as pointer to pointer to char


I think this is a little bit more than syntactic sugar, it also offers a way to express semantic information about the (voluntary) contract implied by each type of declaration.

With char*[] you are saying that this is intended to be used as an array.

With char**, you are saying that you CAN use this as an array but that's not the way it's intended to be used.


As it was mentioned in the other answers, char*[] declares an array of pointers to char, char** declares a pointer to a pointer to char (which can be used as array).

One difference is that the array is constant, whereas the pointer is not.

Example:

int main()
{
    char** ppc = NULL;
    char* apc[] = {NULL};
    ppc++;
    apc++; /* this won't compile*/
    return 0;
}


This really depends on the context of where the declarations occur.

Outside of a function parameter definition, the declaration

T a[];

declares a as an unknown-sized array of T; the array type is incomplete, so unless a is defined elsewhere (either in this translation unit or another translation unit that gets linked) then no storage is set aside for it (and you will probably get an "undefined reference" error if you attempt to link, although I think gcc's default behavior is to define the array with 1 element) . It cannot be used as an operand to the sizeof operator. It can be used as an operand of the & operator.

For example:

/** 
 * module1.c
 */
extern char *a[]; /* non-defining declaration of a */

void foo()
{
  size_t i = 0;
  for (i = 0; a[i] != NULL; i++)
    printf("a[%lu] = %s\n", (unsigned long) i, a[i++]);
}

module1.c uses a non-defining declaration of a to introduce the name so that it can be used in the function foo, but since no size is specified, no storage is set aside for it in this translation unit. Most importantly, the expression a is not a pointer type; it is an incomplete array type. It will be converted to a pointer type in the call to printf by the usual rules.

/**
 * module2.c
 */
char *a[] = {"foo", "bar", "bletch", "blurga", NULL}; /* defining declaration of a */

int main(void)
{
  void foo();

  foo();
  return 0;
}

module2.c contains a defining declaration for a (the size of the array is computed from the number of elements in the initializer), which causes storage to be allocated for the array.

Style note: please don't ever write code like this.

In the context of a function parameter declaration, T a[] is synonymous with T *a; in both cases, a is a pointer type. This is only true in the context of a function parameter declaration.


As Paul said in the comment above, it's syntactic sugar. Both char* and char[] are the same data type. In memory, they will both contain the address of a char.

The array/index notation is equivalent to the pointer notation, both in declaration and in access, but sometimes much more intuitive. If you are creating an array of char pointers, you may want to write it one way or another to clarify your intention.

Edit: didn't consider the case Jerry mentioned in the other answer. Take a look at that.


    char *ptr[2]={"good","bad"}; //Array of ptr to char
    char **str;  //Refer ptr to ptr to char
    int i;
    //str = &ptr[0];  //work
    str = ptr;

    for(i=0;i<2;i++)  printf("%s %s\n",ptr[i],str[i]);

Its o/p same. Using that we can easily understand.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜