Thread: Array as an argument to a function

  1. #1
    Registered User
    Join Date
    Dec 2010
    Posts
    113

    Array as an argument to a function

    Hello All,

    I have a question about function definitions and calls which accept arrays as their argument.

    As far as I see the types of formal parameters and arguments match. For example if I define a function like this:

    Code:
    int function(int x)
    I should call this function with an argument of int type (or even if I don't the compiler may convert it to int.) However when it comes to arrays I am a bit confused. If I define a function like this:

    Code:
    int function(int x[][2])
    I can call this function with the name of the array. Let's say I want to use the array "array[3][2]" for the argument. I need to call the function like this:

    Code:
    function(array)
    If I have learnt what has been told here well 'array' decays to a pointer, its value is the address of a[0][0] and it refers to the addresses of a[0][0], a[0][1] and a[0][2]

    Is this an exception to the usual way of "both the argument and the formal parameter must be the same type" or by chance they are the same also in my example but I am missing something?

    The question may sound a silly one but I really want to make sure I have the right information. Also I have one more silly (even sillier) question but I will ask it later, after I learn this one.

  2. #2
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    If I have learnt what has been told here well 'array' decays to a pointer, its value is the address of a[0][0] and it refers to the addresses of a[0][0], a[0][1] and a[0][2]
    No the name of the array decays to the address of the first element not some other random element.

    Is this an exception to the usual way of "both the argument and the formal parameter must be the same type"
    No it is not an exception, the function prototype, function implementation, and function call must agree as to the type. Let's simplify things and just talk about one dimensional array for now. Do you realize that when talking about function parameters that the following are all equivalent?

    Code:
    void someFunction(int *array);
    void someFunction(int array[]);
    void someFunction(int array[3]);   // The number in the brackets is actually ignored by the compiler (remember this is a single dimensional array).
    Do you realize that the following are also equivalent?

    Code:
    int main()
    {
        ...
    
       someFunction(array);
       someFunction(&array[0]);
    ...
    Multidimensional arrays just add the brackets with the sizes of all but the last dimension (array[][2], *array[2], or array[3][2]). All dimensions except the first must have the corresponding sizes.

  3. #3
    Registered User
    Join Date
    Dec 2010
    Posts
    113
    Quote Originally Posted by jimblumberg View Post
    No the name of the array decays to the address of the first element not some other random element.
    I was thinking I was saying the same thing [I used the name 'a' instead of 'array' by mistake.] The first element of the array is array[0], the value of its address is the same as the adress of array[0][0] and it refers to the array composed of array[0][0], array[0][1] and array [0][2]. I may have worded it wrongly in the previous post. Could you please educate me if that one is wrong too?

    Quote Originally Posted by jimblumberg View Post
    Do you realize that the following are also equivalent?

    Code:
    int main()
    {
        ...
    
       someFunction(array);
       someFunction(&array[0]);
    ...
    Yes I understand that, the first one decays to the pointer to the first element and the second one is already the address of the first element. I would say both have the type int*.

    Quote Originally Posted by jimblumberg View Post
    Do you realize that when talking about function parameters that the following are all equivalent?

    Code:
    void someFunction(int *array);
    void someFunction(int array[]);
    void someFunction(int array[3]);   // The number in the brackets is actually ignored by the compiler (remember this is a single dimensional array).
    This is where I am confused. I can clearly see the first one is a pointer to an int. But the others look like arrays to me. It is not clear to me they are pointers to int too. Could you please explain this a bit?

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    It is true that they use array notation, but in the context of a parameter they still are part of the declaration of a pointer, not an array.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    Yes I understand that, the first one decays to the pointer to the first element and the second one is already the address of the first element. I would say both have the type int*.
    Yes that is correct. Do you understand that you can pass partial arrays by using the address of some other element of the array, ie by calling the function like: someFunction(&array[1]); to pass the address of the second element of the array?

    This is where I am confused. I can clearly see the first one is a pointer to an int. But the others look like arrays to me. It is not clear to me they are pointers to int too. Could you please explain this a bit?
    All of those examples are using pointers, that is why they are equivalent. When you pass an array to a function you are passing a pointer to array.

    But the others look like arrays to me.
    That is usually the main reason you would use those methods, because they reinforce that you are working with an array not just a pointer to a single int. Realize that the compiler will let you pass the address of a single int or an array of int into that function no matter what method you use. And yes it can get confusing, multidimensional arrays can get even more confusing.

  6. #6
    Registered User
    Join Date
    Dec 2010
    Posts
    113
    @jimblumberg and @laserlight

    Thanks a lot for your answers. They did not only clarify things for me but also gave me good keywords to search on Google more. My search took me to C99 draft standards and it says "A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to type’’

    Therefore I understand a formal parameter like "int array[]" is adjusted to something like "int *pointer. Furthermore "int array[][3]" must be adjusted to "int *p[3]" as the array is 'an array of arrays of ints' and the type must be "an array of ints". If I my logic is correct I see why all the three in jimblumberg's example are equivalent.

    Quote Originally Posted by jimblumberg View Post
    Yes that is correct. Do you understand that you can pass partial arrays by using the address of some other element of the array, ie by calling the function like: someFunction(&array[1]); to pass the address of the second element of the array?
    It is an interesting thing, I saw a similar one in an example which checks if a sub-string is present in another string yesterday. I just assumed I can do this (passing partial arrays) but your comment confirmed my assumption.

    Thanks a lot again.

  7. #7
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    945
    Quote Originally Posted by GokhanK View Post
    Furthermore "int array[][3]" must be adjusted to "int *p[3]" as the array is 'an array of arrays of ints' and the type must be "an array of ints".
    Just as a nitpick, "int array[][3]" is adjusted to "int (*p)[3]" (the parentheses change the meaning). "int *p[3]" means "p is an array of 3 pointers to int", whereas "int (*p)[3]" means "p is a pointer to an array of 3 ints".

  8. #8
    Registered User
    Join Date
    Dec 2010
    Posts
    113
    Quote Originally Posted by christop View Post
    Just as a nitpick, "int array[][3]" is adjusted to "int (*p)[3]" (the parentheses change the meaning). "int *p[3]" means "p is an array of 3 pointers to int", whereas "int (*p)[3]" means "p is a pointer to an array of 3 ints".
    Thanks for your correction, it seems I will need to spend some time with these to gain familiarisation and get used to write my code properly.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help using a 2D array of strings as a function argument
    By agamemn0n in forum C Programming
    Replies: 4
    Last Post: 11-02-2016, 11:31 AM
  2. Array pointer as function argument?
    By mtn_student in forum C Programming
    Replies: 1
    Last Post: 09-27-2011, 03:25 PM
  3. multidimensional array as a function argument
    By Luciferek in forum C++ Programming
    Replies: 7
    Last Post: 09-30-2008, 11:16 AM
  4. Replies: 1
    Last Post: 10-21-2007, 07:44 AM
  5. function passing argument..array ?
    By jochen in forum C Programming
    Replies: 2
    Last Post: 09-30-2007, 11:53 AM

Tags for this Thread