Efecto de “+1” después del parámetro de cadena de formato para printf ()

Tengo algunos problemas relacionados con este código. El parámetro de printf es de tipo const char* y ... (lista de argumentos variables).

1) ¿Por qué la salida del progtwig es d y no 127 ?
2) ¿Es que el +1 se convertiría en una cadena y se pasaría a una variable de parámetro de tipo const char* ?

 #include int main() { printf("%d"+1 , 127); //how this will get executed? return 0; } 

Salida:

 d 

El primer parámetro es un puntero a char .
El literal "%d" sería un puntero al '%' , que está seguido implícitamente por 'd' y '\0' . Es un puntero a char , porque esa es la representación en C de los literales de cadena: secuencias de caracteres con un '\0' al final; representado para su uso como parámetros, etc. como un puntero a char .
Pero "%d"+1 , de acuerdo con la aritmética del puntero, es un puntero a 'd' , seguido de '\0' .
Ambos están terminados en cero, como ajuste para un parámetro a printf.

Así que la salida es la misma que

 printf("d", ignored); 

127 se convierte en “ignorado”, es decir, se ignora, porque la "d" le dice a printf que no espere nada, porque no tiene ninguna de las secuencias de caracteres especiales, por ejemplo, “% someletter”. Por lo tanto, no esperará, no buscará nada y no realizará ninguna impresión más allá de la cadena perfectamente normal que cree haber recibido.
Sin embargo, tenga en cuenta que los parámetros adicionales, aquellos que no están cubiertos por nada en la cadena de formato, se evalúan y luego se ignoran. Esto es relevante, porque de hecho se producen efectos secundarios (por ejemplo, llamadas a funciones) de esa evaluación.
Ver por ejemplo aquí para más detalles:
http://en.cppreference.com/w/c/io/fprintf

Déjame intentar ayudar y agregar a la respuesta de @Yunnosch, podrías hacer lo siguiente:

  char *str = "%d"; printf (str, 127); 

y la salida debe ser:

 127 

En el ejemplo anterior, str se almacena en una memoria como esta (esto es solo un ejemplo y en la vida real las direcciones son como 0xabcdef12345678):

 address | memory --------+-------------- 0 | % 1 | d 3 | \0 

así que str apunta a la dirección 0 (o equivalente en su sistema) que contiene % , printf() obtiene esa dirección y comienza a leer desde allí, lee hasta que encuentra el carácter NULO ‘\ 0’. Ahora, cada vez que ve el % busca el siguiente carácter d , c , x , etc., lee el siguiente argumento de la lista de argumentos. Si proporcionó d , se imprimirá decimal, si suministra c imprimirá el carácter, x es para hex y hay muchos más. Por lo tanto, printf() leerá todos los caracteres y reemplazará % con el parámetro apropiado hasta que scope el carácter NULO \0 , pero comenzará en la dirección proporcionada.

Tu caso:

 printf("%d"+1, 127); 

es lo mismo que

 char *str = "%d"; printf (str + 1, 127); // printf receives address of character `d` as starting point 

o es similar a

 char *str = "%d"; char *str1 = str+1; // increment the address of string by one printf (str1, 127) 

en ambos casos, recibe la dirección de d y lee desde allí hasta que llega a \0 .

Si lo haces a continuación:

 printf ("%d" + 2, 127); 

Esto sería lo mismo que:

 char *str = "%d"; printf (str + 2, 127); 

no generaría nada porque, printf() obtendrá la dirección de \0 . y como @Yunnosh dijo que 127 sería ignorado.

Así que +1 y +2 no se convierten en una cadena que se agregan a la dirección de la cadena.

Espero que esto ayude, creo que respondí ambas preguntas.