2010-11-09 3 views
6

Vor kurzem stieß ich auf dieses Rätsel: "?"Kann man das lösen?

int main(){ 
    int arr[7]; 
    int b,c,d,a; 
    a=4; 
    printf("%d",arr[?]); 
    return 0; 
} 

Die Frage ist, ersetzen mit einer ganzen Zahl, so dass der Ausgang 4 ist. Ich bin mir nicht sicher, aber ich denke nicht, dass dies auf eine standardmäßige Weise lösbar ist?! (Kein undefiniertes Verhalten oder abhängig von der Implementierung) Wenn NEIN, dann bin ich sehr daran interessiert zu wissen, wie?

bearbeiten: Diese Aufgabe aus here genommen wird, habe ich versucht, mit 10, zu lösen, aber es ist leider nicht die Antwort das Problem Setter wants.However ich es solved einige pretested Implementierung abhängig Hokuspokus, aber ich wirklich habe keine Erklärung dafür, wie es wirklich funktioniert!

Hier ist die Antwort: SPOILER, Sie sind willkommen, es

+9

Es gibt keine Möglichkeit, garantiere die Ausgabe ist vier, mit diesen Einschränkungen.Wenn Sie das "?" erlauben, etwas zu sein, dann können Sie es ersetzen mit '0] = 4, arr [0'. – GManNickG

+0

Was war Ihre Lösung? – SLaks

+0

@SLaks: Ich habe Ich habe es als Spoiler – Quixotic

Antwort

14

Angenommen, es gibt keine Antwort, die dem Standard entspricht, könnten Sie eine Operation (offensichtlich keine Ganzzahl) wie arr [& a-arr] verwenden?

Edit: Made clean dank Ben und andere in den Kommentaren.

+1

Ich denke, dass Sie dort einige Klammern brauchen könnten, da das Subtrahieren eines Zeigers von 0 nicht definiert ist, aber das ist ziemlich elegant. –

+0

Nicht ganz da, weil die Werte in Klammern mit sizeof (int) multipliziert werden ... aber der Klang der Idee war nicht für die Einschränkung, dass '?' Eine Integer-Konstante ist. –

+1

@Tony, es sagt nicht, dass die Antwort ein Integer-Literal sein muss, es sagt nur, es muss eine ganze Zahl sein. Der Unterschied zwischen zwei Zeigern ist eine ganze Zahl. So ist die Negation einer ganzen Zahl. Außerdem wird die Differenz zwischen zwei Zeigern durch 'sizeof (int)' geteilt, wodurch die von Ihnen erwähnte Multiplikation aufgehoben wird. Damit ? = '- (arr- & a)' ist richtig. –

15

In den meisten Implementierungen zu erklären, arr[10] (oder 7) wird 4 sein, da die Einheimischen werden sequentiell angelegt werden.

Dies ist jedoch weder definiert noch Standard, und muss nicht sein.

+0

Nun, könnten Sie bitte erklären, was Sie mit "da die Einheimischen werden sequentiell ausgelegt werden" gemeint? – Quixotic

+2

arr [7] nimmt 7 Bytes auf, dann wird _int b_ im nächsten Byte sein, __int c__ im nächsten Byte ... würde der Zugriff auf arr [10] aus dem Array und in den benachbarten Speicher überspringen, was diese sind neu deklarierte Ints (hoffentlich) – sova

+1

Dies gilt nur, wenn Sie die Optimierung ausgeschaltet haben! Selbst bei niedrigen Optimierungsstufen werden b c und d fallen, da sie nie benutzt werden. Höhere Optimierungsebenen können möglicherweise in den Anfang des Stacks verschoben werden, wie er zuerst verwendet wird (die Reihenfolge von Variablen in der Reihenfolge, in der sie verwendet werden, kann Cache-Treffer und "freie" Chach-Lasten erhöhen). –

3

Ich vermute, auf einigen Systemen 10 würde den Trick tun (je nach Ausrichtung und Auffüllung und die Größe von int), aber das ist undefiniertes Verhalten. Ich kann keine Standardmethode sehen, um zu tun, was gefragt wird.

+0

Nur wenn der Stapel nach oben wächst. – JeremyP

0

Vielleicht ist es eine Trick Frage, vielleicht gibt es eine 4, aber es existiert nicht im Array (so vielleicht ein seltsamer Index wird Ihnen eine 4 aus einem interessanten Grund geben).

+0

Ja, der Index ist wirklich seltsam! – Quixotic

1

auf http://ideone.com:

#include "stdio.h" 
int main(){ 
    int arr[7]; 
    int b,c,d,a; 
    a=4; 
    printf("%p %p %d %d",arr, &a, arr - &a, arr[7]); 
    return 0; 
} 

0xbfa95918 0xbfa95934 -7 4 

Optimierer b, c entfernt, d daher ein Recht auf 7

0

Ich glaube nicht eine tragbare Antwort möglich ist, wenn ? Bedarf durch eine ganze Zahl ersetzt werden; aber eine tragbare Lösung kann möglich sein, wenn ein Ausdruck erlaubt ist; mit der Tatsache, dass a [i] == i [a].

printf("%d",arr[(unsigned long) ((a & (1 << ((sizeof (int) - 1) * CHAR_BIT))) ? 
           /* Big Endian */ 
           memset (calloc ((unsigned long) arr + sizeof (int), 1), 
             4, (unsigned long) arr + 1) 
           : 
           /* Small Endian*/ 
           memset (memset (malloc ((unsigned long) arr + sizeof (int)), 
               4, (unsigned long) arr + sizeof (int)), 
             0, 
             (unsigned long) arr + sizeof (int) - 1) 
           )]); 

Sie benötigen eine große Menge RAM, um zu arbeiten; und ich kann die Richtigkeit nicht aus dem gleichen Grund prüfen.

0
$ cat 4130250.c \ 
> && echo -------- \ 
> && sed -e 's/\?/arr[0] = 4, 0/' 4130250.c | gcc -xc - \ 
> && ./a.out 
int main(){ 
int arr[7],b,c,d,a; 
a=4; 
printf("%d\n", arr[?]); 
return 0; 
} 
-------- 
<stdin>: In function `main`: 
<stdin>:4: warning: incompatible implicit declaration of built-in function `printf` 
4 

Erläuterung der Befehlszeile :-)

cat 4130250.c: Ausgabe der Inhalte des "Programm"
echo --------: output a separator
sed ...: das „ersetzen?"Mit‚arr [0] = 4, 0‘und schreiben in der Standardausgabe
| gcc -xc -: Kompilieren C von der Standardeingabe (die Ausgabe der vorherige SED)
./a.out: Ausführen der binären erzeugen