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

#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;
}

Related

Macro loops to create a large number of variables at pre-processing

I want to create a large number of declarations of static arrays, each with a different (static) size. I also want to be able to create an instance of all of them, and access them easily just with their ID. Can this be done with macros in C ?
i.e. I want to shorten this code
int array_1[SIZE_1];
int array_2[SIZE_2];
int array_3[SIZE_3];
int array_4[SIZE_4];
int array_5[SIZE_5];
int array_6[SIZE_6];
.
.
.
int array_40[SIZE_40];
and create this code (where the parts between <> are the ones I hope macros can do for me).
int StoreInArray(int array_id, int position, int value)
{
if(position < SIZE_<array_id>)
{
array_<array_id>[position] = value;
return 0;
}
else
{
return 1;
}
}
Of note : memory imprint is important. I really want to have each array be exactly the size that it must be, and no more - unless a cheap solution is offered.
The correct solution is likely to reconsider your overall program design and instead do something like this:
typedef struct
{
int* data;
size_t size;
} array_t;
const array_t array [40] =
{
{ some_array, 3 },
{ some_other_array, 5 },
...
};
A much worse idea is to implement an evil macro. It might look like this:
// NOT RECOMMENDED
#define StoreInArray(id,pos,val) (pos < SIZE_##id ? (array_##id[pos] = val,1) : 0)
Where the parameter id is an integer constant such as 1. Token concatenation then forms SIZE_1, array_1 etc as the macro is expanded.
This is written as a function-like macro only assigning to the array if pos is smaller than the array size. If so, the macro returns 1 otherwise 0. The comma operator is used inside the conditional operator ?: to achieve this.
Example:
#include <stdio.h>
#define SIZE_1 4
#define SIZE_2 2
#define SIZE_3 5
int array_1[SIZE_1];
int array_2[SIZE_2];
int array_3[SIZE_3];
#define StoreInArray(id,pos,val) (pos < SIZE_##id ? (array_##id[pos] = val,1) : 0)
int main(void)
{
if(StoreInArray(1, 3, 123))
{
printf("%d\n", array_1[3]); // prints 123
}
if(StoreInArray(1, 4, 123))
{
printf("%d\n", array_1[3]); // doesn't get executed
}
if(StoreInArray(3, 4, 456))
{
printf("%d\n", array_3[4]); // prints 456
}
}

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.

Initialize integer variable on typedef in C

I have a definition for int with my preferred name like so
Step 0 :
define array type of 128 elements
typedef int ishida_opcua_array[128];
and later i have a function to initialize the type ishida_opcua_array
void ishida_opcua_array_init(ishida_opcua_array array)
{
int i;
for(i = 0; i < 128; i++)
array[i] = -56565;
}
And finally; this is how i use the ishida_opcua_array type
Step 1 :
define an array of type ishida_opcua_array
ishida_opcua_array source_array;
Step 2 :
Initialize source_array with ishida_opcua_array_init() function
ishida_opcua_array_init(source_array);
/*
* Then i can do whatever i want with [source_array]
*/
How can i declare and initialize the array with the typedef, i want to be able to do
/*
* Define the variable and you are ready to go
* initialization has already been done while creating the variable
*/
ishida_opcua_array already_initialized_array; //already initialzed, ready to use
Please note in the first step, i had to first define the variable like so
ishida_opcua_array source_array;
then initialize the variable using below function
ishida_opcua_array_init(source_array);
ishida_opcua_array already_initialized_array = { 1, 2, 3 };
Of course, this would only initialise the first three members specifically and the rest to 0; you could use macros to generate your initialiser:
#define INIT_0 -56565 // well, prefer a better name...
#define INIT_1 INIT_0, INIT_0
#define INIT_2 INIT_1, INIT_1
up to INIT_7 and then have
ishida_opcua_array already_initialized_array = { INIT_7 };
Not going to judge if this really is better than your function...

How can I find the number of elements in an array?

