2012-06-28 15 views
19

ich diesen Code haben, die funktioniert der Trick:Hinzufügen von zwei Zahlen ohne die Verwendung von +

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

Kann jemand bitte erklären, was im Code geschieht?

+0

wie eine bitweise Operation aussieht. Sie können einen kurzen Blick auf http://www.cprogramming.com/tutorial/bitwise_operators.html für weitere Informationen werfen –

+7

Sorry, aber das ist überhaupt nicht bitweise. Der Code ist erfunden, aber Sie werden es verstehen, wenn Sie ein wenig in Pointer Arithmetic (speziell der [] -Operator) lesen. Wenn du in C programmieren willst, wird sich das definitiv lohnen. –

+0

Siehe auch: [Wie füge ich zwei Zahlen ohne den Operator + hinzu?] (Http://stackoverflow.com/questions/4679556/how-do-i-add-two-numbers-without-the-operator) – Mysticial

Antwort

22

Ich denke, es lohnt sich, zu den anderen Antworten eine kurze Erklärung der Zeiger, Arrays und Speicherplätze in c hinzuzufügen.

Erstens Arrays in c sind nur ein Speicherblock, der groß genug, um die Anzahl der Elemente in dem Array zu halten (siehe http://www.cplusplus.com/doc/tutorial/arrays/)

Wenn wir also die

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

32 Bits int ist Angenommen, wir hätte einen Speicherblock 5 * 32bits = 160bits lang. Da C eine Low-Level-Sprache ist, versucht es, so effizient wie möglich zu sein, speichert daher die geringste Menge an Information über Arrays wie möglich, in diesem Fall ist die kleinste mögliche Anzahl die Speicheradresse des ersten Elements. So könnte die Art von Beispiel ausgedrückt werden als

int *example; 

Oder Beispiel zeigt auf einen int. Um die Elemente in das Array zu bekommen, fügen Sie die korrekte Nummer zu der im Beispiel gespeicherten Adresse hinzu und lesen die Nummer an dieser Speicheradresse. Wenn wir Speicher aussehen wie

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 
angenommen

als

ausgedrückt werden konnte
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; 

Der sizeof (int) 4 (int 32 Bit oder 4 * 8 Bit-Bytes). Wenn Sie versuchen, Addition zu tun, würden Sie ein char wünschen, das 8 Bits oder 1 * 8 Bit-Bytes ist.

Sie Code Also zurück

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 wird Summe die Adresse des 21. Element des Arrays zugeordnet.

Lange umständliche Erklärung.

+0

+ 1'd für die höchste Detailstufe und Klarheit in Ihrer Antwort! Vielen Dank ! – insane

6

p [b] gibt das b-te Element des Arrays p zurück, das äquivalent zu * (p + b) ist. & p [b] entspricht p + b * sizeof (char), das zurück in int konvertiert wird.

+0

Die "mal sizeof (char)" Teil ist genau das, was FatalError mit "scaling factor" meint. –

+0

danke für Ihre Antwort wirklich die Tatsache, warum der Skalierungsfaktor war wichtig, wie von FatalError. – insane

37

&p[b] ist im Grunde Zucker für:

&*(p + b) 

Die * und & Operatoren sind inverse Operationen hier und stornieren, einfach p + b verlassen. Die Umwandlungen umgehen nur die Typüberprüfung von C. Die Tatsache, dass ein char * Zeiger verwendet wird ist signficant, jedoch; C skaliert Zeiger Arithmetik, und da sizeof(char) == 1 per Definition ist der Skalierungsfaktor 1.

+0

Perfekt! Vielen Dank, FatalError! – insane

+0

Es ist schneller als 'sum = a + b'? – Jack

+0

@Jack ist es nicht, '& p [b]' wird während der Kompilierung in '& * (p + b)' übersetzt. –

0

Wenn die Frage war „zwei Zahlen ohne den Operator + Hinzufügen“, ist hier ein:

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

Nichts schlägt "a - (-b)" –

Verwandte Themen