Declaring and initializing arrays in C - c

Is there a way to declare first and then initialize an array in C?
So far I have been initializing an array like this:
int myArray[SIZE] = {1,2,3,4....};
But I need to do something like this
int myArray[SIZE];
myArray = {1,2,3,4....};

In C99 you can do it using a compound literal in combination with memcpy
memcpy(myarray, (int[]) { 1, 2, 3, 4 }, sizeof myarray);
(assuming that the size of the source and the size of the target is the same).
In C89/90 you can emulate that by declaring an additional "source" array
const int SOURCE[SIZE] = { 1, 2, 3, 4 }; /* maybe `static`? */
int myArray[SIZE];
...
memcpy(myarray, SOURCE, sizeof myarray);

No, you can't set them to arbitrary values in one statement (unless done as part of the declaration).
You can either do it with code, something like:
myArray[0] = 1;
myArray[1] = 2;
myArray[2] = 27;
:
myArray[99] = -7;
or (if there's a formula):
for (int i = 0; i < 100; i++) myArray[i] = i + 1;
The other possibility is to keep around some templates that are set at declaration time and use them to initialise your array, something like:
static const int onceArr[] = { 0, 1, 2, 3, 4,..., 99};
static const int twiceArr[] = { 0, 2, 4, 6, 8,...,198};
:
int myArray[7];
:
memcpy (myArray, twiceArr, sizeof (myArray));
This has the advantage of (most likely) being faster and allows you to create smaller arrays than the templates. I've used this method in situations where I have to re-initialise an array fast but to a specific state (if the state were all zeros, I would just use memset).
You can even localise it to an initialisation function:
void initMyArray (int *arr, size_t sz) {
static const int template[] = {2, 3, 5, 7, 11, 13, 17, 19, 21, ..., 9973};
memcpy (arr, template, sz);
}
:
int myArray[100];
initMyArray (myArray, sizeof(myArray));
The static array will (almost certainly) be created at compile time so there will be no run-time cost for that, and the memcpy should be blindingly fast, likely faster than 1,229 assignment statements but very definitely less typing on your part :-).

Is there a way to declare first and
then initialize an array in C?
There is! but not using the method you described.
You can't initialize with a comma separated list, this is only allowed in the declaration. You can however initialize with...
myArray[0] = 1;
myArray[1] = 2;
...
or
for(int i = 1; i <= SIZE; i++)
{
myArray[i-1] = i;
}

