2010-11-09 32 views
6

Recientemente me encontré con este rompecabezas: "?"¿Es posible resolver esto?

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

La pregunta es Reemplazar con un número entero para que la salida sea 4. No estoy seguro, pero no creo que esto pueda resolverse de manera estándar? (No se invoca Comportamiento no definido o dependiendo de la implementación) Si no, entonces estoy muy interesado en saber cómo hacerlo.

Editar: Esta tarea se toma de here, traté de resolver con 10, pero por desgracia, no es la respuesta al problema colocador wants.However, me solved usando alguna aplicación probada previamente dependientes galimatías, pero realmente no tengo explicación de cómo funciona realmente!

Aquí está la respuesta: SPOILER, Usted es bienvenido a explicarlo

+9

No hay manera de garantizar la salida es de cuatro, con esas restricciones Si usted permite que el ser nada, entonces se puede reemplazar con '0] = 4, arr [0' – GManNickG

+0

¿Cuál fue su solución – SLaks

+0

@SLaks. "?":.? tengo . actualizado como un alerón – Quixotic

Respuesta

14

Suponiendo que no hay una respuesta que cumpla con el estándar, ¿podría usar una operación (obviamente no un número entero) como arr [& a-arr]?

Editar: Hecho más limpio gracias a Ben y otros en los comentarios.

+1

Creo que podría necesitar algunos paréntesis allí, porque restar un puntero de 0 no está definido, pero eso es bastante elegante. –

+0

No está exactamente allí, porque los valores entre paréntesis se multiplican por sizeof (int) ... pero el sonido de la idea no fue por la restricción de que '?' Sea una constante entera. –

+1

@Tony, no dice que la respuesta debe ser un literal entero, solo dice que debe ser un número entero. La diferencia entre dos punteros ES un número entero. También lo es la negación de un entero. Además, la diferencia entre dos punteros se divide por 'sizeof (int)', que cancela la multiplicación que mencionaste. Asi que ? = '- (arr- & a)' es correcto. –

15

En la mayoría de las implementaciones, arr[10] (o 7) será de 4, ya que quedan dispuestas secuencialmente los locales.

Sin embargo, esto no está definido ni es estándar, y no debe confiarse en.

+0

Bueno, ¿podría explicar qué quiere decir con 'ya que los locales se distribuirán secuencialmente'? – Quixotic

+2

matriz [7] ocupa 7 bytes, entonces b_ _int estará en el siguiente byte, C__ __int en el siguiente byte ... para acceder matriz [10] se salta fuera de la matriz y en la memoria de la vecina, que es éstas Ints recientemente declarados (con suerte) – sova

+1

¡Esto solo es cierto si tiene la optimización desactivada! Incluso bajos niveles de optimización caerán b c y d ya que nunca se usan. Los niveles más altos de optimización pueden moverse al inicio de la pila como se usa primero (ordenar las variables en el orden en que se usan puede aumentar los hits de la memoria caché y las cargas de chache "gratuitas"). –

3

Sospecho que en algunos sistemas 10 haría el truco (dependiendo de la alineación y el relleno, y el tamaño de int), pero eso ES un comportamiento indefinido. No veo ninguna forma estándar de hacer lo que se pide.

+0

Solo si la pila crece hacia arriba. – JeremyP

0

Tal vez es una pregunta capciosa, tal vez haya un 4 pero no existe en el conjunto (por lo que tal vez algún índice extraño le dará un 4 por una razón interesante).

+0

Sí, ¡el índice es realmente extraño! – Quixotic

1

en 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 

optimizador elimina b, c, d, por tanto, a la derecha en 7

0

no creo una respuesta portátil es posible si ? necesidades para ser reemplazado por un número entero; pero una solución portátil puede ser posible si se permite una expresión; utilizando el hecho de que 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) 
           )]); 

Necesitará una gran cantidad de RAM para funcionar; y no puedo probar la corrección por la misma razón.

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 

Explicación de la línea de comandos :-)

cat 4130250.c: Salida de los contenidos del "programa"
echo --------: salida de un separador
sed ...: sustituir el "?"Con "arr [0] = 4, 0" y escribir en la salida estándar
| gcc -xc -: compilar C de la entrada estándar (la salida de la SED anterior)
./a.out: ejecutar el producido binario

Cuestiones relacionadas