assigning values to an array after declaring it

Discussion in 'C Programming' started by Eric Bantock, Jun 16, 2004.

  1. Eric Bantock

    Eric Bantock Guest

    Very basic question I'm afraid. Once an array has been declared, is there
    a less tedious way of assigning values to its members than the following:

    myarray[0]=8;
    myarray[1]=3;
    myarray[2]=4;
    myarray[3]=0;
    myarray[4]=0;
    myarray[5]=1;
    myarray[6]=8;
    myarray[7]=8;
    etc...

    I can't assign values immediately on declaration because I want myarray
    to be initialised differently according to various cases only determined
    at runtime.

    Thanks for any help. best regards -Eric
     
    Eric Bantock, Jun 16, 2004
    #1
    1. Advertisements

  2. Here are some ideas:
    1. Many constant arrays:
    Declare constant arrays for each case in the program.
    Copy the data from the constant array to the variable
    depending on the circumstances. If the data won't change,
    then use a pointer instead of an array.

    2. Load data from a stream (file).
    Prefer a text file to a binary file. Text files can be
    easily created and updated using an editor. Binary files
    are more difficult to create and maintain.

    3. Load data from another source.
    Some platforms have places that programs can store
    their data, such as a registry or ROM. Accessing these
    are off-topic for this newsgroup and not portable.


    --
    Thomas Matthews

    C++ newsgroup welcome message:
    http://www.slack.net/~shiva/welcome.txt
    C++ Faq: http://www.parashift.com/c++-faq-lite
    C Faq: http://www.eskimo.com/~scs/c-faq/top.html
    alt.comp.lang.learn.c-c++ faq:
    http://www.raos.demon.uk/acllc-c++/faq.html
    Other sites:
    http://www.josuttis.com -- C++ STL Library book
     
    Thomas Matthews, Jun 16, 2004
    #2
    1. Advertisements

  3. Eric Bantock

    Dan Pop Guest

    If there are only a few possibilities, create an array for each one:

    static const int ini1[] = { ... };
    static const int ini2[] = { ... };
    static const int ini3[] = { ... };

    Then, if you have decided that ini2 is the right initialiser, you can do:

    memcpy(myarray, ini2, sizeof myarray);

    The other solution is a compound literal, but since this works in C99 only
    I'm not advising it.

    Dan
     
    Dan Pop, Jun 16, 2004
    #3
  4. (than assigning values to members)

    No.

    Well, you could memcpy data into it, if you could be sure of byte order and
    alignment constraints.
     
    Mark McIntyre, Jun 16, 2004
    #4
  5. Eric Bantock

    Eric Sosman Guest

    You can use a loop:

    for (i = 0; i < N; ++i)
    myarray = some_expression_probably_involving_i;

    Of course, this approach requires that there is some method
    behind the apparent madness of 8,3,4,...

    If the array contents are not systematic or readily computed
    but have been laboriously typed in from historical records of
    molybdenum production in nineteenth-century Bolivia *but* there
    are only a few such sets of data, you could carry a few pre-
    initialized arrays around and then copy the chosen one into
    myarray[] at run-time:

    const SomeType data_sets[][N] = {
    { 8,3,4, ... },
    { 6,6,8, ... },
    { 4,9,2, ... },
    ...
    };
    SomeType myarray[N];
    ...
    int k = index_of_chosen_data_set;
    memcpy(myarray, data_sets[k], sizeof myarray);

    It's hard to recommend one approach over the other (or
    over alternative possibilities) without some notion of what
    you're really trying to accomplish.
     
    Eric Sosman, Jun 16, 2004
    #5
  6. Eric Bantock

    Peter Ammon Guest

    Initializers can be determined at runtime. Why can't you initialize
    where you define it? You can use an inner scope.

    void foo(void) {
    int a, b, c;
    scanf("%d %d %d", &a, &b, &c);
    {
    float arr[] = {a, b, c};
    /* do something with arr */
    }
    }
     
    Peter Ammon, Jun 17, 2004
    #6
  7. Eric Bantock

    nobody Guest

    But that wouldn't be *assigning* (as in "assigning values to its members"),
    would it? IMHO, as usual, problem lies in
    the problem definition, which seems not to define the problem, but to imply
    the solution., and question turns out to be about the implementation of
    particular
    "suggested" solution. I hate it when my bosses are doing this to me. So the
    1st
    answer is perfectly correct (to my limited knowledge). Second one will
    hopefully
    clarify OP's question to himself. Though it may be considered irritating to
    some participants here, I go by the old Chinese proverb: "Give a man a fish
    and
    you feed him for a day. Teach a man to fish, and you feed him for a
    lifetime..",
    even if someone only asks for one (topical) fish, (non-topical) reply in
    some
    circumstances can be more beneficial, in the long run.
     
    nobody, Jun 17, 2004
    #7
  8. Eric Bantock

    Neil Kurzman Guest

    suggestion 1
    create the other constant arrays. Then assign each value in a for loop
    or with memcopy();

    suggestion 2
    create all the possible arrays, then use a pointer to choose the correct
    one.
     
    Neil Kurzman, Jun 17, 2004
    #8
  9. Eric Bantock

    Dan Pop Guest

    When Mark McIntyre says "no", it is usually safe to assume that the answer
    is "yes". And vice versa.
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ^^^^^^^^^^^^^^^^^^^^^

    An idiotic statement, as one could expect from Mark. Since the
    initialiser is compiled by the same compiler, there are no representation
    issues at all. And memcpy() has NO alignment constraints: it is
    actually the right way of handling assignments when the source is not
    guaranteed to be aligned for its type (but this is a non-issue here,
    anyway).

    Dan
     
    Dan Pop, Jun 17, 2004
    #9
  10. Eric Bantock

    Eric Bantock Guest


    yes, and in this case unfortunately there is none.
    Thanks Eric (and Dan and others who suggested a similar approach) - this
    is what I'll do. Actually, I have always wondered (but never been curious
    enough to actually find out) exactly *why* C won't let you assign values
    "all at once" to an array except at declaration. Can anyone explain?

    Eric
     
    Eric Bantock, Jun 17, 2004
    #10
  11. Eric Bantock

    Eric Bantock Guest

    Thanks, but in my case it's much simpler to declare the array in question
    as a global, so I don't think I can do something like this--my a, b and c
    will only be determined much later, as a result of user input etc.
     
    Eric Bantock, Jun 17, 2004
    #11
  12. Eric Bantock

    Dan Pop Guest

    Why not? Isn't copying the values of the members of one array into the
    corresponding members of another arrays the closest you can get in
    the way of "array assignment", an operation not directly supported
    by the language?

    Dan
     
    Dan Pop, Jun 17, 2004
    #12
  13. Eric Bantock

    Dan Pop Guest

    After declaration, memcpy(array1, array2, sizeof array1) does exactly
    that. It may not look as nicely as array1 = array2, but it has the same
    semantics as this hypothetical usage of the assignment operator.

    If you want to know why array1 = array2 doesn't work, it is because
    in this context (as in most other contexts) array names are converted to
    pointers to their first elements. Furthermore, these pointers are not
    lvalues, so they cannot be assigned values (it wouldn't make any sense
    to try to change the address of the first element of an array, anyway).

    It is because of this rule that arrays are not considered first class
    citizens in C. You cannot pass them to functions and you cannot
    return them from functions. Instead, you pass the address of the first
    array element to the function and you can return such an address from the
    function, which, most of the time, is exactly what you want.

    Dan
     
    Dan Pop, Jun 17, 2004
    #13
  14. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    This is C99 only, correct?
     
    Orhan Kavrakoglu, Jun 22, 2004
    #14
  15. For an aggregate (list) initializer, yes; in C89 all aggregate
    initializer values must be constant=compile-time expressions
    regardless of the (scope and) duration of the variable. Although of
    course runtime could still be allowed for auto as an extension.

    A single-expression initializer, including for a struct or union, of
    an auto variable, can be runtime since C89 at least.
    - David.Thompson1 at worldnet.att.net
     
    Dave Thompson, Jul 1, 2004
    #15
    1. Advertisements

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.