Подтвердить что ты не робот

Добавление двух чисел без использования +

У меня есть этот код, который делает трюк:

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

Может кто-нибудь объяснить, что происходит в коде?

p = (char*)a;
sum = (int)&p[b]; // adding a & b
4b9b3361

Ответ 1

Я думаю, что стоит добавить к другим ответам быстрое объяснение указателей, массивов и мест памяти в c.

Во-первых, массивы в c - это всего лишь блок памяти, достаточно большой для хранения количества элементов в массиве (см. http://www.cplusplus.com/doc/tutorial/arrays/)

поэтому, если бы мы сказали

int[5] example;
example[0] = 1;
example[1] = 2;
example[2] = 3;
example[3] = 4;
example[4] = 5;

Предполагая, что int - 32 бита, у нас будет блок памяти 5 * 32 бит = 160 бит. Поскольку язык C является языком низкого уровня, он пытается быть настолько эффективным, насколько это возможно, поэтому сохраняет наименьшее количество информации о массивах, насколько это возможно, в этом случае наименьшее возможное количество - это адрес памяти первого элемента. Таким образом, тип примера может быть выражен как

int *example;

Или пример указывает на int. Чтобы получить элементы в массиве, вы затем добавляете правильный номер в адрес, хранящийся в примере, и читаете номер на этом адресе памяти. Если мы предположили, что память выглядит как

Memory Address = Value (ints take up 4 bytes of space)
          1000 = 1          <-- example
          1004 = 2   
          1008 = 3   
          1012 = 4   
          1016 = 5

Итак,

int i = example[3];  //The 4th element

может быть выражена как

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;

sizeof (int) - 4 (int - 32 бита или 4 * 8 бит байтов). Если вы пытаетесь сделать дополнение, вам понадобится char, который составляет 8 бит или 1 * 8 бит байтов.

Итак, вернемся к коду

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.

Таким образом, сумме присваивается адрес 21-го элемента массива.

Долгое объяснение.

Ответ 2

&p[b] - это в основном сахар для:

&*(p + b)

Операторы * и & здесь являются обратными операциями и отменяются, оставляя просто p + b. Броски просто обходят проверку типа C. Однако тот факт, что используется указатель char *, является значимым; C, а с sizeof(char) == 1 по определению коэффициент масштабирования равен 1.

Ответ 3

p [b] возвращает b-й элемент массива p, что эквивалентно * (p + b). & p [b] равно p + b * sizeof (char), который преобразуется обратно в int.

Ответ 4

Если вопрос заключался в "добавлении двух чисел без оператора +", вот один из них:

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