Given:
int x[10] = {1,2,3,4,5,6,7};
What's the difference between:
*(x+4) and (x+4) ??
*(x + 4) dereferences the fifth element of the array, which has value 4.
(x + 4) is the address of the fifth element of the array (which is the corresponding address of the value 4).
You can check what (x + 4) is, and why:
printf( "sizeof( int ) = %ld \n", sizeof( int ) );
printf( "x = %p \n", x );
printf( "(x + 4) = %p \n", (x + 4));
Sample output:
sizeof( int ) = 4
x = 0x7fff3c0e5fc0 # address of the first element
(x + 4) = 0x7fff3c0e5fd0 # address of the fifth element
Related
This is the code; and in this one a + c gives me result in digit, why? The output below. How the character is converted into a digit? And why 125 + 'c' = 212? Thank you in response!
#include <stdio.h>
int main()
{
int a = 125, b = 12345;
long ax = 1234567890;
short s = 4043;
float x = 2.13459;
double dx = 1.1415927;
char c = 'W';
unsigned long ux = 2541567890;
printf("a + c = %d\n", a + c);
printf("x + c = %f\n", x + c);
printf("dx + x = %f\n", dx + x);
printf("((int) dx) + ax = %ld\n", ((int) dx) + ax);
printf("a + x = %f\n", a + x);
printf("s + b = %d\n", s + b);
printf("ax + b = %ld\n", ax + b);
printf("s + c = %hd\n", s + c);
printf("ax + c = %ld\n", ax + c);
printf("ax + ux = %lu\n", ax + ux);
return 0;
}
Sample output:
a + c = 212
x + c = 89.134590
dx + x = 3.276183
((int) dx) + ax = 1234567891
a + x = 127.134590
s + b = 16388
ax + b = 1234580235
s + c = 4130
ax + c = 1234567977
ax + ux = 3776135780
This is the code; and in this one a + c gives me result in digit, why?
It gives you this output, as you 1) specified, that you want to print an integer (%d) and 2) If you add a char to an int, the result is an int.
How the character is converted into a digit?
Each character has an int value, ('A'=65,' '=32,...,See: https://en.wikipedia.org/wiki/ASCII)
And why 125 + 'c' = 212?
'c' has the ASCII-Value 87, and 125+87==212.
I am tracing a code but I don't understand how the values are being calculated. My question is on the comments beside the code.
I am tracing code and I understand all the parts except 2. I posted those 2 part below. I will be really glad if someone could help me.
#include <stdio.h>
int function1(int *m, int n)
{
*m = *m + n;
return(*m);
}
int function2(int n, int *m)
{
n = *m + 2;
return(n);
}
int main()
{
int x = 1, y = 3;
int *xptr = &x,*yptr = &y;
x = 1; y = 3;
y = function1(xptr,x);
printf("x = %d, Y = %d\n",x,y);//x=2 but why? shouldn't it be x=1? y=2
x = 1; y = 3;
x = function1(yptr,function2(2,yptr));
printf("x = %d, y = %d\n",x,y);//x=8 y=8 but why? shouldn't y=3?
return 0;
}
So, inside function1:
int function1(int *m, int n) {
*m = *m + n;
return(*m);
} /*
... */
y = function1(xptr,x);
n holds a copy of the value of x,
m holds a copy of the value of xptr, which is the address of x.
*m refers to the contents of the address held by m
...*m = *m + n
That's 'assign to the contents of the address of x: the contents of the address of x, plus the value of x'.
The contents of the address of x (aka it's value) is 1. So we assign 1 + 1 to the contents of address holding the value of x.
In the first printf, x == 2 because when calling function1 the first time *m is a pointer to x, so you assign to the location pointed by m (that is the location of x), *m + n == x + x == 1 + 1 == 2.
In the second printf, y == 8 because in function2 you return its value incremented by 2 (so 3 + 2 == 5) but without updating y, so in function1 you sum the resulting value of function2 to the old value of y (3 + 5 == 8). function1 return also that value, so also x == 8.
I need to pass Two Dimension array to a function as a single pointer. There are different types of approaches are there but due to some constraints(CodeGeneration), I want to pass a single pointer only. I have macros which contain the size of each dimension. I implemented the following way but I am not sure it will work fine for N dimensions also
#define size_1D 3
#define size_2D 3
void fun(int *arr)
{
int i,total_size = size_1D* size_2D;
for(i = 0; i < total_size ; i++)
{
int value = arr[i];
}
}
int main()
{
int arr[size_1D][size_2D] = {{1,2,7},{8,4,9}};
fun(&arr[0][0]);
}
Any loophole is there if I followed the above approach?
void fun(int (*arr)[3]);
or exactly equivalent, but maybe more readable:
void fun(int arr[][3]);
arr is a pointer to two dimensional array with 3 rows and 3 columns. arr decayed to a pointer has the type of a pointer to an array of 3 elements. You need to pass a pointer to an array of 3 elements. You can access the data normally, using arr[a][b].
#define size_1D 3
#define size_2D 3
void fun(int arr[][3])
{
for(int i = 0; i < size_1D ; i++) {
for(int j = 0; j < size_2D ; j++) {
int value = arr[i][j];
}
}
}
int main()
{
int arr[size_1D][size_2D] = {{1,2,7},{8,4,9}};
fun(arr);
}
You can specify the sizes as arguments and use a variable length array declaration inside function parameter list. The compiler will do some job for you.
#include <stdlib.h>
void fun(size_t xmax, size_t ymax, int arr[xmax][ymax]);
// is equivalent to
void fun(size_t xmax, size_t ymax, int arr[][ymax]);
// is equivalent to
void fun(size_t xmax, size_t ymax, int (*arr)[ymax]);
void fun(size_t xmax, size_t ymax, int arr[xmax][ymax])
{
for(int i = 0; i < xmax ; i++) {
for(int j = 0; j < ymax ; j++) {
int value = arr[i][j];
}
}
}
int main()
{
int arr[3][4] = {{1,2,7},{8,4,9}};
fun(3, 4, arr);
}
#edit
We know that the result of array subscript operator is exactly identical to pointer dereference operator of the sum:
a[b] <=> *(a + b)
From pointer arithmetic we know that:
type *pnt;
int a;
pnt + a = (typeof(pnt))(void*)((uintptr_t)(void*)pnt + a * sizeof(*pnt))
pnt + a = (int*)(void*)((uintptr_t)(void*)pnt + a * sizeof(type))
And that the array is equal to the value to the pointer to the first element of an array:
type pnt[A];
assert((uintptr_t)pnt == (uintptr_t)&pnt[0]);
assert((uintptr_t)pnt == (uintptr_t)&*(pnt + 0));
assert((uintptr_t)pnt == (uintptr_t)&*pnt);
So:
int arr[A][B];
then:
arr[x][y]
is equivalent to (ignore warnings, kind-of pseudocode):
*(*(arr + x) + y)
*( *(int[A][B])( (uintptr_t)arr + x * sizeof(int[B]) ) + y )
// ---- x * sizeof(int[B]) = x * B * sizeof(int)
*( *(int[A][B])( (uintptr_t)arr + x * B * sizeof(int) ) + y )
// ---- C11 6.5.2.1p3
*( (int[B])( (uintptr_t)arr + x * B * sizeof(int) ) + y )
*(int[B])( (uintptr_t)( (uintptr_t)arr + x * B * sizeof(int) ) + y * sizeof(int) )
// ---- *(int[B])( ... ) = (int)dereference( ... ) = *(int*)( ... )
// ---- loose braces - conversion from size_t to uintptr_t should be safe
*(int*)( (uintptr_t)arr + x * B * sizeof(int) + y * sizeof(int) )
*(int*)( (uintptr_t)arr + ( x * B + y ) * sizeof(int) )
*(int*)( (uintptr_t)( &*arr ) + ( x * B + y ) * sizeof(int) )
// ---- (uintptr_t)arr = (uintptr_t)&arr[0][0]
*(int*)( (uintptr_t)( &*(*(arr + 0) + 0) ) + ( x * B + y ) * sizeof(int) )
*(int*)( (uintptr_t)( &arr[0][0] ) + ( x * B + y ) * sizeof(int) )
*(int*)( (uintptr_t)&arr[0][0] + ( x * B + y ) * sizeof(int) )
// ---- decayed typeof(&arr[0][0]) = int*
*( &arr[0][0] + ( x * B + y ) )
(&arr[0][0])[x * B + y]
So:
arr[x][y] == (&arr[0][0])[x * B + y]
arr[x][y] == (&arr[0][0])[x * sizeof(*arr)/sizeof(**arr) + y]
On a sane architecture where sizeof(uintptr_t) == sizeof(size_t) == sizeof(int*) == sizeof(int**) and etc., and there is no difference in accessing data behind a int* pointer from accessing data behind int(*)[B] pointer etc. You should be safe with accessing one dimensional array when using a pointer to the first array member, as the operations should be equivalent ("safe" with exception for out-of-bound accesses, that's never safe)
Note, that this is correctly undefined behavior according to C standard and will not work on all architectures. Example: there could be an architecture, where data of the type int[A] are stored in different memory bank then int[A][B] data (by hardware, by design). So the type of the pointer tells the compiler which data bank to choose, so accessing the same data with the same to the value pointer, but with different pointer type, leads to UB, as the compiler chooses different data bank to access the data.
I am trying to understand the logic behind the printf numbers in the code below. Can someone explain how the valuables change? What symbol is executed first (|| , &&, != and so on)? In which direction is it executed?
#include <stdio.h>
static float w = 3.9;
short
f (short a, short *b)
{
a++;
(*b)++;
w++;
printf ("13: %d %d %4.2f\n", a, *b, w);
return a - *b;
}
int
main ()
{
short x, y, z, arr[] = { 4, 8, 0, 6 }, *p = arr;
char m[] = "dcrfvtgb", *pc;
y = 2;
z = 3;
x = (++y != z);
printf ("1: %d %d %d\n", x, y, z);
x = y = 6;
x *= (y = 5);
printf ("2: %d %d\n", x, y);
x = 0;
y = 2;
z = 7;
printf ("3: %d %d %d %d\n", !x || y && !z, x, y, z);
x = 5;
y = 3;
printf ("4: %d %d %d\n", x, y, x < y ? x : y);
y = 0;
if (y)
x = 7;
else
x = 5;
printf ("5: %d %d\n", x, y);
y = 8;
if (z = (y++ > 8))
x = 9;
else
x = 0;
printf ("6: %d %d %d\n", x, y, z);
x = y = 5;
while (y++ < 5)
x += y;
printf ("7: %d %d\n", x, y);
for (x = y = 5; y < 7; x = y++)
printf ("8:%d %d\n", x, y);
for (x = 2, y = 5; y >= 1; x++, y /= 3);
printf ("9: %d %d\n", x, y);
printf ("10: %d %d\n", p[2], *(arr + 1));
x = y = 3;
z = f (x, &y);
printf ("11:%d %d %d %4.2f\n", x, y, z, w);
for (x = y = z = 10; z-- > 9; x *= y);
printf ("12: %d %d %d\n", x, y, z);
for (pc = m; *pc; pc++)
(*pc)--;
printf ("14: %s %c\n", m + 2, *(m + 1));
return 0;
}
#abligh says "The C standard does not specify the order in which the arguments are evaluated."
As far as I know, the Intel implementation pushes the arguments right-to-left onto the stack, which means that the arguments are evaluated right-to-left.
printf ("12: %d %d %d\n", x, z, z++);
In this example the first value of z, when printed, will be one higher than the second value of z when printed.
The printf function takes a format string as the first argument, then zero or more other arguments. Each of the things beginning with % in the format string correspond to one of the other arguments. At least the way you are using it, these are in the same order, so the first % placeholder corresponds to to the second argument (i.e. the first after the format string), the second % placeholder to the next and so forth. The letter following the % (and sometimes other characters) describe the type of argument and how it is to be printed. See the manual page for printf() for more information.
Each of the arguments is evaluated before the call to printf. The C standard does not specify the order in which the arguments are evaluated. So if you have (e.g.), !x || y && !z as an argument, each of those will be evaluated prior to the call to printf(). For the order in which the components of those are evaluated, see operator precedence.
Note that that only tells you what order operators are evaluated in (i.e. in x + z * y, this says the z * y is evaluated before the +). It doesn't tell you whether x, y or z will be evaluated first; as they may be expressions themselves, that's important. So, for instance in:
int
f(int a, int b, int c)
{
return g(a) + h(b) * i(c);
}
in the general case you have no guarantee in which order g(a), h(b), and i(c) are evaluated. You only know the order in which the + and * are evaluated.
If you want to know more about evaluation order, you need to research sequence points.
so here is the code, till the 4th print out I easily followed it, but at the 5th print out, I don't understand
why its "5: a[0] = 200, a[1] = 128144, a[2] = 256, a[3] = 302 "?
I have commented the line in the code which I don't understand. I look forward to your response.
"#include <stdio.h>
#include <stdlib.h>
void
f(void)
{
int a[4];
int *b = malloc(16);
int *c = 0;
int i;
printf("1: a = %p, b = %p, c = %p\n", a, b, c);
c = a;
for (i = 0; i < 4; i++)
a[i] = 100 + i;
c[0] = 200;
printf("2: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]);
c[1] = 300;
*(c + 2) = 301;
3[c] = 302;
printf("3: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]);
c = c + 1;
*c = 400;
printf("4: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]);
//I DONT UNDERSTAND WHAT THIS LINE BELOW DOES
c = (int *) ((char *) c + 1);
*c = 500;
printf("5: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]);
b = (int *) a + 1;
c = (int *) ((char *) a + 1);
printf("6: a = %p, b = %p, c = %p\n", a, b, c);
}
int
main(int ac, char **av)
{
f();
return 0;
}
output:
1: a = 0x7fff65fdcb90, b = 0x1065007e0, c = 0x0
2: a[0] = 200, a[1] = 101, a[2] = 102, a[3] = 103
3: a[0] = 200, a[1] = 300, a[2] = 301, a[3] = 302
4: a[0] = 200, a[1] = 400, a[2] = 301, a[3] = 302
5: a[0] = 200, a[1] = 128144, a[2] = 256, a[3] = 302
6: a = 0x7fff65fdcb90, b = 0x7fff65fdcb94, c = 0x7fff65fdcb91
Let's start with the basics.
c is a pointer to an array of ints.
Let this be a:
[00000000][00000000][00000000][00000000]
Every two digits is a byte, and we assume that sizeof(int) is 4 in our example, so every element in a has 4 bytes, or 8 digits.
Now, c is a pointer to the first element in a.
Let's have a look at the expression in question:
c = (int *) ((char *) c + 1);
Obviously, c is changed here, but what exactly happens is:
c is cast from int* to char*
the result of the cast is incremented, resulting in sizeof(char) being added to c. Since sizeof(char) is 1, c is incremented by 1 and points to the second byte of an element in a.
the result is cast back to int*, and reassigned to c. This second cast is actually not needed.
So, ignoring all the other code, we start from this:
a : [00000000][00000000]...
^
c -|
And go to this:
a : [00000000][00000000]...
^
c ---|
As Daniel pointed out below, if c is not correctly aligned for a pointer of type int*, you get undefined behaviour, which should be avoided.
c is a pointer-to-int, so normally c+1 refers to the address which is sizeof(int) further along in memory - usually 4 bytes on a 32-bit system.
But you cast c to char* - that is, pointer-to-char. Now, char is only 1 byte long, so (char *)c + 1 refers to the memory location 1 byte further on than c; which is in the middle of the int at c.
You then cast the result back to an int* and write 500 into it. So what you're doing is (probably) writing the 4-byte representation of 500 over the last 3 bytes of a[1] and the 1st byte of a[2]. Exactly what effect that will have depends on the endianness of your system, but that's basically what's going on.