How many ways are there to pass char array to function in C?

折月煮酒 提交于 2019-12-01 07:30:11

问题


  • foo(char *s)
  • foo(char *s[ ])
  • foo(char s[ ])

What is the difference in all these ?

Is there any way in which I will be able to modify the elements of the array which is passed as argument, just as we pass int or float using & and value of actual arguments gets modified?


回答1:


It is not possible in C to pass an array by value. Each working solution that you listed (which unfortunately excludes #2) will not only let you, but force you to modify the original array.

Because of argument decay, foo(char* s) and foo(char s[]) are exactly equivalent to one another. In both cases, you pass the array with its name:

char array[4];
foo(array); // regardless of whether foo accepts a char* or a char[]

The array, in both cases, is converted into a pointer to its first element.

The pointer-to-array solution is less common. It needs to be prototyped this way (notice the parentheses around *s):

void foo(char (*s)[]);

Without the parentheses, you're asking for an array of char pointers.

In this case, to invoke the function, you need to pass the address of the array:

foo(&array);

You also need to dereference the pointer from foo each time you want to access an array element:

void foo(char (*s)[])
{
    char c = (*s)[3];
}

Just like that, it's not especially convenient. However, it is the only form that allows you to specify an array length, which you may find useful. It's one of my personal favourites.

void foo(char (*s)[4]);

The compiler will then warn you if the array you try to pass does not have exactly 4 characters. Additionally, sizeof still works as expected. (The obvious downside is that the array must have the exact number of elements.)




回答2:


Scenario: You're calling the function with an array as argument.

In that case,

 foo(char *s)

and

 foo(char s[])

are considered equivalent. They both expect to be called with a char array.

OTOH, foo(char *s[ ]), is different, as it takes the address of a char * array.




回答3:


  • foo(char *s) is pretty straight-forward, it is just a pointer, which could potentially be a pointer to the first element of an array.

  • foo(char s[]) is a declaration of an array of char, but because of a (stupid) rule in the C standard, this gets translated to a pointer to char. Similarly, if you declare any array size, you still get a pointer to char.

    Mentioned rule can be found in C11 6.7.6.3 Function declarators:

    A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to type’’

    It would perhaps have been much better if this strange, confusing "would-be-array" syntax was banned entirely, as it is 100% superfluous and fills no other purpose but to confuse beginners who try to join the "C club". But then C was never a rational language...

    Some will say that the the rationale is that you should never be allowed to pass arrays by value in C, for performance reasons. Well, tough luck, because you still can, despite this rule.

  • You can "hack the C standard" and pass an array by value:

    typedef struct
    {
      char array[10];
    } by_val_t;
    
    foo (by_val_t arr);  // bad practice but possible
    

    Now there's really never a reason why you would want to pass an array by value, this is very bad program design and doesn't make any sense. I merely included this example here to prove that the rule in 6.7.6.3 completely lacks any rationale.

  • You could pass an array pointer as a parameter to a function. This is where things turn advanced, as this is quite obscure and has very limited practical use:

    foo(char(*s)[])
    

    If you specify an array size here, you actually get a bit of added type safety because compilers tend to warn about casts between array pointers of different size.

    But note that array pointers are mainly just there to make the C language more consistent. There's very few reasons why you would ever want to pass an array pointer to a function (here is one somewhat complex example where I apparently found a valid use for it).




回答4:


foo(char *s), foo(char *s[ ]), foo(char s[ ]) , what is the difference in all these ?

In these foo(char *s) and foo(char s[ ]) both will expect char array as argument.

Exception remaining this -foo(char *s[ ]) this will expect a array of pointers to chars as argument.



来源:https://stackoverflow.com/questions/32377418/how-many-ways-are-there-to-pass-char-array-to-function-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!