Is it possible to assign some values to an array instead of all? To clarify what I want:
If I need an array like {1,0,0,0,2,0,0,0,3,0,0,0} I can create it like:
int array[] = {1,0,0,0,2,0,0,0,3,0,0,0};
Most values of this array are '0'. Is it possible to skip this values and only assign the values 1, 2 and 3? I think of something like:
int array[12] = {0: 1, 4: 2, 8: 3};
Is it possible to skip this values and only assign the values 1, 2 and 3?
In C, Yes. Use designated initializer (added in C99 and not supported in C++).
int array[12] = {[0] = 1, [4] = 2, [8] = 3};
Above initializer will initialize element 0, 4 and 8 of array array with values 1, 2 and 3 respectively. Rest elements will be initialized with 0. This will be equivalent to
int array[12] = {1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0};
The best part is that the order in which elements are listed doesn't matter. One can also write like
int array[12] = {[8] = 3, [0] = 1, [4] = 2};
But note that the expression inside [ ] shall be an integer constant expression.
Here is my trivial approach:
int array[12] = {0};
array[0] = 1; array[4] = 2; array[8] = 3;
However, technically speaking, this is not "initializing" the array :)
An alternative way to do it would be to give default value by memset for all elements in the array, and then assign the specific elements:
int array[12];
memset(array, 0, sizeof(int) * 12); //if the default value is 0, this may not be needed
array[0] = 1; array[4] = 2; array[8] = 3;
Standard C17
The standard (C17, N2176) has an interesting example in § 6.7.9(37):
EXAMPLE 13 Space can be “allocated” from both ends of an array by using a single designator:
int a[MAX] = {
1, 3, 5, 7, 9, [MAX-5] = 8, 6, 4, 2, 0
};
In the above, if MAX is greater than ten, there will be some
zero-valued elements in the middle; if it is less than ten, some of
the values provided by the first five initializers will be overridden
by the second five.
Example
#include <stdio.h>
#define MAX 12
int main(void)
{
// n2176, § 6.7.9(37)
int a[MAX] = {
1, 3, 5, 7, 9, [MAX-5] = 8, 6, 4, 2, 0
};
for (size_t i = 0; i < MAX; i++) {
printf("%d\n", a[i]);
}
return 0;
}
Output:
1
3
5
7
9
0 <-- middle element, defaults to zero
0 <-- middle element, defaults to zero
8
6
4
2
0
Related
This question already has answers here:
Why is char[][] = {{...}, {...}} not possible if explicitly given a multidimensional array?
(5 answers)
Array type has incomplete element type error in C [duplicate]
(1 answer)
Closed 1 year ago.
Why do we need the column size for
int arr[][] = { {1,2,3},{1,3,5} };//int arr[][3]
In this particular example, why can't the compiler deduce it from the data that it has to pack only 3 elements each into each row? Why is there a limitation on compiler for doing it?
I can understand if it was
int arr[][] = { 1,2,3,1,3,5 };
then the compiler has no information of how much data has to be packed into each row.
I read a similar question Why do we need to specify the column size when passing a 2D array as a parameter?. But it doesn't contain the answer.
Edit: To avoid confusion, I am talking about the exact format of data mentioned above.
What does prevent a compiler from deducing the size of column?
The C standard.
From the standard:
6.7.9 Initialization
The type of the entity to be initialized shall be an array of unknown size or a complete object type that is not a variable length array type.
So you can initialize "an array of unknown size" but you can't initialize "an array of unknown size of array of unknown size".
Because you may want the array size to be greater than it is deduced. Like
int arr[5] = {1, 2, 3}; // Last two elements are zero.
If you declare the array like
int arr[][] = { {1, 2, 3}, {1, 3, 5, 7} };
What should the compiler do, report the error, since it expects the array int array[][3], or make the array int array[][4]? This decision is left to be up to a human.
The 2-D arrays are flat in the memory. For example int arr[3][3] and int arr[9] have the same storage. Thus, it is allowed to initialize both vectors by one initializing lists, it can be considered as placing initializing list values directly to a flat memory:
#include <stdio.h>
#include <memory.h>
int main(void) {
int arr2d[3][3] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
int arr1d[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
printf("size: %d\n", sizeof(arr2d) == sizeof(arr1d));
printf("memcmp: %d\n", memcmp(arr2d, arr1d, sizeof(arr2d)));
return 0;
}
// size: 1
// memcmp: 0
Extending the above, all 4 functions bellow declare and initialize the same array int arr[3][3] differently:
#include <stdio.h>
void arr2_list2(void) {
int arr[3][3] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}};
printf("int arr[3][3] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}}:\n");
for (int i = 0; i < 3; ++i)
printf("%d %d %d\n", arr[i][0], arr[i][1], arr[i][2]);
return 0;
}
void arr2_list1(void) {
int arr[3][3] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
printf("int arr[3][3] = {0, 1, 2, 3, 4, 5, 6, 7, 8}:\n");
for (int i = 0; i < 3; ++i)
printf("%d %d %d\n", arr[i][0], arr[i][1], arr[i][2]);
return 0;
}
void arr2open_list2(void) {
int arr[][3] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}};
printf("int arr[][3] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}}:\n");
for (int i = 0; i < 3; ++i)
printf("%d %d %d\n", arr[i][0], arr[i][1], arr[i][2]);
return 0;
}
void arr2open_list1(void) {
int arr[][3] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
printf("int arr[][3] = {0, 1, 2, 3, 4, 5, 6, 7, 8}:\n");
for (int i = 0; i < 3; ++i)
printf("%d %d %d\n", arr[i][0], arr[i][1], arr[i][2]);
return 0;
}
int main(void) {
arr2_list2();
arr2_list1();
arr2open_list2();
arr2open_list1();
return 0;
}
// int arr[3][3] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}}:
// 0 1 2
// 3 4 5
// 6 7 8
// int arr[3][3] = {0, 1, 2, 3, 4, 5, 6, 7, 8}:
// 0 1 2
// 3 4 5
// 6 7 8
// int arr[][3] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}}:
// 0 1 2
// 3 4 5
// 6 7 8
// int arr[][3] = {0, 1, 2, 3, 4, 5, 6, 7, 8}:
// 0 1 2
// 3 4 5
// 6 7 8
Imaging int arr[][] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}}; is allowed, why would not int arr[][] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; be allowed then, but how can the compiler decide what a human means in the statement
int arr[][] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
int arr[1][9], or int arr[3][3], or int arr[9][1]?
Simple answer - in a declaration like
int arr[][] = { ... };
the element type is int [], which is an incomplete type, and you cannot declare an array where the element type is incomplete. The presence or absence of an initializer doesn’t change that. All an initializer can tell you is how many elements you have of the given element type; it can’t tell you what that element type is.
By contrast, in the declaration
int arr[] = { ... };
the element type is int, which is a complete type. You still need something in the initializer to determine the number of elements, but it’s not telling you how big each element needs to be.
That's because although the [][] syntax looks like array-of-arrays, in memory it is laid like 1-D array. If we imagine a 3x3 chessboard it would be laid out as {1A, 2A, 3A, 1B, 2B, 3B, 1C, 2C, 3C}. The only way to access it as 2-D is to address it as [row + column * columnsize].
Now it's clear that you MUST know the columnsize in order to even start thinking about accessing the elements of the array. Where is this columnsize parameter stored? The array is of type int (*)[3]. Columnsize is an integral part of the type as much as "t" is a part of int.
What are you asking for is auto type. The compiler would have to determine the entire type on its own. It's equivalent of wanting auto arr = 1; or auto arr = "foo";. C compiler doesn't deal in such tricks.
Notice that columnsize is entirely different creature than the length of an array. int arr[] = {1} is of exactly same type as int arr[] = {1,2,3} The compiler couldn't care less about the length (actual size in memory) of the array, not going out of bounds is entirely your responsibility. That's why one element could be left unspecified. Not because the compiler can figure it out, but because the compiler ignores it.
int arr[][2] = {1,2,3,4,5,6} is of entirely different type than int arr[][3] = {1,2,3,4,5,6}, even though they're same size in memory. To the compiler, they're like int[1] and char[4].
The {{},{}} is just a syntactic sugar to help YOU, not the compiler.
I have a sequence of arrays of numbers with 5 elements each, from 0 to 8, and I have to order than using that combination, I mean:
i=0, {0,0,0,0,0}
i=1, {0,0,0,0,1}
i=2, {0,0,0,0,2}
i=3, {0,0,0,0,3}
i=4, {0,0,0,0,4}
i=5, {0,0,0,0,5}
i=6, {0,0,0,0,6}
i=7, {0,0,0,0,7}
i=8, {0,0,0,0,8}
i=9, {0,0,0,1,1}
...
i=1285, {7,8,8,8,8}
i=1286, {8,8,8,8,8}
so if I give {0,0,1,1,2} to the function it's returns 7.
I thought about using the Combinatorial number system
but I'm missing something that I don't know what it is, the code below just doesn't work
#include <stdio.h>
#include <stdlib.h>
#define size 1287
int combination[9][5] = {
{0, 0, 0, 0, 0},
{1, 1, 1, 1, 1},
{2, 3, 4, 5, 6},
{3, 3, 6, 15, 21},
{4, 10, 20, 35, 56},
{5, 15, 35, 70, 126},
{6, 21, 56, 126, 252},
{7, 28, 84, 210, 462},
{8, 36, 120, 330, 792}
};
int getKey(int array[]){
int key=0;
int tempArray[9] = {0};
for(int i=0;i<5;i++){
tempArray[array[i]]++;
}
int j=0;
for(int i=0;i<9;i++){
if(tempArray[i]!=0){
while(tempArray[i]!=0){
array[j++] = i;
key += combination[i][5-j];
tempArray[i]--;
}
}
}
return key;
}
int main(){
int it[5];
for(it[0] = 0 ;it[0]<9;it[0]++){
for(it[1]=it[0];it[1]<9;it[1]++){
for(it[2]=it[1];it[2]<9;it[2]++){
for(it[3]=it[2];it[3]<9;it[3]++){
for(it[4]=it[3];it[4]<9;it[4]++){
printf("{%d %d %d %d %d} = %d\n",it[0],it[1],it[2],it[3],it[4],getKey(it));
}
}
}
}
}
return 0;
}
Obs: I'm using counting sort to keep the lexicographic order, in theory I will receive unsorted arrays.
I will give you the Answer I wrote for the previous version of this question which you posted yesterday and deleted. (And that's bad form, by the way.)
Let's call the binomial coefficient C(n, k) = n!/(k!(n-k)!)
The number of unordered strings of m letters drawn from an alphabet of s symbols is C(m+s-1, s-1). Let's call that D(m, s). In this case, D(5, 9) = C(5+9-1, 9-1) = C(13, 8) = 1287
Let's sort each string, then number them:
aaaaa 1
aaaab 2
aaaac 3
...
aaaai 9
aaabb 10
aaabc 11
...
If a string contains 5 a's, its number is D(5, 1) = C(5+1-1, 1-1) = C(5, 0) = 1.
If a string contains 4 a's, its number is 1 plus a number determined by the non-a letter, which goes up to D(1,8) = C(1+8-1,8-1) = C(8, 7) = 8. So they go up to 1+8=9.
If a string contains 3 a's, its number is 9 plus a number determined by the non-a letters, which goes up to D(2,8) = C(9,7) = 36, so 9+36=45.
If a string contains 2 a's, its number is in [46,165].
If a string contains 1 a, its number is in [166, 495].
If a string contains no a, its number is in [496, 1287].
So how about the string "aabgg"? It's number is (45)+(8)+(7)+(6)+(5)+(4)+(1)=76
No collisions, and the calculation of the index is O(sm(s+m)), which is not too bad for m=5 and s=9.
EDIT: to clarify, let's define
E(j, m, s) = D(0,s-1)+D(1,s-1)+...+D(m-j-1,s-1)
Suppose a string of m letters drawn from an alphabet of s symbols contains j of the first letter of the alphabet. There are E(j,m,s) strings in the catalogue before the first such string. For instance, before the first string that begins with exactly two a's ("aabbb"), there are E(2, 5, 9)=45 strings.
To get to "aabbb" we must count out 45 strings.
To get from "aabbb" to the next string that contains exactly one b ("aabcc"), we must count out E(1, 3, 8) = 8 strings.
From there to the next string that contains no c ("aabdd"), E(0, 2, 7) = 7 strings.
No d ("aabee"): E(0, 2, 6) = 6
No e ("aabff"): E(0, 2, 5) = 5
No f ("aabgg"): E(0, 2, 4) = 4
And we must count "aabgg" itself: 1
well, I think this look like oct number 1...8
0 = {00000}
1 = {00001}
2 = {00002}
8 = {00010}
if this what you mean
I think this algorithm is the best
int get_key(int a[5]){
int idx, rval=0;
for(i=4; i<=0; i--)
rval += powl(a[i], i);
return rval;
}
Given this array:
int a[] = {5, 8, 5, 6, 9, 5};
Would it be possible to remove all ints which equals 5 and move the rest the front of the array?
So that after the removal the array would look like this:
int a[] = {8, 6, 9, 0, 0, 0}
I don't know if by removing a element it becomes a 0 or a NULL?
Thanks!
You can do it with two iterations over the array, first iteration two to turn the element you want to delete, second iteration to separate zeros from non-zeros.
int a[] = {5, 8, 5, 6, 9, 5};
int n = 6;
for(int i = 0 ; i < n ; i++ ) {
if(a[i] == 5 ) {
a[i] = 0;
}
}
int* zero = a;
int* nonZero = a;
int j = 0;
while(j < n) {
while(*zero != 0) {
zero++;
}
while(*nonZero == 0) {
nonZero++;
j++;
}
if(zero < nonZero) {
*zero = *nonZero;
*nonZero = 0;
}
j++;
}
Your array is statically allocated, so always has the same size and deleted elements have the 0 value (according how you define the deleted values).
This link can help you and explains about how to delete element from array.
It is been awhile that i have programmed in C but it is posibble.
This is just a pseudo code, but you just need to change it to way of C programming.
int a[] = {5, 8, 5, 6, 9, 5};
int b[] = {5, 8, 5, 6, 9, 5}; // copy of array a to hold temp
for(int i = 0; i < Size of array; i++ ){
for(int j = i; j < Size of array; j++ ){
if(b[j] != 5){
a[i] = b[j];
a[j] = b[i];
break;
}
}
}
It will be like (▼: Target to swap, F: Finished, X: Not a targe to swap, N: Not processed):
▼, ▼, N, N, N, N
5, 8, 5, 6, 9, 5
F, ▼, X, ▼, N, N
8, 5, 5, 6, 9, 5
F, F, ▼, X, ▼, N
8, 6, 5, 5, 9, 5
Result:
8, 6, 9, 5, 5, 5
And remove 5s, it is quite different depends what you mean. If you do not change size of array then they can be 0 or undefined(null). So I think it differs by how you program the function that returns array.
your array is not dynamic so you just can't reduce its size after its been allocated.setting the value zero might solve the problem in your case.
int *a[4] = {
(int[]){ 1},
(int[]){ -4, -5},
(int[]){ -4, -5, 0},
(int[]){ 1, 3, 4, 6}
};
for (i = 0; i < 4; i++)
len = sizeof(a[i])/sizeof(int);
I know it is not a correct approach, but len is always 2. Could someone explain why len is two? Is it a undefined behavior, if not, how is it being calculated?
a[i] is pointer to int. sizeof(a[i]) will return sizeof int *, not the array it points to. On 64-bit machines, size of a pointer is 8 bytes and size of int is 4 bytes. 8/4 = 2.
I have an array of 10 elements, and I need to make that array into its moving average equivalent.
Using 3 elements each time (eg average of elements at indices 0-2, then 1-3 and so on up to indices from 10 then back to 0 and 1 to make the new array have exactly 10 elements as well).
What is the best approach to this without using pointers to wrap the array around (ring buffer).
Just do some bounds checking and wrap the index in code.
The example code below can be made more efficient, but it's written like this for clarity (sort of). Also there may be some minor mistake since I'm typing into StackOverflow rather than compiling it.
int array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int averages[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
for (int i = 0; i < 10; i++)
{
int a = i;
int b = i + 1 > 9 ? i - 10 + 1;
int c = i + 2 > 9 ? i - 10 + 2;
int count = array[a] + array[b] + array[c];
int average = count / 3; // note this will truncate any decimal part
averages[i] = average;
}