He encontrado una función que calcula el cuadrado de un número:
int p(int n) {
int a[n]; //works on C99 and above
return (&a)[n] - a;
}
Devuelve el valor de n 2 . La pregunta es, ¿cómo hace eso? Después de una pequeña prueba, encontré que entre (&a)[k]y (&a)[k+1]es sizeof(a)/ sizeof(int). ¿Porqué es eso?

int p(n)? ¿Eso incluso compila?int q(int n) { return sizeof (char [n][n]); }sizeoffue para guardar caracteres. Todos los demás: este es un código intencionalmente oscuro, es un comportamiento indefinido, la respuesta de @ ouah es correcta.Respuestas:
Obviamente, un truco ... pero una forma de cuadrar un número sin usar el
*operador (este era un requisito del concurso de codificación).es equivalente a un puntero a la
intubicacióny así toda la expresión es
fuente
(&a)como un puntero a un objeto den*sizeof(int)cuandonno se conoce en el momento de la compilación. C solía ser un lenguaje simple ...Para comprender este truco, primero debe comprender la diferencia del puntero, es decir, ¿qué sucede cuando se restan dos punteros que apuntan a elementos de la misma matriz ?
Cuando se sustrae un puntero de otro, el resultado es la distancia (medida en elementos de la matriz) entre los punteros. Entonces, si
papuntaa[i]yqapuntaa[j], entoncesp - qes igual ai - j.C11: 6.5.6 Operadores aditivos (p9):
Ahora espero que esté al tanto de la conversión del nombre de la matriz a puntero, se
aconvierte en puntero al primer elemento de la matriza.&aes la dirección de todo el bloque de memoria, es decir, es una dirección de matriza. La siguiente figura lo ayudará a comprender ( lea esta respuesta para obtener una explicación detallada ):Esto le ayudará a comprender por qué
ay&atiene la misma dirección y cómo(&a)[i]es la dirección de la matriz (del mismo tamaño que la dea).Entonces, la declaración
es equivalente a
y esta diferencia dará el número de elementos entre los punteros
(&a)[n]y(&a)[0], que sonnmatrices de cada uno de losnintelementos. Por lo tanto, los elementos de la matriz total sonn*n=n2 .NOTA:
C11: 6.5.6 Operadores aditivos (p9):
Dado que
(&a)[n]ni apunta a elementos del mismo objeto de matriz ni a uno más allá del último elemento del objeto de matriz,(&a)[n] - ainvocará un comportamiento indefinido .También tenga en cuenta que es mejor cambiar el tipo de función de retorno
paptrdiff_t.fuente
&a[k]es una dirección delkelemento de matriza. Es(&a)[k]que siempre se considerará una dirección de una matriz dekelementos. Entonces, el primer elemento está en la posicióna(o&a), el segundo está en la posicióna+ (número de elementos de la matrizaque esn) * (tamaño de un elemento de la matriz) y así sucesivamente. Y tenga en cuenta que, la memoria para matrices de longitud variable se asigna en la pila, no en el montón.aes una matriz (variable) denint.&aes un puntero a una matriz (variable) denint.(&a)[1]es un puntero deintunointpasado el último elemento de la matriz. Este puntero esnintelementos después&a[0].(&a)[2]es un puntero deintunintpasado el último elemento de matriz de dos matrices. Este puntero es2 * nintelementos después&a[0].(&a)[n]es un puntero deintunointpasado el último elemento denmatriz de matrices. Este puntero esn * nintelementos después&a[0]. Solo resta&a[0]oay tienesn.Por supuesto, este es un comportamiento técnicamente indefinido, incluso si funciona en su máquina, ya
(&a)[n]que no apunta dentro de la matriz o más allá del último elemento de la matriz (como lo requieren las reglas C de la aritmética del puntero).fuente
[n]sintaxis declara una matriz y las matrices se descomponen en punteros. Tres cosas útiles por separado con esta consecuencia.(&a)[n]es tipoint[n], y que se expresa comoint*debido a las matrices que se expresan como la dirección de su primer elemento, en caso de que no esté claro en la descripción.Si tiene dos punteros que apuntan a dos elementos de la misma matriz, entonces su diferencia producirá el número de elementos entre estos punteros. Por ejemplo, este fragmento de código generará 2.
Ahora consideremos la expresión
En esta expresión
atiene tipoint *y apunta a su primer elemento.La expresión
&atiene tipoint ( * )[n]y apunta a la primera fila de la matriz bidimensional con imagen. Su valor coincide con el valor de losatipos aunque son diferentes.es el enésimo elemento de esta matriz bidimensional con imagen y tiene el tipo
int[n]Es decir, es la enésima fila de la matriz con imagen. En expresión(&a)[n] - a, se convierte a la dirección de su primer elemento y tiene el tipo `int *.Entonces, entre
(&a)[n]yahay n filas de n elementos. Entonces la diferencia será igual an * n.fuente
Así,
(&a)[n]esint[n]punteroaesintpunteroAhora la expresión
(&a)[n]-arealiza una sustracción de puntero:fuente