I have an int array and I need to find the number of elements in it. I know it has something to do with sizeof but I'm not sure how to use it exactly.
If you have your array in scope you can use sizeof to determine its size in bytes and use the division to calculate the number of elements:
#define NUM_OF_ELEMS 10
int arr[NUM_OF_ELEMS];
size_t NumberOfElements = sizeof(arr)/sizeof(arr[0]);
If you receive an array as a function argument or allocate an array in heap you can not determine its size using the sizeof. You'll have to store/pass the size information somehow to be able to use it:
void DoSomethingWithArray(int* arr, int NumOfElems)
{
for(int i = 0; i < NumOfElems; ++i) {
arr[i] = /*...*/
}
}
int a[20];
int length;
length = sizeof(a) / sizeof(int);
and you can use another way to make your code not be hard-coded to int
Say if you have an array array
you just need to:
int len = sizeof(array) / sizeof(array[0]);
I personally think that sizeof(a) / sizeof(*a) looks cleaner.
I also prefer to define it as a macro:
#define NUM(a) (sizeof(a) / sizeof(*a))
Then you can use it in for-loops, thusly:
for (i = 0; i < NUM(a); i++)
It is not possible to find the number of elements in an array unless it is a character array. Consider the below example:
int main()
{
int arr[100]={1,2,3,4,5};
int size = sizeof(arr)/sizeof(arr[0]);
printf("%d", size);
return 1;
}
The above value gives us value 100 even if the number of elements is five.
If it is a character array, you can search linearly for the null string at the end of the array and increase the counter as you go through.
In real we can't count how many elements are store in array
But you can find the array length or size using sizeof operator.
But why we can't find how many elements are present in my array.
Because when we initialise an array compiler give memory on our program like a[10] (10 blocks of 4 size) and every block has garbage value if we put some value in some index like a[0]=1,a[1]=2,a[3]=8; and other block has garbage value no one can tell which value is garbage and which value is not garbage that's a reason we cannot calculate how many elements in an array. I hope this will help you to understand. Little concept
Super easy.
Just divide the number of allocated bytes by the number of bytes of the array's data type using sizeof().
For example, given an integer array called myArray
int numArrElements = sizeof(myArray) / sizeof(int);
Now, if the data type of your array isn't constant and could possibly change, then make the divisor in the equation use the size of the first value as the size of the data type.
For example:
int numArrElements = sizeof(myArray) / sizeof(myArray[0]);
This way, the code is type agnostic and will function correctly no matter the data type of the array.
I used following code as suggested above to evaluate number of elements in my 2-dimensional array:
#include <stdio.h>
#include <string.h>
void main(void)
{
char strs[3][20] =
{
{"January"},
{"February"},
{""}
};
int arraysize = sizeof(strs)/sizeof(strs[0]);
for (int i = 0; i < arraysize; i++)
{
printf("Month %d is: %s\n", i, strs[i]);
}
}
It works nicely. As far as I know you can't mix up different data types in C arrays and also you should have the same size of all array elements (if I am right), therefore you can take advantage of that with this little trick:
count number of bytes with sizeof() function from whole 2d array (in this case 3*20 = 60 bytes)
count number of bytes with sizeof() function from first array element strs[0] (in this case 20 bytes)
divide whole size with size of one element what will give you number of elements
This snipped should be portable for 2d arrays in C however in other programming languages it could not work because you can use different data types within array with different sizes (like in JAVA).
The question is simple: given a C++ array (e.g. x as in int x[10]), how would you get the number of elements in it?
An obvious solution is the following macro (definition 1):
#define countof( array ) ( sizeof( array )/sizeof( array[0] ) )
I cannot say this isn’t correct, because it does give the right answer when you give it an array. However, the same expression gives you something bogus when you supply something that is not an array. For example, if you have
int * p;
then countof( p ) always give you 1 on a machine where an int pointer and an int have the same size (e.g. on a Win32 platform).
This macro also wrongfully accepts any object of a class that has a member function operator[]. For example, suppose you write
class IntArray {
private:
int * p;
size_t size;
public:
int & operator [] ( size_t i );
} x;
then sizeof( x ) will be the size of the x object, not the size of the buffer pointed to by x.p. Therefore you won’t get a correct answer by countof( x ).
So we conclude that definition 1 is not good because the compiler does not prevent you from misusing it. It fails to enforce that only an array can be passed in.
What is a better option?
Well, if we want the compiler to ensure that the parameter to countof is always an array, we have to find a context where only an array is allowed. The same context should reject any non-array expression.
Some beginners may try this (definition 2):
template <typename T, size_t N>
size_t countof( T array[N] )
{
return N;
}
They figure, this template function will accept an array of N elements and return N.
Unfortunately, this doesn’t compile because C++ treats an array parameter the same as a pointer parameter, i.e. the above definition is equivalent to:
template <typename T, size_t N>
size_t countof( T * array )
{
return N;
}
It now becomes obvious that the function body has no way of knowing what N is.
However, if a function expects an array reference, then the compiler does make sure that the size of the actual parameter matches the declaration. This means we can make definition 2 work with a minor modification (definition 3):
template <typename T, size_t N>
size_t countof( T (&array)[N] )
{
return N;
}
This countof works very well and you cannot fool it by giving it a pointer. However, it is a function, not a macro. This means you cannot use it where a compile time constant is expected. In particular, you cannot write something like:
int x[10];
int y[ 2*countof(x) ]; // twice as big as x
Can we do anything about it?
Someone (I don’t know who it is – I just saw it in a piece of code from an unknown author) came up with a clever idea: moving N from the body of the function to the return type (e.g. make the function return an array of N elements), then we can get the value of N without actually calling the function.
To be precise, we have to make the function return an array reference, as C++ does not allow you to return an array directly.
The implementation of this is:
template <typename T, size_t N>
char ( &_ArraySizeHelper( T (&array)[N] ))[N];
#define countof( array ) (sizeof( _ArraySizeHelper( array ) ))
Admittedly, the syntax looks awful. Indeed, some explanation is necessary.
First, the top-level stuff
char ( &_ArraySizeHelper( ... ))[N];
says _ArraySizeHelper is a function that returns a reference (note the &) to a char array of N elements.
Next, the function parameter is
T (&array)[N]
which is a reference to a T array of N elements.
Finally, countof is defined as the size of the result of the function _ArraySizeHelper. Note we don’t even need to define _ArraySizeHelper(), -- a declaration is enough.
With this new definition,
int x[10];
int y[ 2*countof(x) ]; // twice as big as x
becomes valid, just as we desire.
Am I happy now? Well, I think this definition is definitely better than the others we have visited, but it is still not quite what I want. For one thing, it doesn’t work with types defined inside a function. That’s because the template function _ArraySizeHelper expects a type that is accessible in the global scope.
I don’t have a better solution. If you know one, please let me know.
#include<stdio.h>
int main()
{
int arr[]={10,20,30,40,50,60};
int *p;
int count=0;
for(p=arr;p<&arr+1;p++)
count++;
printf("The no of elements in array=%d",count);
return 0;
}
OUTPUT=6
EXPLANATION
p is a pointer to a 1-D array, and in the loop for(p=arr,p<&arr+1;p++)
I made p point to the base address. Suppose its base address is 1000; if we increment p then it points to 1002 and so on. Now coming to the concept of &arr - It basically represents the whole array, and if we add 1 to the whole array i.e. &arr+1, it gives the address 1012 i.e. the address of next 1-D array (in our case the size of int is 2), so the condition becomes 1000<1012.
So, basically the condition becomes
for(p=1000;p<1012;p++)
And now let's check the condition and count the value
1st time p=1000 and p<1012 condition is true: enter in the loop, increment the value of count to 1.
2nd time p=1002 and p<1012 condition is true: enter in the loop, increment the value of count to 2.
...
6th time p=1010 and p<1012 condition is true: enter in the loop, increment the value of count to 6.
Last time p=1012 and p<1012 condition is false: print the value of count=6 in printf statement.
sizeof returns the size in bytes of it's argument. This is not what you want, but it can help.
Let's say you have an array:
int array[4];
If you apply sizeof to the array (sizeof(array)), it will return its size in bytes, which in this case is 4 * the size of an int, so a total of maybe 16 bytes (depending on your implementation).
If you apply sizeof to an element of the array (sizeof(array[0])), it will return its size in bytes, which in this case is the size of an int, so a total of maybe 4 bytes (depending on your implementation).
If you divide the first one by the second one, it will be: (4 * the size of an int) / (the size of an int) = 4; That's exactly what you wanted.
So this should do:
sizeof(array) / sizeof(array[0])
Now you would probably like to have a macro to encapsulate this logic and never have to think again how it should be done:
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
You need the parentheses enclosing all the macro as in any other complex macro, and also enclosing every variable, just to avoid unexpected bugs related to operators precedence.
Now you can use it on any array like this:
int array[6];
ptrdiff_t nmemb;
nmemb = ARRAY_SIZE(array);
/* nmemb == 6 */
Remember that arguments of functions declared as arrays are not really arrays, but pointers to the first element of the array, so this will NOT work on them:
void foo(int false_array[6])
{
ptrdiff_t nmemb;
nmemb = ARRAY_SIZE(false_array);
/* nmemb == sizeof(int *) / sizeof(int) */
/* (maybe ==2) */
}
But it can be used in functions if you pass a pointer to an array instead of just the array:
void bar(int (*arrptr)[7])
{
ptrdiff_t nmemb;
nmemb = ARRAY_SIZE(*arrptr);
/* nmemb == 7 */
}
void numel(int array1[100][100])
{
int count=0;
for(int i=0;i<100;i++)
{
for(int j=0;j<100;j++)
{
if(array1[i][j]!='\0')
{
count++;
//printf("\n%d-%d",array1[i][j],count);
}
else
break;
}
}
printf("Number of elements=%d",count);
}
int main()
{
int r,arr[100][100]={0},c;
printf("Enter the no. of rows: ");
scanf("%d",&r);
printf("\nEnter the no. of columns: ");
scanf("%d",&c);
printf("\nEnter the elements: ");
for(int i=0;i<r;i++)
{
for(int j=0;j<c;j++)
{
scanf("%d",&arr[i][j]);
}
}
numel(arr);
}
This shows the exact number of elements in matrix irrespective of the array size you mentioned while initilasing(IF that's what you meant)
we can find number of elements in array only if array is declared in this format
int a[]={1,2,3,4,5,6};
number of element in array is
n=sizeof(a) / sizeof(a[0]);
we should no able to calculate array size if it is declared like this int a[10]={1,2,3,4,5,6}
i mostly found a easy way to execute the length of array inside a loop just like that
int array[] = {10, 20, 30, 40};
int i;
for (i = 0; i < array[i]; i++) {
printf("%d\n", array[i]);
}
If we don't know the number of elements in the array and when the input is given by the user at the run time. Then we can write the code as
C CODE:
while(scanf("%d",&array[count])==1) {
count++;
}
C++ CODE:
while(cin>>a[count]) {
count++;
}
Now the count will be having the count of number of array elements which are entered.
Assuming you have an array with elements 1,3,4.
To know its length, you'd need to use the sizeof function as follows:
int myArray[] = {1,3,4};
int len = sizeof(myArray) / sizeof(myArray[0]);
You can check the number of elements by printing the output as follows:
cout<<"This array has " << len << " elements";
The full program would be as follows:
#include <iostream>
using namespace std;
int main()
{
int myArray[] = {1,3,4};
int len = sizeof(myArray) / sizeof(myArray[0]);
cout<<"The array has " << len << "elements";
return 0;
}
Actually, there is no proper way to count the elements in a dynamic integer array. However, the sizeof command works properly in Linux, but it does not work properly in Windows. From a programmer's point of view, it is not recommended to use sizeof to take the number of elements in a dynamic array. We should keep track of the number of elements when making the array.

Resources