Adding two numbers without using + - c

I have this code which does the trick:
#include <stdio.h>
int main()
{
int a = 30000, b = 20,sum;
char *p;
p=(char *)a;
sum = (int)&p[b]; // adding a & b
printf("%d",sum);
return 0;
}
Can someone please explain what is happening in the code?
p = (char*)a;
sum = (int)&p[b]; // adding a & b

&p[b] is basically sugar for:
&*(p + b)
The * and & operators are inverse operations here and cancel, leaving simply p + b. The casts just circumvent C's type checking. The fact that a char * pointer is used is signficant, however; C scales pointer arithmetic, and since sizeof(char) == 1 by definition, the scaling factor is 1.

I think it is worth adding to the other answers a quick explanation of pointers, arrays and memory locations in c.
Firstly arrays in c are just a block of memory big enough to hold the number of items in the array (see http://www.cplusplus.com/doc/tutorial/arrays/)
so if we said
int[5] example;
example[0] = 1;
example[1] = 2;
example[2] = 3;
example[3] = 4;
example[4] = 5;
Assuming int is 32 bits we would have a block of memory 5*32bits = 160bits long.
As C is a low level language it tries to be as efficient as possible, therefor stores the least amount of information about arrays as possible, in this case the least amount possible is the memory address of the first element. So the type of example could be expressed as
int *example;
Or example points to an int. To get the items in the array you then add the correct number to the address stored in example and read the number at that memory address.
If we assumed memory look like
Memory Address = Value (ints take up 4 bytes of space)
1000 = 1 <-- example
1004 = 2
1008 = 3
1012 = 4
1016 = 5
So
int i = example[3]; //The 4th element
could be expressed as
int i = *(example + 3 * sizeof(int));
int i = *(example + 3 * 4);
int i = *(1000 + 12);
int i = *(1012); // Fetch the value at memory location 1012
int i = 4;
The sizeof(int) is 4 (int is 32 bits, or 4 * 8 bit bytes). If you where trying to do addition you would want a char which is 8 bits or 1 * 8 bit bytes.
So back to you code
char* p; // declare p as a pointer to a char/
p = (char *)a; // point p at memory location 3000
// p[b] would be the 21st element of the "array" p =>
// p[20] =>
// p + 20 * sizeof(char) =>
// p + 20 * 1 =>
// p + 20 =>
// 3000 + 20 =>
// 3020
// the & operator in c gets the address of the variable so
sum = (int) &p[b];
// &p[b] => find the address pointed to by p[b] => 3020
// (int) casts this pointer to a int.
So sum is assigned the address of the 21st element of the array.
Long winded explanation.

p[b] returns the b-th element of the array p, which is equivalent to *(p + b). &p[b] equals to p + b*sizeof(char) that is converted back to int.

If the question was "adding two numbers without the + operator", here is one:
#include <stdio.h>
int main()
{
int a=5, b=7;
int a1=a, b1=b;
int res;
res = (++a1 * ++b1) - (a * b) -1;
printf("a1=%d b1=%d res=%d\n", a1, b1, res );
return 0;
}

Related

C code, pointers and their content. Exam question [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I have this code from an old exam.
The first print generates 5a9b1740.
And the question is what does the second print generate.
x: unknown since we do not know what *k holds.
y: 35.
z: ffff ffff. WHY?
p: 5c9b1748. WHY?
{
int x = 4;
int y = 15;
int *k = &x;
int z;
int *p;
*k = *k * (*k + 1);
y = x + y;
k = &z;
int a[] = {7,9,3,8};
p = a;
printf("%x\n",(unsigned int)p);
x = *k + 1;
p = p + 2;
z = *p - 4;
printf("%d %d %x %x\n",x,y,z,(unsigned int)p);
}
Edit: Sorry for causing confusion, the first print is 5a9b1740 and second 5c9b1748. Not 5a9b1740,5c961748. Question is edited on that regard.
x: unknown since we do not know what *k holds.
Technically, the value of *k when x = *k + 1; was executed is indeterminate since it points to z and z was uninitialized at that time. This means the value is either unspecified (i.e. it can have any value) or a trap representation (i.e. it doesn't represent a valid value and can trigger a fault if read). If the value happens to be a trap representation then reading invokes undefined behavior.
In some cases reading an uninitialized variable can still be undefined even if it is not a trap representation, however that is not the case here because z had its address taken.
y: 35.
At this point:
*k = *k * (*k + 1);
y = x + y;
k points to x and 4 has the value 4, so the first line is the same as x = 4 * (4 + 1). This sets x to 20, then adding that to the current value of y (15) gives 35.
z: ffff ffff. WHY?
p: 5c9b1748. WHY?
Looking at these lines:
p = a;
p = p + 2;
z = *p - 4;
This first points p to the first element of a, and that pointer has value 5a9b1740 as in the first printf. The next line then points it to 2 elements after that one. Assuming an int is 4 bytes on your system, that means the raw value of the pointer p increased 2 * 4 = 8. So the value of p is now 5a9b1740 + 8 = 5a9b1748.
With p now pointing to the third element of a which has the value 3, the following line sets z to -1. This value is then printed with the %x format specifier which interprets the value as an unsigned int and prints it in hex. Assuming two's complement representation of negative numbers an (again) a 4 byte int, this value has the representation ffffffff. When read as an unsigned int is is this that is printed.
p.s. no 3:
It comes out that, the addresses given in the question are not the actual outcome of a program execution but example values given with the assignment text. So, there is a possible typo: either both addresses would start with 5c9b... or both w/ 5a9b....
p.s. no 2:
Please refer to the comments as well. Just checking the last 2 ~ 4 digits of the addresses, I overlooked the weird address gap b/w the 1st & 2nd results of the print lines.
Let's go line by line:
Line 1:
int x = 4; // x is defined and set to value 4
Line 2:
int y = 15; // y is defined and set to value 15
Line 3:
int *k = &x; // pointer k is set to point x
Line 4:
int z; // z is defined but uninitialized
Line 5:
int *p; // pointer p is defined but uninitialized
Line 7:
*k = *k * (*k + 1);
// k was set to point x (above)
// so, *k = x
// and x = x * (x + 1) => x = 4 * 5 = 20
Line 8:
y = x + y
// y = 20 + 15 = 35
Line 9:
k = &z;
// k is set to point z (but z is still uninitialized)
Line 11:
int a[] = {7, 9, 3, 8};
// array 'a' is defined
Line 12:
p = a;
// p is set to point the first int element of array 'a'
Line 13:
printf("%x\n", (unsigned int)p);
// printing the memory address of p
// same as printing the memory address of array 'a'
Line 14:
x = *k + 1;
// k was set to point z
// but z is still uninitialized
// so, x = z + 1 is unpredictable so far
// x is, whatever the value z plus 1
Line 15:
p = p + 2;
// p was set to point first integer element of array 'a'
// so, after p = p + 2, p = address of 'a' + 2 * sizeof(int)
// since sizeof(int) = 4 bytes, p is now address(a) + 8
// p is now pointing to the third element of array 'a'
// that is, p is pointing to '3'; *p = 3
Line 16:
z = *p - 4;
// p was set to point third element of array 'a'
// *p was '3'
// so, z = *p - 4 means z = 3 - 4 = -1
Line 17:
printf("%d %d %x %x\n", x, y, z, (unsigned int)p);
// x is, what ever the value of z plus 1
// y is 35
// z is -1; its hex representation if ffff ffff
// p is address of array a plus 2; p = &a[0] + 2
// that is; p is now, address of array 'a' + 2 * sizeof(int)
p.s. Yes, I had nothing else to do today.
{
int x = 4;
int y = 15;
int *k = &x;
int z;
int *p;
*k = *k * (*k + 1); /* x = x * (x+1) i.e. 20 */
y = x + y; /* y = 20 + 15 i.e. 35 */
k = &z; /* fine, though the content is not initialised */
int a[] = {7,9,3,8};
p = a;
printf("%x\n",(unsigned int)p);
x = *k + 1; /* x = z +1 which is unknown because content of z still not initialised */
p = p + 2; /* pointing to 3 now */
z = *p - 4; /* z= 3 - 4 ; i.e. -1 */
printf("%d %d %x %x\n",x,y,z,(unsigned int)p);
}
The result prints a signed integer (z) as unsigned, which in this case results in the representation of -1 in the twos-complement hex representation, but shown as unsigned, i.e. "ffff ffff" in 32bit.
I initially was confused by z not being intialised, but it turns out to be irrelevant.
It seems to me that the value of p would not really have been predictable.
Judging from the first print being "5a9b1740", the value should be bigger by the size of two ints, i.e. "5a9b1748" on most systems. But that does not match the output you show (before or after your edit to the question; please note 5c9b1748-5a9b1740=2000008 and 5c961748-5a9b1740=1FB 0008. Neither can be explained with the shown code. For some reason people fail to see the large difference and focus only on the few least significant nibbles...)
If those two values come from different runs of the program, then it could explain the difference with intentional randomisation. (Thanks to Gerhardh for making me look for an explanation.)
This is blatantly undefined behavior. The compiler is allowed to lay out variables in any order it likes, even leave variables without backing store (it just keeps the value in a register, sees it isn't ever used, or can deduce it's value each time it is used and doesn't require storing it, ever. You can not legally point outside the referenced object by adding to the pointer. For a rather dumb compiler (or no optimization whatsoever) the above might be right. Or it might not.
For examples of the above, compile some program with e.g. gcc -O2 -g and debug it. When single-stepping the debugger will often jump around seemingly at random in the source, skip some statements altogether, tell you some variables have been optimized out, and others.

Proper way to iterate throught list of pointers?

I can't wrap my head about idea of array of pointers. Problem is I'm trying to iterate throught list of pointers (or at least get second value from pointer's array). I understand that integer is 4 bytes long (assuming im on 32-bit). And what I'm trying to do is get first address that points to a[0] and add to this address 4 bytes, which in my opinion will result in a[1]. However, this works as I'm just adding value to index. I.e. f[0] + 4 -> f[5]
And I don't quite understand why.
#include "stdio.h"
int main()
{
int a[6] = {10,2,3,4,20, 42};
int *f[6];
for(int i = 0; i < sizeof(a)/sizeof(int); i++) f[i] = &a[i];
for(int i = 0; i < sizeof(a)/sizeof(int); i++) printf("Current pointer points to %i\n", *(*f+i));
printf("The is %i", *(f[0]+sizeof(int)));
return 1;
}
Pointer arithmetic takes into account the size of the pointer.
f[0] + 4 will multiply 4 by the size of the integer type.
Here's an online disassembler: https://godbolt.org/.
When I type the code f[0] + 4, the disassembly appears as
add QWORD PTR [rbp-8], 16
Meaning it has multiplied the 4 by 4 (32-bit = 4 bytes) to make 16.
An array is a pointer to a chunk of RAM. int a[6] = {10,2,3,4,20, 42}; actually creates a chunk with [0x0000000A, 0x00000002, 0x00000003, 0x00000004, 0x00000014, 0x0000002A], and a points to where the list starts.
Using an index a[n] basically means go to the position of a (start of the array), then advance by n*sizeof(int) bytes.
a[0] means Go to position of a, then don't jump
a[1] means Go to position of a, then jump 1 time the size of an integer
a[2] means Go to position of a, then jump 2 times the size of an integer
supposing a is at the address 0xF00D0000, and you're on a 32bit machine:
a[0] // Pointer to 0xF00D0000
a[1] // Pointer to 0xF00D0004
a[2] // Pointer to 0xF00D0008
a[32] // Pointer to 0xF00D0080
I hope this makes sense.

When subtracting two pointers in C

I was playing with pointers in order to fully get the concept and then wanted to subtract two pointers expecting the distance between these two addresses or something, but apparently I was wrong, so here is my code.
int x = 5, y = 7;
int *p = &y;
int *q = &x;
printf("p is %d\nq is %d\np - q is %d", p, q, (p - q));
Why does the program output p - q is 1? Thank you.
It is undefined behavior. According to the standard (N1570):
6.5.6 Additive operators
....
9 When two pointers are subtracted, both shall point to elements of the same array object,
or one past the last element of the array object; the result is the difference of the
subscripts of the two array elements.
Note that when allowed, the result is the subscripts difference. So if pointers point to two sequential elements of the same type, the subtraction gives 1, regardless of the size of the type. (This is perhaps the reason why you get 1 in your concrete case.)
Your particular case is cause for undefined behavior since p and q point to unrelated objects.
You can make sense of p-q only if p and q point to the same array/one past the last element of the same array.
int array[10];
int* p = &array[0];
int* q = &array[5];
ptrdiff_t diff1 = q - p; // Valid. diff1 is 5
ptrdiff_t diff2 = p - q; // Valid. diff2 is -5
q - p is 5 in this case since they point to elements of the array that are 5 elements apart.
Put another way, p+5 is equal to q. If you start from p and step over 5 elements of the array, you will point to the same element of the array that q points to.
As an aside, don't use the format specifier %d for printing pointers. Use %p. Use %td for ptrdiff_t.
printf(" p is %p\n q is %p\n p-q is :%td", p, q, p-q);`
// ^^ ^^
See http://en.cppreference.com/w/c/io/fprintf for the valid format specifiers for the different types.
Pointer arithmetic works like that. It doesn't give you differences between two addresses. Instead it will show difference between two variables as if they are stored in an array. so, no matter if your variables (of same type ) are 4 bytes, 8 bytes or 1 byte, if stored in adjacent memory location their pointer subtraction will always result in 1 or -1.
The subtraction of 2 pointers give the distance in between the 2 variables.
For eg.
//let the address of a is 1000 then of a+1 will be 1004
int a[]={1,2,3};
int *p1=a;
int *p2=a+1;
printf("%u",p2-p1);
The result of this will be 1 not 4.
Same here in your case the the location of x and y are consecutive that is why the ans. is 1.
The formula used by pointer substraction is:
( p2 - p1 ) == ( addr( p2 ) - addr( p1 ) ) / sizeof( T )
with T being the type of both p1 and p2.
int array[10];
int* p1 = array + 2;
int* p2 = array + 5;
int* a = p2 - p1; // == 3
int* b = p1 - p2; // == -3
int a=5,b=6;
int *ptr=&a,*diff;
diff=ptr;
printf("%p\n",diff);
ptr++;ptr++;ptr++;ptr++;ptr++;ptr++;ptr++;ptr++;ptr++;ptr++;
printf("%p\n",ptr);
printf("diff==%td\n",(ptr-diff)*sizeof(int));
(diff-ptr) will provide the distance between two variables, but will not provide the memory gap between two pointers.
Important: only the same type of pointer can be subtracted.
The subtraction of two pointers in array will give the distance between the two elements.
Let the address of first element i.e., is 1000 then address of second element a+1 will be 1004. Hence p1 = 1000 and p2 =1004.
p2-p1 = (1004- 1000) /size of int = (1004-1000)/4 =4/4 =1

Pointer subtraction confusion

When we subtract a pointer from another pointer the difference is not equal to how many bytes they are apart but equal to how many integers (if pointing to integers) they are apart. Why so?
The idea is that you're pointing to blocks of memory
+----+----+----+----+----+----+
| 06 | 07 | 08 | 09 | 10 | 11 | mem
+----+----+----+----+----+----+
| 18 | 24 | 17 | 53 | -7 | 14 | data
+----+----+----+----+----+----+
If you have int* p = &(array[5]) then *p will be 14. Going p=p-3 would make *p be 17.
So if you have int* p = &(array[5]) and int *q = &(array[3]), then p-q should be 2, because the pointers are point to memory that are 2 blocks apart.
When dealing with raw memory (arrays, lists, maps, etc) draw lots of boxes! It really helps!
Because everything in pointer-land is about offsets. When you say:
int array[10];
array[7] = 42;
What you're actually saying in the second line is:
*( &array[0] + 7 ) = 42;
Literally translated as:
* = "what's at"
(
& = "the address of"
array[0] = "the first slot in array"
plus 7
)
set that thing to 42
And if we can add 7 to make the offset point to the right place, we need to be able to have the opposite in place, otherwise we don't have symmetry in our math. If:
&array[0] + 7 == &array[7]
Then, for sanity and symmetry:
&array[7] - &array[0] == 7
So that the answer is the same even on platforms where integers are different lengths.
Say you have an array of 10 integers:
int intArray[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
Then you take a pointer to intArray:
int *p = intArray;
Then you increment p:
p++;
What you would expect, because p starts at intArray[0], is for the incremented value of p to be intArray[1]. That's why pointer arithmetic works like that. See the code here.
"When you subtract two pointers, as long as they point into the same array, the result is the number of elements separating them"
Check for more here.
This way pointer subtraction behaves is consistent with the behaviour of pointer addition. It means that p1 + (p2 - p1) == p2 (where p1 and p2 are pointers into the same array).
Pointer addition (adding an integer to a pointer) behaves in a similar way: p1 + 1 gives you the address of the next item in the array, rather than the next byte in the array - which would be a fairly useless and unsafe thing to do.
The language could have been designed so that pointers are added and subtracted the same way as integers, but it would have meant writing pointer arithmetic differently, and having to take into account the size of the type pointed to:
p2 = p1 + n * sizeof(*p1) instead of p2 = p1 + n
n = (p2 - p1) / sizeof(*p1) instead of n = p2 - p1
So the result would be code that is longer, and harder to read, and easier to make mistakes in.
When applying arithmetic operations on pointers of a specific type, you always want the resulting pointer to point to a "valid" (meaning the right step size) memory-address relative to the original starting-point. That is a very comfortable way of accessing data in memory independently from the underlying architecture.
If you want to use a different "step-size" you can always cast the pointer to the desired type:
int a = 5;
int* pointer_int = &a;
double* pointer_double = (double*)pointer_int; /* totally useless in that case, but it works */
#fahad Pointer arithmetic goes by the size of the datatype it points.So when ur pointer is of type int you should expect pointer arithmetic in the size of int(4 bytes).Likewise for a char pointer all operations on the pointer will be in terms of 1 byte.

Difference between "pointer to int" and "pointer to array of ints"

int main()
{
int (*x)[5]; //pointer to an array of integers
int y[6] = {1,2,3,4,5,6}; //array of integers
int *z; //pointer to integer
z = y;
for(int i=0;i<6;i++)
printf("%d ",z[i]);
x = y;
for(int i=0;i<6;i++)
printf("%d ",(*x)[i]);
return 0;
}
Both the above printfs print numbers 1 through 6.
If both "pointer to array of integers" and "pointer to integer" can do the same thing, do they have the same internal representation?
EDIT: This code does give warnings when compiled as pointed out by the answers below, however it does print the values correctly both the time on my x86_64 machine using gcc
Firstly, your code will not compile. The array has type int[6] (6 elements), while the pointer has type int (*)[5]. You can't make this pointer to point to that array because the types are different.
Secondly, when you initialize (assign to) such a pointer, you have to use the & on the array: x = &y, not just a plain x = y as in your code.
I assume that you simply typed the code up, instead of copy-pasting the real code.
Thirdly, about the internal representation. Generally, in practice, you should expect all data pointers to use the same internal representation. Moreover, after the above assignments (if written correctly), the pointers will have the same numerical value. The difference between int (*)[5] and int * exists only on the conceptual level, i.e. at the level of the language: the types are different. It has some consequences. For example, if you increment your z it will jump to the next member of the array, but if you increment y, it will jump over the whole array etc. So, these pointers do not really "do the same thing".
The short answer: There is a difference, but your example is flawed.
The long answer:
The difference is that int* points to an int type, but int (*x)[6] points to an array of 6 ints. Actually in your example,
x = y;
is undefined** behavior, you know these are of two different types, but in C you do what you want. I'll just use a pointer to an array of six ints.
Take this modified example:
int (*x)[6]; //pointer to an array of integers
int y[6] = {1,2,3,4,5,6}; //array of integers
int *z; //pointer to integer
int i;
z = y;
for(i = 0;i<6;i++)
printf("%d ",z[i]);
x = y; // should be x = &y but leave it for now!
for(i = 0;i<6;i++)
printf("%d ",x[i]); // note: x[i] not (*x)[i]
First,
1 2 3 4 5 6
Would be printed. Then, we get to x[0]. x[0] is nothing but an array of 6 ints. An array in C is the address of the first element. So, the address of y would be printed, then the address of the next array in the next iteration. For example, on my machine:
1 2 3 4 5 6 109247792 109247816 109247840 109247864 109247888 109247912
As you can see, the difference between consecutive addresses is nothing but:
sizeof(int[6]) // 24 on my machine!
In summary, these are two different pointer types.
** I think it is undefined behavior, please feel free to correct my post if it is wrong.
Hope this code helps:
int main() {
int arr[5] = {4,5,6,7,8};
int (*pa)[5] = &arr;
int *pi = arr;
for(int i = 0; i< 5; i++) {
printf("\n%d %d", arr[i], (*pa)[i]);
}
printf("\n0x%x -- 0x%x", pi, pa);
pi++;
pa++;
printf("\n0x%x -- 0x%x", pi, pa);
}
prints the following:
4 4
5 5
6 6
7 7
8 8
0x5fb0be70 -- 0x5fb0be70
0x5fb0be74 -- 0x5fb0be84
UPDATE:
You can notice that pointer to integer incremented by 4 bytes (size of 32 bit integer) whereas pointer to array of integer incremented by 20 bytes (size of int arr[5] i.e. size of 5 int of 32 bit each). This demonstrates the difference.
To answer your question from the title, from the comp.lang.c FAQ: Since array references decay into pointers, if arr is an array, what's the difference between arr and &arr?
However, the code you've posted has other issues (you're assigning y, not &y to x, and y is a 6-element array, but *x is a 5-element array; both of these should generate compilation warnings).
Who knows - this code exhibits undefined behavior:
printf("%d ",(*x)[i]);
Hope this code helps.
#include <stdio.h>
#include <stdlib.h>
#define MAXCOL 4
#define MAXROW 3
int main()
{
int i,j,k=1;
int (*q)[MAXCOL]; //pointer to an array of integers
/* As malloc is type casted to "int(*)[MAXCOL]" and every
element (as in *q) is 16 bytes long (I assume 4 bytes int),
in all 3*16=48 bytes will be allocated */
q=(int(*)[MAXCOL])malloc(MAXROW*sizeof(*q));
for(i=0; i<MAXROW; i++)
for(j=0;j<MAXCOL;j++)
q[i][j]=k++;
for(i=0;i<MAXROW;i++){
for(j=0;j<MAXCOL;j++)
printf(" %2d ", q[i][j]);
printf("\n");
}
}
#include<stdio.h>
int main(void)
{
int (*x)[6]; //pointer to an array of integers
int y[6] = {11,22,33,44,55,66}; //array of integers
int *z; //pointer to integer
int i;
z = y;
for(i = 0;i<6;i++)
printf("%d ",z[i]);
printf("\n");
x = &y;
for(int j = 0;j<6;j++)
printf("%d ",*(x[0]+j));
return 0;
}
//OUTPUT::
11 22 33 44 55 66
11 22 33 44 55 66
Pointer to an array are best suitable for multi-dimensional array. but in above example we used single dimension array. so, in the second for loop we should use (x[0]+j) with * to print the value. Here, x[0] means 0th array.
And when we try to print value using printf("%d ",x[i]);
you will get 1st value is 11 and then some garbage value due to trying to access 1st row of array and so on.
One should understand the internal representation of (*x)[i]. Internally, it is represented as
*((*x)+i), which is nothing but the ith element of the array to which x is pointing. This is also a way to have a pointer pointing to 2d array. The number of rows is irrelevant in a 2d array.
For example:
int arr[][2]={{1,2},{3,4}};
int (*x)(2);
x=arr; /* Now x is a pointer to the 2d array arr.*/
Here x is pointing to a 2d array having 2 integer values in all columns, and array elements are stored contiguously. So (*x)[0] will print arr[0][0] (which is 1), (*x)[1] will print the value of arr[0][1] (which is 2) and so on. (*x+1)[0] will print the value of arr[1][0] (3 in this case) (*x+1)[1] will print the value of arr[1][1] (4 in this case) and so on.
Now, a 1d array could be treated as nothing but a 2d array having only one row with as many columns.
int y[6] = {1,2,3,4,5,6};
int (*x)[6];
x =y;
This means x is a pointer to an array having 6 integers. So (*x)[i] which is equivalent to *((*x)+i) will print ith index value of y.

Resources