With an array of a certain type of element. Is there a way to use lfind to retrieve the index of an element instead of a pointer to the element?
You have that with the pointer.
Subtract the start of the array from the returned pointer - that's the index.
Edit to explain more, just in case:
When you declare an array
int foo[5];
foo without an index is a pointer to the first element
foo == &foo[0]
So if I have a pointer to an element in the array
int *p = &foo[4];
I can get the index with:
int index = p - foo;
Related
I have the following code :
int allocationMatrix[2+ 1][1+ 1];
allocationMatrix[0][0] = 2;
allocationMatrix[0][1] = 1;
buildAllocationMatrix(flowNProcess, allocationMatrix);
The buildAllocationMatrix function is declared like:
void buildAllocationMatrix(FlowNProcess *flowNProcess, int *allocationMatrix)
inside it, if I check the value of *(allocationMatrix+1), it gives 0 but the assignment
before calling the function is allocationMatrix[0][1] = 1; Not sure why its giving 0
It should return 1. What could be the reason for this?
Pass int **allocationMatrixinside function since it is 2D array.
(becauseint *allocationMatrix is interpreted as passing address of 1D array) .
And access it by
*(*(allocationMatrix+0)+1).
(Reason: by using*(allocationMatrix+0) you will get address of 0th row and in order to get address of 0th row 1st column we can use (*(allocationMatrix+0)+1) thus to get element of that position dereference it as
*(*(allocationMatrix+0)+1) ).
While accessing you can skip zero.
I try to create an array of int in C, and then, use it in a custom function :
int a[] = {1,3,5,7,9};
int* new_a = extract(a, 2, 4);
// ...
int *extract(int* T, int a, int b){
int lenght_T = getLenghtOfSimpleArray(T);
...
}
I use the IDE visual code, when I inspect the code through the degugger, I get :
I don't understand why, in the debugger, the value of T is not {1,3,5,7,9}...
Where is my mystake ?
When you pass an array to a function it gets degraded to a pointer that points to the first element of the array. That means, T is an address in memory, so the big hex value shown in the debugger looks normal.
The debugger also shows *T, which is the value where the pointer points to, i.e. the first element of the array. The value is 1 as expected.
There is no way to find out the size/length of an array passed to a function this way, so it is not possible to make a working function getLenghtOfSimpleArray, except if you define an "invalid" value (sentinel value) which must be put to the last element of the array. In the general case, the caller must pass the size of the array to the function in addition to the array name = pointer to the first element.
example code with passing the array length
int a[] = {1,3,5,7,9};
int* new_a = extract(a, sizeof(a) / sizeof(a[0]), 2, 4);
int *extract(int* T, size_t length, int a, int b){
int lenght_T = getLenghtOfSimpleArray(T);
...
}
Arrays are not pointers. Pointers are not arrays.
T is not an array, it's a pointer to the first element. As you can see from your debugger, *T is 1, which is that first element.
Most debuggers support watches such as T[1] etc if you wish to inspect individual items beyond the first. Or they have a "range" feature that allows you to view a number of items.
In C, arrays are just values in the memory right next to each other, and the pointer only points to the first entry.
So in your case if you want to access the other values you have to access them with T[index]
The debugger only shows the first value of the array in this case.
In C:
When a struct is sent (via a parameter) by value in to a function, a new struct is created, so changing the structure inside the function won't change the original structure.
When an array is sent (via a parameter) by value in to a function, a new pointer is created, so changing the array inside the function won't change the original array, but changing array values inside the function (since we have the pointer to the original array) will change the values in the original array.
When a struct with an array field is sent (via a parameter) by value in to a function, ????? is created, so that changing the array (pointer) inside the function won't change the original array and changing array values won't change the values in the original array.
Does the third point mean that an array field of a struct, when sent in to a function will be entirely cloned? Why isn't just the pointer used instead? What does the specification say about it?
A piece of code that I've played with:
typedef struct {
int value;
int array[3]; /* initialized to 0 by default */
} Struct_t;
void foo(Struct_t structure)
{
printf("-- %p\n", structure.array); /* Pointer to local array */
structure.value = 1;
*structure.array = 1; /* Won't change the original array */
*(structure.array + 1) = 1; /* Won't change the original array */
structure.array[2] = 1; /* Won't change the original array */
}
int main()
{
Struct_t s = { .value = 0 };
foo(s);
printf("-- %p\n", s.array); /* Pointer to original array */
printf("%d\n", s.value);
printf("%d\n", s.array[0]);
printf("%d\n", s.array[1]);
printf("%d\n", s.array[2]);
}
Output:
-- 0x7ffe8f17d194
-- 0x7ffe8f17d1b4
0
0
0
0
OP's "When an array is sent ..." needs clarification.
When an array is sent (via a parameter) by value in to a function, a new pointer is created, so changing the array inside the function won't change the original array, but changing array values inside the function (since we have the pointer to the original array) will change the values in the original array. (OP)
When an array, like s[] below, is passed to strcpy(char *s1, const char *s2), a conversion occurs first. The object s is converted to the address of the first element of the array. strcpy() does not receive s[] as the s1 parameter, instead it receives a copy of the value of of &s[0].
char s[6] = "Hello";
strcpy(s, "World");
Within strcpy(), s1 is not an array. s1 is a pointer to a char. strcpy() has no concept of "changing the array inside the function" as the function does not know s1 points to array memory, allocated memory or anything else. strcpy() understands s1 points to a char.
Does the third point mean that an array field of a struct, when sent in to a function will be entirely cloned?
Yes. When an object is passed to a function in C, it is potentially converted and then passed by value. It is much like any assignment. The contents of the object, after conversion is copied to the destination. It makes no difference, after conversion, if the object is a struct, union, int, double, void*, int(*)() etc or a struct containing an array.
int a;
double b;
a = 5; // 5 is copied to a
b = a; // a is converted to double and copied to b
char s[6] = "Hello";
char *e;
void *v;
e = s; // s is converted to the address on the first array element and then copied to e
v = e; // e is converted to a `void*` and then copied to v
Struct_t f = {0};
Struct_t g;
g = f; // f is copied to g
Does the third point mean that an array field of a struct, when sent in to a function will be entirely cloned?
Yes.
Why isn't just the pointer used instead?
Because there is no pointer. An array is not a pointer. (More on this here.)
In C everything is pass-by-value.
When we pass-by-value we are passing a copy of the variable to a function.
When we pass-by-reference we are passing an alias of the variable to a function.
It is copying the value of the pointer, the address, into the function.
If a struct is passed by value to a function the bytes of the
struct are copied as the function parameter. Anything done to that
struct within the function changes the copy, not the original
struct
A struct is a predefind structure of memory, that has a certain memory layout. By adding an array to the struct the actual memory of the array is located in the struct not a pointer. That is why it has to be copied with the rest of the struct.
Arrays are not pointers, an arrays has a specific unchangable memory location, while a pointer can point anywhere you want.
Given a struct Element:
typedef struct {
char someString[9]
int value;
} Element
and an array elementList:
Element elementList[5];
is there an easy way to dynamically add an Element to each index of the list? I have tried creating a function add_element that takes in the list and modifies it there but I'd prefer something equivalent to Java's elementList[i] = new Element.
There's no need, that array consists of structure instances.
You can do e.g.:
strcpy(elementList[0].someString, "foo");
elementList[0].value = 4711;
This is not possible in Java, where everything is a reference, but in C you can do this. If you want a bunch of NULL-able references, in C you use pointers:
Element *elementList[5]; /* An array of 5 pointers to type Element. */
Then you have to use e.g. heap allocations to make sure there is memory before accessing the Element:
elementList[0] = malloc(sizeof *elementList[0]); /* This might fail! */
elementList[0]->value = 17;
As declared, you've created a 5-element array of Element instances; there's no need to allocate new Element objects. You can go ahead and read/assign each member of each element:
element[i].value = some_value();
strcpy( element[i].someString, some_string() );
If you want to emulate the Java method, you'd do something like the following:
Element *elementList[5]; // create elementList as an array of *pointers* to Element
...
elementList[i] = malloc( sizeof *elementList[i] ); // dynamically allocate each element
Note that in this case, you'd use the -> operator instead of the . operator to access each Element member, since each elementList[i] is a pointer to Element, not an Element instance:
elementList[i]->value = some_value();
strcpy( elementList[i]->someString, some_string() );
In either case, the array size is fixed; you cannot grow or shrink the number of elements in the array.
I wrote a function that returns a pointer to a 1D array. The function prototype is:
double* NameFunction (int,double*,double*)
The function seems to work fine with 1D array.
Here's the question: I'd like to use the function to fill one row of a 2D array.
How do I write in the calling function a pointer to the row of the 2D array to fill?
Can I use the same pointer structure to indicate a row of a 2D array as argument?
Yes just pass the name of the 2D array with the first index filled in:
NameFunction (12121212,&array[0],some pointer here) // for example if you want to pass the first row
A variable pointing to an array in C always contains just an address location i.e., the pointer to the starting of the array. So, whatever the array type, it just needs a pointer which is a *.So this function should work as it is now.
But you may need to change some programming logic.
You can take double foo[20] as 1×20 array, or you can take it as two-dimensional 4×5 array. Then you have the coordinates like this:
foo foo+1 foo+2 foo+3 foo+4
foo+5 foo+6 foo+7 foo+8 foo+9
foo+10 foo+11 foo+12 foo+13 foo+14
foo+15 foo+16 foo+17 foo+18 foo+19
So if you have a function that returns double *, you can pass it (or make it return) foo + 5*n to point at row n.
#define ROW_LEN 5
#define ROWS 4
void fillRow(double * row)
{
int i;
for (i = 0; i < ROW_LEN; i++)
{
row[i] = 12;
(row + i) = 12; // this is the same thing written differently
}
}
double arr[ROW_LEN * ROWS];
fillRow(arr + 2 * ROW_LEN); // fill third row
Note that C does not do any range checking at all, so if you are not careful and accidentally to something like arr[627] = 553 somewhere in your code, it's going to blindly overwrite everything that is at the computed address in the memory.