1

I want to write a function in c which is able to print the array we created. However, there is a problem. When I want to create the loop I need to know the number of elements in the array. So, I used the sizeof function in order to fix that.

I wrote the line size = sizeof(list) / sizeof(list[0]); in order to get the size of the whole array and divide it to size of one element in order to get the number of elements in the array. However, when I build the code I get the following warning:

warning : 'sizeof' on array function parameter 'list' will return the size of 'int *'

#include <stdio.h>

void displayArray(int myarray[]);

int main()
{
    int list1[] = {0, 5, 3, 5, 7, 9, 5};
    displayArray(list1);
    return 0;
}

void displayArray(int list[])
{
    int size;
    size = sizeof(list) / sizeof(list[0]);
    printf("Your array is: ");
    for (int i = 0; i < size; i++)
    {
         printf("%d ", list[i]);
    }
    printf("\n");
    return;
}
mr. hacker
  • 13
  • 3

4 Answers4

3

void displayArray(int list[]) is exactly the same as void displayArray(int *list). This is because an array doesn't have a value itself, and when you try to evaluate just the identifier of the array, what you get instead is a pointer to its first element.

Therefore, passing an array to a function always means passing a pointer. The sizeof operator (it's not a function) doesn't get your array type but a pointer type, and the size of the pointer is useless to you.

A typical approach is to explicitly pass the size of the array as a second parameter to your function, the correct type for this is size_t.

  • I want to wrote function with only array as the parameter. Is this possible? Or I need to pass the size of the array as the second parameter? – mr. hacker Jul 13 '17 at 11:29
  • 1
    Yes, you do. That's exactly what everyone has told you. – underscore_d Jul 13 '17 at 11:30
  • either that or some sentinel value for the end of the array, like, a `char[]` holding a **string** will have a `0` at its end. –  Jul 13 '17 at 11:31
3

There's no such thing as array parameters. They're just hidden pointers.

You should size your array in the caller (where there's a real array) and pass the size to the callee.

(As arrays get passed to callees, their size information gets lots in the array-to-pointer conversion, and so you have to pass it separately)

#include <stdio.h>

void displayArray(int myarray[], int size);

int main()
{
    int list1[] = {0, 5, 3, 5, 7, 9, 5};
    displayArray(list1, sizeof list1 / sizeof list1[0]);
    /*you don't need the parens if the argument is a variable / isn't a type */
    return 0;
}

void displayArray(int list[], int size)
{
    printf("Your array is: ");
    for (int i = 0; i < size; i++)
    {
         printf("%d ", list[i]);
    }
    printf("\n");
    return;
}
Petr Skocik
  • 58,047
  • 6
  • 95
  • 142
  • I want to wrote function with only array as the parameter. Is this possible? Or I need to pass the size of the array as the second parameter? – mr. hacker Jul 13 '17 at 11:29
  • If you don't want to pass the size, you will need to mark the end of the array in some way so that the callee knows where it ends. C-string literals use null bytes. Perhaps you could use a negative number or something like INT_MAX or INT_MIN. – Petr Skocik Jul 13 '17 at 11:32
1

According to the C Standard (6.3.2.1 Lvalues, arrays, and function designators)

3 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 with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.

And (6.7.6.3 Function declarators (including prototypes))

7 A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to type’’, where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation...

Thus the following function declarations declare the same one function

void displayArray(int myarray[100]);
void displayArray(int myarray[10]);
void displayArray(int myarray[1]);
void displayArray(int myarray[]);
void displayArray(int *myarray);

You may include all these declarations (that are not definitions) in your program. The function parameter that declares an array is adjusted to pointer type.

So you need explicitly pass to the function the size of the array if the array does not have a sentinel value. For example

void displayArray( const int *myarray, size_t n );

//...

displayArray( list1, sizeof( list1 ) / sizeof( *list1 ) );
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

You should have create a variable to contain the size of the array and add this as a parameter to the function. 'list' is just a pointer to the first element of the array, so when you check sizeof(list), it returns the size of the pointer. Try it like this:

#include <stdio.h>
void displayArray(int myarray[]);
int main()
{
    int list1[] = {0, 5, 3, 5, 7, 9, 5};
    int size1 = 7;
    displayArray(list1,size1);
    return 0;
}

void displayArray(int list[], int size)
{
    printf("Your array is: ");
    for (int i = 0; i < size; i++)
    {
         printf("%d ", list[i]);
    }
    printf("\n");
    return;
}
  • 1
    You can, and probably should, use `int size1 = sizeof list1 / sizeof list1[0];`. No magic numbers, less error-prone, and easier to maintain. Or better, `size_t size1 = ....`. – ad absurdum Jul 13 '17 at 11:33
  • Better, name it `len1` to show it is the array length, not its size. – Weather Vane Jul 13 '17 at 11:39
  • 1
    @DavidBowling `int` is bad because it could invoke a narrowing conversion and is bad style anyway. I wouldn't even bother mentioning it. If that was to help newbies who might not have heard of `size_t`, then now's the time they need to learn about it. – underscore_d Jul 13 '17 at 11:39
  • @underscore_d-- right, hence my "Or better,...". – ad absurdum Jul 13 '17 at 11:42
  • @DavidBowling Sure, but generally I don't see the point of saying _'You can do this [something that maybe is slightly easier to read; by this point the readers has already copy/pasted it and left], or alternatively you can do it the right way'_. – underscore_d Jul 13 '17 at 11:50
  • @underscore_d-- the point of my comment was avoidance of magic numbers, not correct types. Completely agree that `size_t` is the correct type, which is why I mentioned it, but this seemed secondary to what I was commenting on. Your comments are good and useful, but perhaps should be directed at the answerer or OP, not me. And I didn't say "alternatively," I said "better." – ad absurdum Jul 13 '17 at 12:05