This is an addendum to the accepted answer by AndreyT, with Nyan's comment on mismatched array sizes. I disagree with their automatic setting of the fifth element to zero. It should likely be 5 --the number after 1,2,3,4. So I would suggest a wrapper to memcpy() to produce a compile-time error when we try to copy arrays of different sizes:
#define Memcpy(a,b) do { /* copy arrays */ \
ASSERT(sizeof(a) == sizeof(b) && /* a static assert */ \
sizeof(a) != sizeof((a) + 0)); /* no pointers */ \
memcpy((a), (b), sizeof (b)); /* & unnecesary */ \
} while (0) /* no return value */
This macro will generate a compile-time error if your array is of length 1. Which is perhaps a feature.
Because we are using a macro, the C99 compound literal seems to need an extra pair of parentheses:
Memcpy(myarray, ((int[]) { 1, 2, 3, 4 }));
Here ASSERT() is a 'static assert'. If you don't already have your own, I use the following on a number of platforms:
#define CONCAT_TOKENS(a, b) a ## b
#define EXPAND_THEN_CONCAT(a,b) CONCAT_TOKENS(a, b)
#define ASSERT(e) enum {EXPAND_THEN_CONCAT(ASSERT_line_,__LINE__) = 1/!!(e)}
#define ASSERTM(e,m) /* version of ASSERT() with message */ \
enum{EXPAND_THEN_CONCAT(m##_ASSERT_line_,__LINE__)=1/!!(e)}

Why can't you initialize when you declare?
Which C compiler are you using? Does it support C99?
If it does support C99, you can declare the variable where you need it and initialize it when you declare it.
The only excuse I can think of for not doing that would be because you need to declare it but do an early exit before using it, so the initializer would be wasted. However, I suspect that any such code is not as cleanly organized as it should be and could be written so it was not a problem.

The OP left out some crucial information from the question and only put it in a comment to an answer.
I need to initialize after declaring, because will be different
depending on a condition, I mean something like this int
myArray[SIZE]; if(condition1) { myArray{x1, x2, x3, ...} } else
if(condition2) { myArray{y1, y2, y3, ...} } . . and so on...
With this in mind, all of the possible arrays will need to be stored into data somewhere anyhow, so no memcpy is needed (or desired), only a pointer and a 2d array are required.
//static global since some compilers build arrays from instruction data
//... notably not const though so they can later be modified if needed
#define SIZE 8
static int myArrays[2][SIZE] = {{0,1,2,3,4,5,6,7},{7,6,5,4,3,2,1,0}};
static inline int *init_myArray(_Bool conditional){
return myArrays[conditional];
}
// now you can use:
//int *myArray = init_myArray(1 == htons(1)); //any boolean expression
The not-inlined version gives this resulting assembly on x86_64:
init_myArray(bool):
movzx eax, dil
sal rax, 5
add rax, OFFSET FLAT:myArrays
ret
myArrays:
.long 0
.long 1
.long 2
.long 3
.long 4
.long 5
.long 6
.long 7
.long 7
.long 6
.long 5
.long 4
.long 3
.long 2
.long 1
.long 0
For additional conditionals/arrays, just change the 2 in myArrays to the desired number and use similar logic to get a pointer to the right array.

It is not possible to assign values to an array all at once after initialization.
The best alternative would be to use a loop.
for(i=0;i<N;i++)
{
array[i] = i;
}
You can hard code and assign values like --array[0] = 1 and so on.
Memcpy can also be used if you have the data stored in an array already.

There is no such particular way in which you can initialize the array after declaring it once.
There are three options only:
1.) initialize them in different lines :
int array[SIZE];
array[0] = 1;
array[1] = 2;
array[2] = 3;
array[3] = 4;
//...
//...
//...
But thats not what you want i guess.
2.) Initialize them using a for or while loop:
for (i = 0; i < MAX ; i++) {
array[i] = i;
}
This is the BEST WAY by the way to achieve your goal.
3.) In case your requirement is to initialize the array in one line itself, you have to define at-least an array with initialization. And then copy it to your destination array, but I think that there is no benefit of doing so, in that case you should define and initialize your array in one line itself.
And can I ask you why specifically you want to do so???

Related

C: howto convert a pointer to access it as a multidimensional array

