Newbie-Question: Function-Parameters

Discussion in 'C Programming' started by merman, Oct 7, 2004.

  1. merman

    merman Guest

    Hi,

    What is the most common way to pass an array into a function - and how
    can I return it?

    Thanks for help.

    o-o

    Thomas
     
    merman, Oct 7, 2004
    #1
    1. Advertising

  2. merman

    dandelion Guest

    "merman" <> wrote in message
    news:416556a4$0$168$...
    > Hi,
    >
    > What is the most common way to pass an array into a function - and how
    > can I return it?


    By pointer, which is even simpler than you may think. you could call

    void foobar(int bla[])
    {

    }

    or

    void foobar( int* bla)
    {

    }

    using

    int barfoo[3] = { 1, 2, 3 };
    foobar(barfoo);

    The two forms of function foobar are (more or less) equivalent. the sole
    identifier 'barfoo' (as opposed to barfoo[2]) evaluates to a pointer to the
    array.

    See? Easy.
     
    dandelion, Oct 7, 2004
    #2
    1. Advertising

  3. merman

    Pedro Graca Guest

    merman wrote:
    > What is the most common way to pass an array into a function - and how
    > can I return it?


    [newbie answer]
    pass a pointer and the array size, example:

    #include <stdio.h>

    void reverse_array(int * array, const size_t n) {
    size_t i;
    int tmp;

    for (i=0; i<n/2; ++i) {
    tmp = array;
    array = array[(n-1)-i];
    array[(n-1)-i] = tmp;
    }
    }

    int main(void) {
    int arr3[3] = {7, 8, 9};
    int arr6[6] = {2, 3, 4, 5, 6, 7};
    size_t i;

    reverse_array(arr3, 3);
    reverse_array(arr6, 6);

    printf("arr3: ");
    for (i=0; i<3; ++i) printf("%d ", arr3);
    printf("\n\n");

    printf("arr6: ");
    for (i=0; i<6; ++i) printf("%d ", arr6);
    printf("\n\n");

    return 0;
    }

    --
    USENET would be a better place if everybody read: | to mail me: |
    http://www.catb.org/~esr/faqs/smart-questions.html | simply "reply" |
    http://www.netmeister.org/news/learn2quote2.html | with text-only, |
    http://www.expita.com/nomime.html | no attachments. |
     
    Pedro Graca, Oct 7, 2004
    #3
  4. merman

    Eric Sosman Guest

    merman wrote:
    > Hi,
    >
    > What is the most common way to pass an array into a function - and how
    > can I return it?


    Strictly speaking, neither is possible. When we
    speak of "passing an array to a function" or "returning
    an array from a function," we're using sloppy language.
    Sloppy, but convenient: it's easier to say "This function
    returns a string" than to say "This function returns a
    pointer to the first character of a string."

    Recommended reading: Section 6 of the comp.lang.c
    Frequently Asked Questions (FAQ) list

    http://www.eskimo.com/~scs/C-faq/top.html

    .... with special attention to Question 6.4.

    If you really, truly must pass arrays to and from
    functions, you'll need to "disguise" them inside some
    other kind of object, usually a `struct'. But this is
    very seldom what you actually need to do; think carefully
    before trying it.

    --
     
    Eric Sosman, Oct 7, 2004
    #4
  5. merman

    Michael Mair Guest

    Michael Mair, Oct 7, 2004
    #5
  6. merman

    merman Guest

    Thanks for help - It's a really good group;-).

    o-o

    Thomas
     
    merman, Oct 7, 2004
    #6
  7. merman

    John Bode Guest

    merman <> wrote in message news:<416556a4$0$168$>...
    > Hi,
    >
    > What is the most common way to pass an array into a function - and how
    > can I return it?
    >
    > Thanks for help.
    >
    > o-o
    >
    > Thomas


    Strictly speaking, you can't pass array type objects as function
    parameters. What you can do is either pass a pointer to the first
    element in the array, or a pointer to the array object as a whole.
    The former is more common:

    #define ARRSIZE 10

    void process_arr(int *arr, size_t arrsize)
    {
    size_t i;
    for (i = 0; i < arrsize; i++)
    {
    arr = i * 2;
    }
    }

    int main(void)
    {
    int arr[ARRSIZE];

    process_arr (arr, sizeof arr); /* in this context, arr == &arr[0]
    */
    return 0;
    }

    Since you can't determine the size of the array based on a pointer to
    the first element, you must somehow specify the array size separately,
    either by passing the array size as a separate parameter (as above),
    or by writing a sentinel value to the array:

    #include <stdio.h>

    void print_names(char **names)
    {
    size_t i = 0;

    while (names != NULL)
    {
    printf ("name = %s\n", names[i++]);
    }
    }

    int main(void)
    {
    char *names[4] = {"Joe", "Bob", "Sue", NULL};

    print_names(names);
    return 0;
    }

    Note that most of the string processing library functions (strcmp(),
    strcat(), etc.) use the sentinel value method (i.e., the terminating 0
    in a character array) to determine the length of the strings passed to
    them. However, as anyone who's been bitten by gets() knows, this is
    not the most robust method for determining the physical size of an
    array. When I write array processing functions, I rely on passing the
    array size as a separate parameter.

    You can also pass a pointer to the array object (as opposed to a
    pointer to the first element):

    void process_arr(int (*arr)[ARRSIZE])
    {
    size_t i;

    for (i = 0; i < sizeof *arr; i++)
    {
    (*arr) = i*2;
    }
    }

    int main(void)
    {
    int a[ARRSIZE];

    process_arr(&a);
    return 0;
    }

    This form isn't used as much, largely because it isn't as flexible.
    The first method allows functions to work with arrays of any size,
    whereas this method only allows functions to work with arrays of a
    specific size. Doesn't help that the syntax is a little uglier.
    However, there are times when it is the right thing to use.

    Just as you cannot pass an array as an argument directly, you cannot
    have a function return an array type. You must either return a
    pointer to the first element, or a pointer to the whole array object.

    #include <stdlib.h>

    int *init_arr(void)
    {
    static int arr[ARRSIZE];
    size_t i;
    for (i = 0; i < sizeof arr; i++)
    {
    arr = i * 2;
    }
    return arr; /* again, in this context, arr == &arr[0] */
    }

    int (*init_fixedarr())[ARRSIZE]
    {
    static int arr[ARRSIZE];
    size_t i;
    for (i = 0; i < sizeof arr; i++)
    {
    arr = i * 2;
    }
    return &arr;
    }

    int main (void)
    {
    int *a1;
    int (*a2)[ARRSIZE];

    a1 = init_arr();
    a2 = init_fixedarr();

    return 0;
    }

    Since returning auto variables is a Bad Idea, I had to declare the
    arrays as static. Normally you won't be returning pointers to static
    array objects, but rather allocating memory on the fly and returning
    pointers to that:

    int *new_arr(size_t size)
    {
    int *a = malloc (size * sizeof *a);
    if (!a)
    {
    /* handle or log memory error */
    }
    return a;
    }

    int (*new_fixedarr())[ARRSIZE]
    {
    int (*a)[ARRSIZE] = malloc (sizeof *a);
    if (!a)
    {
    /* handle or log memory error */
    }
    return a;
    }

    Note that, in these cases, a1 will *not* be an object of array type,
    and you will not be able to determine its physical size without
    somehow returning or logging the array size as a separate value.
     
    John Bode, Oct 7, 2004
    #7
  8. merman

    Zian Smith Guest

    "dandelion" <> wrote in message news:<416559ff$0$147$4all.nl>...
    > "merman" <> wrote in message
    > news:416556a4$0$168$...
    > > Hi,
    > >
    > > What is the most common way to pass an array into a function - and how
    > > can I return it?

    >
    > By pointer, which is even simpler than you may think. you could call
    >
    > void foobar(int bla[])
    > {
    >
    > }
    >
    > or
    >
    > void foobar( int* bla)
    > {
    >
    > }
    >
    > using
    >

    <snip>

    Don't forget to pass the length of the array to the function..

    void foobar(int bla[], size_t len)
    {

    }

    -Z.Smith
     
    Zian Smith, Oct 7, 2004
    #8
  9. merman

    pete Guest

    Eric Sosman wrote:
    >
    > merman wrote:
    > > Hi,
    > >
    > > What is the most common way to pass an array into a function - and how
    > > can I return it?

    >
    > Strictly speaking, neither is possible. When we
    > speak of "passing an array to a function" or "returning
    > an array from a function," we're using sloppy language.
    > Sloppy, but convenient: it's easier to say "This function
    > returns a string" than to say "This function returns a
    > pointer to the first character of a string."


    You could say that it returns a pointer to a string.
    The term "pointer to a string" is defined in N869.

    --
    pete
     
    pete, Oct 8, 2004
    #9
  10. merman

    Mabden Guest

    "pete" <> wrote in message
    news:...
    > Eric Sosman wrote:
    > >
    > > When we
    > > speak of "passing an array to a function" or "returning
    > > an array from a function," we're using sloppy language.
    > > Sloppy, but convenient: it's easier to say "This function
    > > returns a string" than to say "This function returns a
    > > pointer to the first character of a string."

    >
    > You could say that it returns a pointer to a string.
    > The term "pointer to a string" is defined in N869.


    Oh. OK, thanks, we'll all do that from now on.

    --
    Mabden
     
    Mabden, Oct 8, 2004
    #10
  11. merman

    dandelion Guest

    "Zian Smith" <> wrote in message
    news:...
    > "dandelion" <> wrote in message

    news:<416559ff$0$147$4all.nl>...
    > > "merman" <> wrote in message
    > > news:416556a4$0$168$...
    > > > Hi,
    > > >
    > > > What is the most common way to pass an array into a function - and how
    > > > can I return it?

    > >
    > > By pointer, which is even simpler than you may think. you could call
    > >
    > > void foobar(int bla[])
    > > {
    > >
    > > }
    > >
    > > or
    > >
    > > void foobar( int* bla)
    > > {
    > >
    > > }
    > >
    > > using
    > >

    > <snip>
    >
    > Don't forget to pass the length of the array to the function..
    >
    > void foobar(int bla[], size_t len)
    > {
    >
    > }


    good hint, but only if it's not known in advance by

    #define FOOBAR_BUFFER_SIZE

    or simular.
    >
    > -Z.Smith
     
    dandelion, Oct 8, 2004
    #11
  12. merman

    John Bode Guest

    (John Bode) wrote in message news:<>...
    > process_arr (arr, sizeof arr); /* in this context, arr == &arr[0]
    > */


    Well that was sloppy. What I *meant* to say was that when an array
    identifier appears in an expression, the type of the identifier is
    converted from "array of T" to "pointer to T", and it's value is the
    address of the first element in the array, *except* when the array
    identifier is an operand to either sizeof or &, so:

    sizeof arr -- type of arr == ARRSIZE-element array of int
    &arr -- type of arr == ARRSIZE-element array of int
    arr -- type of arr == pointer to int, value == &arr[0]

    And someone else mentioned another way to pass arrays to functions; as
    members of a struct type:

    struct s {
    int arr[10];
    };

    void process_arr(struct s *arg)
    {
    size_t i;
    for (i = 0; i < sizeof arg->arr; i++)
    {
    /* do something interesting with arg->arr */
    }
    }

    int main(void)
    {
    struct s foo;

    process_arr (&foo);
    return 0;
    }
     
    John Bode, Oct 8, 2004
    #12
  13. merman

    John Bode Guest

    (John Bode) wrote in message news:<>...

    > int (*new_fixedarr())[ARRSIZE]


    ....and that *should* be

    int (*new_fixedarr(void))[ARRSIZE]


    Gah. Should stop trying to post, test, write code, and read email all
    at the same time.
     
    John Bode, Oct 8, 2004
    #13
  14. merman

    dandelion Guest

    "John Bode" <> wrote in message
    news:...
    > (John Bode) wrote in message

    news:<>...
    >
    > > int (*new_fixedarr())[ARRSIZE]

    >
    > ...and that *should* be
    >
    > int (*new_fixedarr(void))[ARRSIZE]
    >
    >
    > Gah. Should stop trying to post, test, write code, and read email all
    > at the same time.


    Never mind...

    I once cancelled a message 4 times before getting it right. Admittedly that
    ws prolog, but the idea is the same.
     
    dandelion, Oct 11, 2004
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jonck van der Kogel
    Replies:
    2
    Views:
    998
    Jonck van der Kogel
    May 27, 2004
  2. Jason
    Replies:
    2
    Views:
    527
    Jonathan Mcdougall
    May 13, 2006
  3. mosscliffe
    Replies:
    6
    Views:
    321
  4. kito
    Replies:
    2
    Views:
    426
  5. Florian Loitsch
    Replies:
    11
    Views:
    255
    Michael Winter
    Mar 15, 2005
Loading...

Share This Page