let consider the following fragment of Code:
#include<stdio.h>
main()
{
int count[100][10];
*(count + (44*10)+8)=99;
printf("%d",count[44][8]);
}
What is the wrong with it?
Array-to-pointer decay only works for one level; so int count[100][10]; decays to int (*)[100] (Why does int*[] decay into int** but not int[][]?).
You can either cast count to int* or use &count[0][0] to get an int* pointer to the first element of the 2D array.
count[44][8]
is not initialized and you are trying to print the value of it which is UB.
a[i][j] = *(a[i] + j);
a[i][j] = *(*(a+i) + j);
So if you want to initialize count[44][8] then do
*(count[44] + 8) = 10; /* or *(*(count + 44) + 8) = 10 */
printf("%d",count[44][8]);
*(count + (44*10)+8)=99; should be
*(count[0] + (44*10)+8)=99;
Type of countp[0] can be reinterpreted as int * as you want.
Live code here
Type of count is int [100][10] so adding some big number to it would go 10 times ahead as you want and access to that location would lead to UB.
Anopter way to write the same is:
*( *(count + 44) + 8 )=99;
Related
Working with pointers and arrays in C I've found a curious case which I don't understand why it occurs.
First, I want to describe correct case:
I've defined a function void modifyArray(int *list) where the array must be modified by reference to multiply items by 2 times (x2). Function implementation is:
void modifyArray(int *list, int arrLength){
for(int i=0; i<arrLength; i++){
*(list + i) = *(list + i) * 2; // x = x * 2
}
}
int main(int nargs, char **args) {
int list[] = {1,2,3,4,5};
modifyArray(&list, 5);
for(int i=0; i<5; i++){
printf("%d\n", *(list + i));
}
}
Output is:
2
4
6
8
10
Now I'm going to explain the incorrect case: I've defined a new data type List and modified the function to accept List instead of int * or int[] as first parameter:
typedef int List[5];
void modifyArray(List *list, int arrLength){
for(int i=0; i<arrLength; i++){
*(list + i) = *(list + i) * 2; // x = x * 2
}
}
After modification my compiler build fails because the sentence *(list + i) = *(list + i) * 2; // x = x * 2 can't multiply bacause of the following error message:
Invalid operands to binary expression ('List' (aka 'int [5]') and 'int')
I know my compiler is trying to multiply the complete array by 2, but don't know the reason.
The solution I've found is replacing *(list + 1) by *(*list + 1). I'm confused because of in second case, when I print list and *list output is a memory address (same memory address for both) instead of a memory address for list and its content for *list.
Can you explain why this is happening and what is the difference by using int * and List defined type?
When list is defined with int list[] = {1,2,3,4,5};, &list is a pointer to an array of five int. It is not appropriate to pass this for a parameter of type int *, and the compiler should have issued a warning or error for that in the first code. The proper argument would be list. Although that is an array, it will be automatically converted to a pointer to its first element, and that pointer is an int *, which is the correct type for the parameter.
When the parameter is declared as List *list, it is a pointer to an array. Then, in *(list + i), the addition is done in units of those arrays, not units of int. The result of the addition is a pointer to an array, so the result of the * in *(list + i) is an array. Then the multiplication is trying to multiply an array by two, so the compiler complains.
Instead, declare the parameter as List list. This declares it to be an array, but it will be automatically adjusted to be a pointer to an int. Because C does not support passing arrays as parameters, it automatically adjusts a declaration of a parameter as an array to be a declaration of a pointer to an array element instead, which is supported.
Also, do not write *(list + i). Use list[i]. It means the same thing but is easier to read.
I'm having trouble in C with creating a pointer that points to an array of pointers where each pointer in the array points to an array. I'm having trouble setting this up and storing values in each array. The goal is to avoid array indexing and use pointer arithmetic only. An example of how to implement this idea correctly and storing the values for access later would help me greatly to understand pointers to functions, pointers to arrays, and pointer arithmetic. I do know how to use malloc and calloc. I know basic pointers but this problem is more advanced so some examples of how this is implemented would help greatly! Thanks! :)
From your description it sounds as if you need something like:
#include <stdio.h>
int main(void) {
// Make some arrays of ints
int a0[3] = {1, 2, 3};
int a1[3] = {4, 5, 6};
// To access element a1[2] do *(a1 + 2)
printf("%d\n", *(a1 + 2));
// Make an array of int pointers
int* b[2] = {a0, a1}; // Or: int* b[2];
// *(b + 0) = a0;
// *(b + 1) = a1;
// To access element a1 do *(b + 1)
// To access a1[1] through b just combine the two expressions
// so that you have *(*(b + 1) + 2)
printf("%d\n", *(*(b + 1) + 2));
return 0;
}
In general: To access b[i][j] do *(*(b + i) + j)
If I have this array:
#define a 10
#define b 20
int foo[a][b];
I could get the pointer to foo[i][j] like this:
int *pointerToElement(i, j)
{
return *foo + i * b + j;
}
Isn't there an easier way using index notation (*foo[i][j])?
How about this:
return & foo[i][j];
Your method is wrong:
*foo + i * b + j
This dereferences the pointer foo and adds something to its value. What you want is:
foo + i * b + j
And since the index notation also dereferences the pointer, you have to reference it again:
&foo[i][j]
So I have the following code snippet:
#include <stdio.h>
void pointer_shift(int *a, int n);
int main(void) {
int a[] = {100, 101, 102};
pointer_shift(a1, 3);
}
void pointer_shift(int *a, int n) {
int i;
for (i = 0; i != n - 1; i++) {
*(a + i) = *(a + i + 1);
}
}
I just want to clarify how the pointers work in this snippet. So pointer_shift takes in 'a', a pointer to an int, correct? a1 is passed in to this parameter, and since arrays decay to a pointer to their first element, it works.
First of all, hopefully what I said in the above paragraph is correct. Secondly, what does *(a + i) = *(a + i + 1); actually do? Say we're on the first iteration of the for loop, and i = 0. Then the left side, *a, accesses what, exactly? Does it represent a pointer? I thought * was the dereferencing operator, and accesses the object that a pointer points to... And so then it sets *a = *(a + 1). (a + 1) is the next element in the array, but what exactly does this assignment do, and why?
Thanks!
It is actually not pointer shift, but value shift, *(a+i) is of same effect as a[i], so what it does is a[i] = a[i+1]
*(a + i) = *(a + i + 1); is copying array elements within the array using a bit of pointer arithmetic.
*(a + i) is equivalent to a[i], so the statement is equivalent to a[i] = a[i + 1];. The loop is moving the array values "to the left" in the array: a[0] = a[1]; a[1] = a[2]; and so on.
Your understanding of the function call is correct.
I just want to clarify how the pointers work in this snippet. So pointer_shift takes in 'a', a pointer to an int, correct? a1 is passed in to this parameter, and since arrays decay to a pointer to their first element, it works.
Yes, when you pass an array to a function it degrades to a pointer. An array is not a pointer in an object sense, but it is a pointer in a value sense. When you pass it to a function its value is passed, i.e., a pointer to the first element.
array indexing is the same as pointer arithmetic, so the last two lines in this snippet are equivalent:
int arr[] = {1, 2, 3};
arr[0] = 10;
*arr = 10;
as are these:
arr[1] = 20;
*(arr + 1) = 20;
The expression a + i is pointer arithmetic, incrementing the memory address stored in a by i units of the pointer size of a. So if a pointer to an int takes four bytes on your system, and if the current memory address is, say, 0x1234 the value of a + 1 would be 0x1238.
What the asterisk does is dereference that address and access the actual value at that address. If you have 100 stored at a or a[0], and 101 stored at a + 1 or a[1], then *(a + i) = *(a + i + 1) replaces 100 with 101 at a[0], for i = 0.
Basically, you want to read this C tutorial on pointers and arrays.
Why the last printf in the main function doesn't print to the screen the value 10?
I know that in ANSI C, statically allocated matrix are arranged in memory in this way:
matrix: matrix[0][0], matrix[0][1],...,matrix[0][ColumnsDimension-1],matrix[1][0], etc
#include <stdio.h>
#include <stdlib.h>
#define dimRighe 20
#define dimColonne 30
int main()
{
int matrice[dimRighe][dimColonne];
int i,j;
for(i=0;i<dimRighe;i++)
for(j=0;j<dimColonne;j++)
matrice[i][j] = i+j;
matrice[0][3] = 10;
i = 0; j = 3;
printf("%d",*matrice[i*dimColonne+j]);
return 0;
}
Use *(matrice[i * dimColonne] + j) instead.
Why the last printf in the main function doesn't print to the screen the value 10?
Because matrice is an array of arrays ...
and matrice[whatever] is an array (which in most circunstances "decays" to a pointer to its first element)
and *matrice[whatever] is the contents of the first element of the array matrice[whatever].
In your code you have:
matrice[i*dimColonne+j]
Since i is 0 this evaluates to
matrice[j]
Since j is 3 this means
matrice[3]
When you print *matrice[3] that is equivalent to printing matrice[3][0] because matrice[3] is an array. And an array decays to a pointer to its first element.
But you don't want to do it this way at all. You should simply write matrice[i][j] and let the compiler do the work.
Change
printf("%d",*matrice[i*dimColonne+j]);
to simply be
printf("%d", matrice[i][j]);
if all you're worred about is printing out the right value. After all, that's how you assigned it.
If you're doing this as an exercise to understand how array subscripting works, then there are several things you need to remember.
First, except when it is the operand of the sizeof or unary & operators, or is a string literal being used to initialize another array in a declaration, an expression of type "N-element array of T" will be replaced with ("decay to") an expression of type "pointer to T", and its value will be the address of the first element of the array. The expression matrice is an array expression of type "20-element array of 30-element array of int"; in most circumstances, it will be converted to an expression of type "pointer to 30-element array of int", or int (*)[30]. Similarly, the expression matrice[i] is an expression of type "30-element array of int", and in most cirumstances it will be converted to an expression of type "pointer to int", or int *.
Here's a handy table to remember all of this:
Declaration: T a[N];
Expression Type Decays to
---------- ---- ---------
a T [N] T *
&a T (*)[N]
*a T
a[i] T
Declaration: T a[M][N];
Expression Type Decays to
---------- ---- ---------
a T [M][N] T (*)[N]
&a T (*)[M][N]
*a T [N] T *
a[i] T [N] T *
&a[i] T (*)[N]
*a[i] T
a[i][j] T
Second, the subscripting operation a[i] is defined as *(a + i); that is, you compute an address based on i number of elements (NOT BYTES) from the base address of your array and dereference the result. For example, if a is an array of int, then *(a + i) will give you the value of the i'th integer after a. If an is an array of struct foo, then *(a + i) will give you the value of the i'th struct after a. Pointer arithemtic always takes the size of the base type into account, so you don't need to worry about the number of bytes in the offset.
The same logic applies to multidimensional arrays, you just apply the rule recursively for each dimension:
a[i][j] == *(a[i] + j) == *(*(a + i) + j)
a[i][j][k] == *(a[i][j]+ k) == *(*(a[i] + j) + k) == *(*(*(a + i) + j) + k)
Note that you should almost never have to do these dereferences manually; a compiler knows what an array access looks like and can optimize code accordingly. Under the right circumstances, writing out the dereferences manually can result in slower code than using the subscript operator.
You can index into a 2-d array as if it were a 1-d array like so:
a[i*rows + j] = val;
but I wouldn't (the types of the expressions don't match up cleanly). Note that you multiply i by the number of rows, not columns.
You could also print it like this:
char *matrixAsByteArray = (char *) matrice;
char *startIntAddr = matrixAsByteArray + i * dimColonne * sizeof(int) + j * sizeof(int);
int outInt = *startIntAddr | *(startIntAddr + 1) << 8 | *(startIntAddr + 2) << 16 | *(startIntAddr + 3) << 24;
printf("%d", outInt);
What this does is first, it converts your matrix to an array of bytes, then, it gets the starting address of the integer you need, and then it reconstructs the integer from the first four bytes read from that address.
This is a bit overkill, but a fun solution to the problem.