I do have a function call like:
int Filter(short* array, short nNumRow, short nNumCol)
but inside it I want to handle array like that:
array[y][x] = xx;
I try to solve this by declaring an array
short help[nNumRow][nNumCol];
help = array;
but this doesn't work that way. How can I handle that problem without changing function parameter list (this *array is result of a different function that I can't change)? Best of course would be not a copy (of memory) is needed.
Probably another option would be
array[y*nNumCol + x] = xx;
but I don't like this calculations. So how to do this best?
Thanks!
How can I handle that problem without changing function parameter list?
If you can't do that, then you are stuck with the "mangled array" array[y*nNumCol + x] notation (which is old style but otherwise ok).
The best and correct solution is to change the function to this:
int Filter (short nNumRow, short nNumCol, short array[nNumRow][nNumCol])
{
...
array[x][y] = something;
}
The last resort, which I would not recommend unless you are maintaining some old crap that can't be changed, is a dirty pointer conversion inside the function. Writing such code requires that you to know exactly what you are doing, because if the types of the actual data or the alignment mismatch, you will get very strange bugs. The below code works and is safe as far as the C language is concerned, but it isn't pretty:
// BAD CODE, avoid this solution
#include <stdio.h>
int Filter (short* array, short nNumRow, short nNumCol)
{
short(*array2D)[nNumCol]; // pointer to array of type short[nNumCol]
array2D = (short(*)[nNumCol])array; // dirty pointer conversion
for(int i=0; i<nNumRow; i++)
{
for(int j=0; j<nNumCol; j++)
{
printf("%d ", array2D[i][j]);
}
printf("\n");
}
return 0;
}
int main (void)
{
short array[2][2] = { {1,2}, {3,4} };
Filter((void*)array, 2, 2);
}
The best (optimal) way to do that is your own solution:
array[y*nNumCol + x] = xx;
Fo "beauty" reasons, you may use a function-like macro to access that data:
#define arrElement(array,x,y) ((array)[(y)*nNumCol + (x)]]))
If you need to apply this trick to only one array, then you can simplify the macro:
#define arrElement(x,y) (array[(y)*nNumCol + (x)]]))
If the size of the array is not known before the function call, you will need to add some complexity to the macro:
#define arrElement(x,y,nNumCol) (array[(y)*(nNumCol) + (x)]]))
Note: I did not text exactly the statements above, but I used the trick in the past several times, successfully.
You can use a pointer-type (as per your question) only if the array always has the same size. Otherwise, you will have to define the pointer-type dynamically at run-time, which is somewhere between difficult and impossible.
A sane thing to do is to pass to the function the array size also, and check if the coordinates actually fall inside the array. Otherwise, you may run into undefined behavior, accessing data outside defined range.
Not the most efficient way, but you can create a two dimensions array inside your function and copy the original array to it:
#include <stdio.h>
int Filter(short* array, short nNumRow, short nNumCol) {
short arr[nNumRow][nNumCol];
memcpy(arr, array, nNumRow * nNumCol * sizeof(short));
for (int i = 0; i < nNumRow; i++) {
printf("| ");
for (int j = 0; j < nNumCol; j++) {
printf("%d ", arr[i][j]);
}
printf("| \n");
}
return 0;
}
int main(void) {
short arr[] = {1, 2, 3, 4, 5, 6 ,7, 8};
Filter(arr, 2, 4);
printf("---\n");
Filter(arr, 4, 2);
return 0;
}
See it running here: https://ideone.com/58KhYj

"Variable may not be initialized" when specifying the array size with another variable

I am trying to compile the following code:
int rows = 4;
int columns = 4;
int numblock[columns][rows] = {
{0,0,0,0},
{0,0,0,0},
{0,0,0,0},
{0,0,0,0}
};
And it tells me that the variable may not be initialized. When I write int numblock[4][4] instead, the compiler doesn't complain.
I guess it is related to this: C compile error: "Variable-sized object may not be initialized"
Can someone please explain this to me?
Edit - from a comment by op:
.. I set columns and rows = 4. It should know the size, shouldn't it?
The answer is already in the link you provide but I'll try to clarify as the linked answer wasn't clear to you.
First - what you have is called VLA, i.e. a Variable Length Array. The idea is simply that you can use another variable to set the size of the array. So this allows the size to be set at run time.
The problem you have is because: It is not allowed to initialize a VLA
It is as simple as that - it is just not supported in C.
It works fine with the initializer when the array is defined with numbers (e.g. [4][4]). That is because the size of the array is known at compile time
The fact you you initialize rows and columns to 4 makes no difference. The compiler do not track whether these variables are changed before the array is created. For instance like this:
void foo()
{
int rows = 4;
int columns = 4;
rows = rows + 42; // or scanf("%d", &rows) to get the number of rows from a user
int numblock[columns][rows]; // no - initializer here - not allowed
}
Even if you make rows and columns constants - like const int rows = 4; - it still won't work in C (but in C++ it will).
One way to "initialize" a VLA is to use memset - like:
void foo()
{
int rows = 4;
int columns = 4;
int numblock[columns][rows]; // no - initializer here - not allowed
memset(numblock, 0, sizeof numblock); // but using memset is easy
}
If you want a fixed number of rows/columns the C way is to use defines. Like:
#define ROWS 4
#define COLUMNS 4
void foo()
{
int numblock[ROWS][COLUMNS] = {
{0,0,0,0},
{0,0,0,0},
{0,0,0,0},
{0,0,0,0}
};
}
This will work because defines are resolved at compile time
I found that if I initialize n at 0 in the variable declarations, but do not initialize the array until inside of the body of the program (int main ()), that the compiler does not complain and the program functions as expected. This may not be the preferred way, and I think perhaps the use of #define may be a more elegant way.

