0

This is my first time asking so please be gentle lol. So I am trying to better understand arrays in C. Is there a way I can add an element to an array without using a for loop? The problem is I want to add a new element to the end of the array, but without knowing the size of the array.

So I already have this:

#include <stdlib.h> //not sure if needed but put it just in case
int main(void):
   float real[20];
   real[]={1,2,3,4,5};

I want to add the number 6 to the array, but I don't want to use real[5]=6. Is there another way to add an element to the end of the array without a loop checking if each element in the array until the element is null? Thanks for your help in advance!

10
  • 3
    real[]={1,2,3,4,5}; is wrong Commented Apr 8, 2015 at 7:57
  • 4
    The code you posted won't compile. In C, array length and array have to be kept separately. Alternatively, you can terminate your array (or the active entries therein) with a sentinel value. You still have to respect the allocated size of the array when adding elements, though. Commented Apr 8, 2015 at 7:59
  • yes, maintain the array length in a seperate variable and use that value. Commented Apr 8, 2015 at 8:00
  • 1
    One way would be to use a variable,say size and increment it as you add values into the array. And No, you can't determine how many slots are filled in the array. Commented Apr 8, 2015 at 8:00
  • 2
    And int main(void): ? Post real code that can compile. Commented Apr 8, 2015 at 8:05

5 Answers 5

3

C arrays don't know about their length. If you need arrays that can grow and shrink, you have to keep extra information on how long your active array is. An array that is created on the stack like so:

real array[20] = {1, 2, 3};

will contain twenty elements, the first three initialised with concrete values, the rest initialised to zero. If you want to consider this array as an array of initially three values that can hold up to 20 values, you have to keep the actual array length as an extra variable:

real array[20] = {1, 2, 3};
int narray = 3;

You can then append a value. Take care not to overflow that maximum storage of 20 elements:

if (narray < 20) array[narray++] = 9;

You can read the last value and remove it from the array:

if (narray) printf("%g\n", array[--narry]);

Here, you have to take care not to underflow the array. (Also, don't decrement narray more than once in the same expression, which will lead to undefined behaviour.)

If you write a function that operates on the array, pass both array and length:

void array_print(float array[], int n)
{
    int i;

    for (i = 0; i < n; i++) {
        if (i) printf(", ");
        printf("%g", array[i]);
    }

    printf("\n");
}

and call it like so:

array_print(array, narray);

Another approach is to keep a sentinel value like 0.0. This can be useful in some cases, but it has the disadvantage that you have to traverse the whole array to find out the length. It also removes the sentinel from the range of valid values that your array can hold.

The advantage here is, of course, that the array is "self-contained", i.e. you don't have to pass array and length to a function; just the array is enough. When appending you still have to take care not to overflow the maximum storage, which makes this approach cumbersome.

Sign up to request clarification or add additional context in comments.

Comments

1

The only way is to keep a pointer to the next free position in the array. For example

#include <stdio.h>

float * copy( const float *src, size_t n, float *dst )
{
    while ( n-- ) *dst++ = *src++;

    return dst;
}

int main(void) 
{
    float real[20];
    float *p = real;

    p = copy( ( float [] ){ 1, 2, 3, 4, 5 }, 5, p );

    p = copy( ( float [] ){ 6, 7 }, 2, p );

    for ( float *q = real; q != p; ++q ) printf( "%1.1f ", *q );
    printf( "\n" );

    return 0;
}

The output is

1.0 2.0 3.0 4.0 5.0 6.0 7.0 

You always can check whether p points within the array using condition

p < real + 20

The other approach is to use a structure that contains an array. For example

struct Array
{
    enum { N = 20 };
    float real[N];
    size_t n; /* current number of filled elements */
};

Comments

0

With a little help of the preprocessor, you can use a compound literal to get the size:

int main(void)
{
    #define REAL_VALUES 1, 2, 3, 4, 5
    float real[20] = {REAL_VALUES};

    real[sizeof((float[]){REAL_VALUES}) / sizeof(float)] = 6;
    return 0;
}

3 Comments

did you mean realloc?
@kuhaku, no, I mean real (the name of the variable used by OP)
I don't know, it wasn't me.
0

In C you can get the length of an array with the expression sizeof (array) / sizeof (array)[0], or even better, by defining a macro:

#define LEN(array) \
    ((int) (sizeof (array) / sizeof (array)[0]))

What you describe is not adding an element to the end of the array but rather adding an element after the last element inserted. For that you need a variable that keeps track of the element count:

int count = 0;
float x;
...
if (count < LEN(real)) {
    real[count] = x;
    count++;
}

Observe, however, that once you have passed the array to a function its length is gone, so you need to pass the array length to the function as well:

void foo(float a[], int len);
...
foo(real, LEN(real));

3 Comments

Any function which alters the array should have the proto type void foo (float *array, int * index); allowing index to be manipulated in situ.
@rhubarbdog I haven't specified what foo does. Let's say it clears the array by setting all elements to 0.0. Why should it have an integer pointer as a formal parameter?
my comment is really for the OP, it's not a slur on your answer. In fairness the argument index should be size_t I only used int to be consistent with your answer.
0

You can use memset() to make space for your element in your array and then insert your element at specific position.

Here is sample code below.

/*Make space for number to insert.*/
memmove(&arr[pos+1],&arr[pos],(ARR_SIZE+1-pos)*sizeof(int));
arr[pos] = num;/*insert the number.*/

Full code snipet could be found here InsertElement

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.