19

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
3
  • Looks like a bitwise operation. You could take a quick look at cprogramming.com/tutorial/bitwise_operators.html for more information Commented Jun 28, 2012 at 12:25
  • 7
    Sorry, but this is not at all bitwise. The code IS contrived, but you will understand it if you read a bit into Pointer Arithmetic (specially the [] operator). If you are going to program in C, this is definitely going to be worth your while. Commented Jun 28, 2012 at 12:41
  • See Also: How do I add two numbers without the + operator? Commented Aug 27, 2012 at 22:06

4 Answers 4

37

&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.

Sign up to request clarification or add additional context in comments.

2 Comments

It's faster than do sum = a + b?
@Jack it isn't, &p[b] is translated to &*(p + b) during compilation.
23

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.

1 Comment

+1'd for the highest level of detail and clarity in your answer ! Thanks !
6

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.

2 Comments

The "times sizeof(char)" part is exactly what FatalError means with "scaling factor".
thank you for your answer really cleared up the fact of why the scaling factor was important as stated by FatalError.
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.