How to assign a predefined value to a struct member on type definition?

This is a long shot, but maybe there will be some ideas. On a system I programming, I have defined structures to program processor registers. The registers are comprised of several fields of a few bits each, with potentially "reserved" bits in between. When writing to a register, the reserved bits must be written as zeros.
For example:
typedef struct {
uint32_t power : 3;
uint32_t reserved : 24;
uint32_t speed : 5;
} ctrl_t;
void set_ctrl()
{
ctrl_t r = {
.power = 1;
.speed = 22;
.reserved = 0;
}
uint32_t *addr = 0x12345678;
*addr = *((uint32_t *) &r);
return;
}
I want to be able to set the reserved field to a default value (0 in this example), and to spare the need for an explicit assignment (which happens a lot in our system).
Note that if the instantiated object is static, then by default an uninitialized field will be 0. However, in the above example there is no guarantee, and also I need to set any arbitrary value.
Structure type definitions in C cannot express values for structure members. There is no mechanism for it. Structure instance definitions can do.
I want to be able to set the reserved field to a default value (0 in
this example), and to spare the need for an explicit assignment (which
happens a lot in our system).
Note that if the instantiated object is static, then by default an
uninitialized field will be 0. However, in the above example there is
no guarantee, and also I need to set any arbitrary value.
That the default value you want is 0 is fortuitous. You seem to have a misunderstanding, though: you cannot partially initialize a C object. If you provide an initializer in your declaration of a structure object, then any members not explicitly initialized get the same value that they would do if the object had static storage duration and no initializer.
Thus, you can do this:
void set_ctrl() {
ctrl_t r = {
.power = 1,
.speed = 22,
// not needed:
// .reserved = 0
};
// ...
If you want an easy way to initialize the whole structure with a set of default values, some non-zero, then you could consider writing a macro for the initializer:
#define CTRL_INITIALIZER { .power = 1, .speed = 22 }
// ...
void set_other_ctrl() {
ctrl_t r = CTRL_INITIALIZER;
// ...
Similarly, you can define a macro for partial content of an initializer:
#define CTRL_DEFAULTS .power = 1 /* no .speed = 22 */
// ...
void set_other_ctrl() {
ctrl_t r = { CTRL_DEFAULTS, .speed = 22 };
// ...
In this case you can even override the defaults:
ctrl_t r = { CTRL_DEFAULTS, .power = 2, .speed = 22 };
... but it is important to remember to use only designated member initializers, as above, not undesignated values.
It can't be done.
Values don't have "constructors" in the C++ sense in C. There's no way to guarantee that arbitrary code is run whenever a value of a certain type is created, so this can't be done. In fact "creation" of a value is quite a lose concept in C.
Consider this:
char buf[sizeof (ctrl_t)];
ctrl_t * const my_ctrl = (ctrl_t *) buf;
In this code, the pointer assignment would have to also include code to set bits of buf to various defaults, in order for it to work like you want.
In C, "what you see is what you get" often holds and the generated code is typically quite predictable, or better due to optimizations. But that kind of "magic" side-effect is really not how C tends to work.
It is probably better to not expose the "raw" register, but instead abstract out the existance of reserved bits:
void set_ctrl(uint8_t power, uint8_t speed)
{
const uint32_t reg = ((uint32_t) power << 29) | speed;
*(uint32_t *) 0x12345678 = reg;
}
This explicitly computes reg in a way that sets the unused bits to 0. You might of course add asserts to make sure the 3- and 5-bit range limits are not exceeded.

In C, how to find an offset of element in array

#define ID_A 5
#define ID_B 7
#define ID_C 9
const int id_arr={ ID_A, ID_B, ID_C, };
I know if I need to know the offset of ID_C in id_arr,
I can use a simple function like
int get_offset(id){
for(i=0;i<id_arr_num;++i){
if(id==id_arr[i]) return i;
}
}
But arr is const,
so I can know offset of ID_C will be 2 before runtime,
is any way to use macro or other way to know the offset before c runtime?
Rather than using ID's directly, use indexes that themselves are offsets:
enum {
IDX_A,
IDX_B,
IDX_C,
IDX_COUNT
};
const int id_arr={ 5, 7, 9 };
/* Error checking to make sure enum and array have same number of elements (from assert.h) */
static_assert((sizeof id_arr / sizeof *id_arr) == IDX_COUNT, "Enum/array mismatch");
Usage is simple:
id = id_arr[IDX_A];
Avoid using macros for that.
And you forgot to define id_arr_num.
No, there is no way of knowing this index before runtime, and avoid using global values as much as possible.
This function will give you the index of the variable you're looking for:
int get_offset(id, arr, size){
for(i = 0;i < size;++i)
if(id == arr[i]) return i;
}

Shared Data in pthread Programming

There's something I'm still not very sure about in pthread programming.
And I'll appreciate if someone can tell me an absolute answer.
My previous question is here:
How do I assign array variable in a simple Pthread programming?
And now, I'm working on matrix multiplication.
It works well using this:
typedef struct {
int rowIdx;
int (*matA)[SIZE], (*matB)[SIZE], (*matC)[SIZE];
} newType;
int main (){
int matriksA[SIZE][SIZE];
int matriksB[SIZE][SIZE];
int matriksC[SIZE][SIZE];
for (i=0;i<NUM_THREAD;i++) {
(*block).rowIdx = i;
(*block).matA = matriksA;
(*block).matB = matriksB;
(*block).matC = matriksC;
pthread_create(&arrThread[i], NULL, matrixMul, (void *)block);
block++;
}
}
void *matrixMul(void *x){
newType *p = (newType *) x;
int i = (*p).rowIdx;
int j,k;
for (j=0;j<SIZE;j++){
int result = 0;
for(k=0;k<SIZE;k++){
int MAik = (*p).matA[i][k];
int MBkj = (*p).matB[k][j];
result = result + (MAik*MBkj);
}
(*p).matC[i][j] = result;
}
pthread_exit(NULL);
}
The matrixMul is doing the matrix multiplication matC = matA x matB.
I tried using this struct before but it didn't work.
typedef struct {
int rowIdx;
int **matA, **matB, **matC;
} newType;
Apparently from what I've read, a variable array can be considered as a pointer that holds the address of the first element in the array. As for 2-dimensional array, we must tell the compiler the size of the column. Thus we must use (*matA)[SIZE] instead of **matA in the typedef struct.
But I'm still not sure about what I was doing there.
Did I just copy a 2D-array to another 2D-array by assigning its pointer or what?
Kinda confusing....LOL...
My next questions is regarding these lines:
(*block).matA = matriksA;
(*block).matB = matriksB;
(*block).matC = matriksC;
What actually happened there? Do each block variable in the code above has its own copy of matrix data? Or do they just share it by having their pointer refer to the same location in memory which means matA, matB, and matC behave like a static variable (as in object oriented programming)? In other words, is there only one copy of matA, matB, and matC; and do the threads access the shared data simultantly? Or is there many copies of 'matA's, and each of them has its own different allocation in RAM?
Same question with my first post, what happened behind these lines?
(*z).arrA = arrayA;
(*z).arrB = arrayB;
(*z).arrC = arrayC;
Are the codes above efficient enough to do the task (array addition and matrix multiplication)? Or is there another way which more efficient from the memory-allocation point of view?
#Code-Guru: there I've posted the new question.
The basic problem in threaded programming is to make sure that there is no possibility of two separate threads trying to modify the data at the same time, or read data which another thread might be modifying. (If there is no danger that the data might be modified, it is perfectly OK for two threads to read the same non-changing data at the same time.)
Applied to your matrix multiplication problem, the threads are only going to read matrix A and matrix B, so you don't have to control access to those variables — assuming that they are initialized before you launch the threads.
On the other hand, the result Matrix C, will be being accessed for write, so you either have to be sure that you have partitioned the workload so that no two threads will ever access the same elements (they are working on disjoint subsets of Matrix C), or you have to coordinate access so that only one thread is modifying a given cell at a given time, and you've enforced this with mutual exclusion (a mutex) or something equivalent.
Your questions
You've not shown how block is defined, amongst other things. It is helpful if you show us an SSCCE (Short, Self-Contained, Correct Example), like the one I show you below. It saves us having to reverse-engineer your code fragment into working code. Done properly, it does not take up much space. (An earlier edition of this answer went off on a tangent because the code was not complete!)
In your original, you created NUM_THREAD threads to process SIZE x SIZE matrices. Since you didn't show the definition of SIZE or NUM_THREAD, we have to assume that the two sizes were equal. Various different recipes for disaster were available depending on the relative sizes of the two constants.
The threads are all being given the same matrices to work on, which is what you were really asking about. Each thread has a pointer to the same memory.
Assuming the (*z).arrA = arrayA; you refer to is the (*block).arrA = matriksA; assignment, then the you're assigning a pointer to an array of SIZE integers to block->arrA (which is equivalent to (*block).arrA). That's a little contorted, but legitimate. You'll need to be careful using that.
You ask if the code is efficient enough. First sub-question: does it produce the correct answer (and is that guaranteed)? I'm not yet sure about that. However, if each thread is working on one column of the result matrix, that should be safe enough.
SSCCE
This code uses C99 constructs. It won't compile under C89.
#include <stdio.h>
#include <pthread.h>
enum { SIZE = 3 };
typedef struct
{
int rowIdx;
int (*matA)[SIZE];
int (*matB)[SIZE];
int (*matC)[SIZE];
} newType;
extern void *matrixMul(void *);
static void print_matrix(const char *tag, int d1, int d2, int matrix[d1][d2])
{
printf("%s: (%d x %d)\n", tag, d1, d2);
for (int i = 0; i < d1; i++)
{
printf("%d:", i);
for (int j = 0; j < d2; j++)
printf(" %6d", matrix[i][j]);
putchar('\n');
}
}
int main(void)
{
int matriksA[SIZE][SIZE] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
int matriksB[SIZE][SIZE] = { { 11, 12, 13 }, { 14, 15, 16 }, { 17, 18, 19 } };
int matriksC[SIZE][SIZE];
newType thedata[SIZE];
newType *block = thedata;
pthread_t arrThread[SIZE];
for (int i = 0; i < SIZE; i++)
{
block->rowIdx = i;
block->matA = matriksA;
block->matB = matriksB;
block->matC = matriksC;
//matrixMul(block);
pthread_create(&arrThread[i], NULL, matrixMul, block);
block++;
}
for (int i = 0; i < SIZE; i++)
pthread_join(arrThread[i], 0);
print_matrix("Matrix A", SIZE, SIZE, matriksA);
print_matrix("Matrix B", SIZE, SIZE, matriksB);
print_matrix("Matrix C", SIZE, SIZE, matriksC);
}
void *matrixMul(void *x){
newType *p = (newType *) x;
int i = p->rowIdx;
for (int j = 0; j < SIZE; j++)
{
int result = 0;
for(int k = 0; k < SIZE; k++)
{
int MAik = p->matA[i][k];
int MBkj = p->matB[k][j];
result += MAik * MBkj;
}
p->matC[i][j] = result;
}
//pthread_exit(NULL);
return(0);
}
You might note that I've added a matrix printing function (and used it). I also added sample data for a pair of 3x3 matrices, and I've verified that the answer is correct. I did the testing in two steps:
Check that a single-threaded version of the code produced the correct answer.
Add threading.
If step 1 produced the wrong answer, you know that you've only got basic calculations to fix; it isn't a thread-induced problem (because there is only one thread!). Fortunately, it produces the right answer. Adding the threading was then simple.
Output
$ ./ta
Matrix A: (3 x 3)
0: 1 2 3
1: 4 5 6
2: 7 8 9
Matrix B: (3 x 3)
0: 11 12 13
1: 14 15 16
2: 17 18 19
Matrix C: (3 x 3)
0: 90 96 102
1: 216 231 246
2: 342 366 390
$

Resources