In C99 you can assign each structure in a single line. I don't think that you can assign the array of structs in one line though.
C99 introduces compound literals. See the Dr. Dobbs article here: The New C: Compound Literals
theTest[0] = (test_t){7,8,9};
theTest[1] = (test_t){10,11,12};
You could assign to a pointer like this:
test_t* p;
p = (test_t [2]){ {7,8,9}, {10,11,12} };
You could use memcpy as well:
memcpy(theTest, (test_t [2]){ {7,8,9}, {10,11,12} }, sizeof(test_t [2]);
Above tested with gcc -std=c99 (version 4.2.4) on linux.
You should read the Dr. Dobbs article to understand how compound literals work.
Answer from Karl Voigtland on Stack OverflowIn C99 you can assign each structure in a single line. I don't think that you can assign the array of structs in one line though.
C99 introduces compound literals. See the Dr. Dobbs article here: The New C: Compound Literals
theTest[0] = (test_t){7,8,9};
theTest[1] = (test_t){10,11,12};
You could assign to a pointer like this:
test_t* p;
p = (test_t [2]){ {7,8,9}, {10,11,12} };
You could use memcpy as well:
memcpy(theTest, (test_t [2]){ {7,8,9}, {10,11,12} }, sizeof(test_t [2]);
Above tested with gcc -std=c99 (version 4.2.4) on linux.
You should read the Dr. Dobbs article to understand how compound literals work.
In case you want to set the values to zero (or -1), you can use memset:
memset(struct_array, 0, sizeof(struct_array));
memset(struct_array, -1, sizeof(struct_array));
Changing array inside function in C - Stack Overflow
Changing all values of an array? - C++ Forum
c - How to change the value in char *array[]? - Stack Overflow
c - Can one (re)set all the values of an array in one line (after it has been initialized)? - Stack Overflow
For your specific case where you initially have 0 and 1, the following might be faster. You'll have to bench mark it. You probably can't do much better with plain C though; you may need to dive into assembly if you want to take advantage of "x86 trickery" that may exist.
for(int i = 0; i < size ; i++){
array[i] *= 123456;
}
EDIT:
Benchmark code:
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
size_t diff(struct timespec *start, struct timespec *end)
{
return (end->tv_sec - start->tv_sec)*1000000000 + end->tv_nsec - start->tv_nsec;
}
int main(void)
{
const size_t size = 1000000;
int array[size];
for(size_t i=0; i<size; ++i) {
array[i] = rand() & 1;
}
struct timespec start, stop;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);
for(size_t i=0; i<size; ++i) {
array[i] *= 123456;
//if(array[i]) array[i] = 123456;
}
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &stop);
printf("size: %zu\t nsec: %09zu\n", size, diff(&start, &stop));
}
my results:
Computer: quad core AMD Phenom @2.5GHz, Linux, GCC 4.7, compiled with
$ gcc arr.c -std=gnu99 -lrt -O3 -march=native
ifversion: ~5-10ms*=version: ~1.3ms
For a small array such as your it's no use trying to find another algorithm, and if the values are not in a specific pattern a simple loop is the only way to do it anyway.
However, if you have a very large array (we're talking several million entries), then you can split the work into threads. Each separate thread handles a smaller portion of the whole data set.
In c you can't pass a variable by reference, the array variable that you assign inside the function contains initially the same address as the passed pointer, but it's a copy of it so modifying it will not alter the passed pointer.
You need to pass the address of the pointer in order to be able to alter it, like this
// Change the pointer of the array
void change(int **array, int length)
{
*array = malloc(length * sizeof(int));
if (*array == NULL)
return;
for (int i = 0 ; i < length ; i++)
(*array)[i] = 1;
}
Then in main() you cannot assign to an array, doing so through this kind of function is surely undefined behavior. The array defined in main() is allocated on the stack and you cannot assign anything to an array since they are non-writeable lvalues so you cannot make it point to a heap memory location obtained with malloc(), you need to pass a pointer like this
int *array;
change(&array, length);
free(array);
If you want the function to replace the previous array, it will have to free() the malloc()ed data (note that passing NULL to free() is well defined), so
// Change the pointer of the array
void change(int **array, int length)
{
free(*array);
*array = malloc(length * sizeof(int));
if (*array == NULL)
return;
for (int i = 0 ; i < length ; i++)
(*array)[i] = 1;
}
then in main()
int *array;
array = NULL;
change(&array, length);
change(&array, length);
change(&array, length);
change(&array, length);
free(array);
will do what you apparently want.
Ok, i will make the answer short.
- Arrays are always passed by reference in C
change(array, length); In this line, it means reference to the first element of the array variable is passed to the function.
Now the function needs a pointer to catch the reference, it can be a pointer or it can be an array. Note that the pointer or the array is local to the function.
You received it in a pointer named array. Which is definitely a pointer but it is not the same as array in main function. It is local to the change function.
You declared a new array dynamically, and assigned a pointer named new with it. And all the changes you did were to new pointer.
Everything is ok till now.
- Now you assigned the new pointer to the array pointer which is local to the change function.
This is the real issue. As even though the array is in heap section, and it will remain in the memory, but the *array and *new are local pointer variables.
Also array pointer in change function is different from array pointer in main function.
The solution to this problem is Manipulate the data of array pointer directly.
void change(int *array,int length) { int i; for(i = 0 ; i < length ; i++) array[i] = 1; }
In this way you are directly overwriting values of array in main function. Everything else is correct.
Summerization: array pointer in change function is local to change function. array in main function is local to main function. Making change function's local array pointer point to array in heap section won't change data in actual array. You changed pointer's position, Not the array's data.
memcpy(myarray, (int [5]){a,b,c,d,e}, 5*sizeof(int));
Here is a solution that is all standards compatible (C89, C99, C++)
It has the advantage that you only worry about entering the data in one place. None of the other code needs to change - there are no magic numbers. Array is declared on the heap. The data table is declared const.
(Click here to try running it in Codepad)
#include<stdio.h>
#include<stdlib.h>
int main()
{
unsigned int i = 0;
int *myarray = 0;
static const int MYDATA[] = {11, 22, 33, 44, 55};
myarray = (int*)malloc(sizeof(MYDATA));
memcpy(myarray, MYDATA, sizeof(MYDATA));
for(i = 0; i < sizeof(MYDATA)/sizeof(*MYDATA); ++i)
{
printf("%i\n", myarray[i]);
}
free(myarray);
return 0;
}
There are fewer possibilities in C, but in case of an unsigned char and setting its values to zero you could use memset:
memset(&digit[4], 0, 4);
Demo.
One options is that you could write a subroutine that would implement the interface that other languages provide "under the cover". You'll probably want to educate yourself on 'VARARGS' to make it take a variable number of arguments.