¿Por qué almacenamos la cadena en un puntero de carácter, por ejemplo, en fopen () ;?

Estoy tratando de profundizar en la siguiente línea:

char* filename="file.txt"; 

Esto lo hago cuando usamos fopen() ;

Mis preguntas son:

  1. se supone que el filename contiene una dirección de un carácter (36 bits en core2Duo). ¿Por qué estamos poniendo una ‘ cadena ‘ en ella?

  2. ¿Por qué el comstackdor no generaría un error (es) ya que podría estar almacenando una dirección que nunca puede existir?

se supone que el nombre del archivo contiene una dirección de un carácter (36 bits en core2Duo), ¿por qué le estamos poniendo una ‘cadena’?

La expresión char* filename="file.txt"; Es una expresión válida. La razón es el tipo de una cadena. Los literales en C son char[N] que pueden descomponerse fácilmente en char* , y char[N] y char* son compatibles. Por lo tanto, puede asignar una dirección de cadena a una variable de puntero char* como lo está haciendo en esta expresión.

¿Por qué el comstackdor no generaría un error, ya que podría estar almacenando una dirección que nunca puede existir?

Por favor lea a continuación tres puntos:

  • Es una dirección válida:

No, en la expresión char* filename="file.txt"; , filename se le asigna una dirección válida. Es conceptualmente algo como (asumiendo que la dirección comienza con 21):

 filename 21 22 23 24 25 26 27 28 29 +---+ +------------------------------------+ |21 |---> |'f'|'i'|'l'|'e'|'.'|'t'|'x'|'t'|'\0'| +---+ +------------------------------------+ filename pointing to string, a valid address. 

y no da ningún error o advertencia: intente con el siguiente código de ejemplo:

Ejemplo 1:

 #include int main(int argc, char **argv){ char* filename = "filename.txt"; printf("%s", filename); return 0; } 

Comstackrlo

 :~$ gcc yc -Wall -pedantic ~$ ./a.out filename.txt 

Ningún error y waring, su comstackción y ejecución perfectamente.

Respecto a tu comentario a mi respuesta:

Las cadenas en C son variables de valores simples, estructuradas por datos y luego simples como int , char , float .

En el caso de tipos de datos básicos:

 int i = 5; You are assigning value 5, to variable i char c = 'A'; You are assigning value 'A' to char variable c. float f = 5.5f; You are assigning value 5.5f to float variable f. 

Pero por cuerdas, cuando haces:

  char* filename = "filename.txt"; 

Entonces, en realidad está asignando la dirección de la cadena "filename.txt" al filename variable del puntero char *.

Considerando que si lo haces:

  char filename[] = "filename.txt"; // ^ notice [] in declaration 

Entonces estás asignando la cadena “nombre_archivo.txt”; a una matriz de filename[] de filename[] char filename[] , aquí el tipo de filename es char[] .

Para obtener más información sobre más referencias en ambas declaraciones, lea: ¿Qué devuelve sizeof (& arr)?

Un literal de cadena puede darle dependencias de valor o dirección en el contexto en que lo use. por ejemplo, pruebe: printf(" address: %p, value: %s", "Hello", "Hello");

  • El comstackdor no valida la dirección pero verifica la syntax.

El comstackdor no es responsable de validar que una dirección es legal. El comstackdor transpone el código y comprueba los errores de syntax (por ejemplo, la falta de coincidencia de tipos no comstackbles). Supongamos que si asigna una dirección falsa a un puntero no le dará una advertencia (si escribe correctamente la dirección de conversión). Considere el siguiente ejemplo:

ejemplo-2:

 #include int main(int argc, char **argv){ char* filename = "filename.txt"; char* ptr = (char*)0x020202; printf("%s %s\n", filename, ptr); return 0; } 

Comstackr:

 $ gcc yc -Wall -pedantic 

Y no genera ningún error o waring. Porque sintácticamente todo está bien y válido.
(Considerando que ptr asignó una dirección falsa que puede no existir).

  • La dirección no válida provoca un comportamiento indefinido en tiempo de ejecución

Bueno, está bien comstackr el código del ejemplo 2 donde ptr se asigna a una dirección falsa, y el comstackdor no genera ningún error / advertencia, incluso con las opciones de marca de comprobación: -Wall -pedantic .

Pero ejecutar este código es incorrecto. Intenta acceder a la dirección de memoria ptr a ptr en la statement printf, y el progtwig se comportará de manera anormal (en diferentes instancias de ejecución). En C -Language standard se llama: comportamiento indefinido .

Cuando ejecuta este código, el sistema operativo (pero no el comstackdor) detecta la violación de los derechos de memoria por un proceso: un acceso no válido a la memoria válida proporciona: SIGSEGV Y el acceso a una dirección no válida proporciona: SIGBUS. Esto puede causar la finalización / caída del proceso con algún fallo de segmentación y volcado de núcleo .

Para aprender y saber qué puede pasar cuando accede a la memoria ilegal, la implementación de strcat () funciona pero provoca un volcado de memoria al final .

se supone que el nombre del archivo contiene una dirección de un carácter (36 bits en core2Duo), ¿por qué le estamos poniendo una ‘cadena’?

La triste verdad es que no lo somos. Estamos poniendo un puntero al primer carácter de la cadena literal en él. La cadena "file.txt" es de tipo char[9] , que, cuando se asigna a un puntero, decae en char * . Pero debe asignarlo a un puntero a const char , ya que modificarlo es ilegal (da como resultado un comportamiento indefinido). Lee esto.

¿Por qué el comstackdor no generaría un error, ya que podría estar almacenando una dirección que nunca puede existir?

Disculpe, pero ¿de qué tipo de dirección inexistente está hablando? ¡La dirección del primer carácter en el literal de cadena siempre es explícitamente válida!

(Pero incluso si lo fuera, el comstackdor sabe muy poco, si es que lo tiene, acerca de la semántica. Simplemente no siempre puede advertirle si existe la posibilidad de usar un puntero no válido. Claro, a veces puede, pero no tiene altas expectativas .)

  1. Sí, tiene una dirección, pero también sucede que a la dirección le sigue la dirección de los vecinos de al lado y la dirección de sus vecinos de al lado, etc. Es a través de esta “cadena” de direcciones que el valor es en realidad encontrado.
  2. El comstackdor no debe generar un error porque podría ser que se cree un archivo “filename.txt” en algún momento en el futuro, y las llamadas a fopen no se evaluarán hasta que el progtwig se ejecute realmente.

Por favor, lea algunos buenos libros de progtwigción en C, explican cuáles son los punteros y las matrices.

Una cadena literal como "file.txt" es una matriz char[] (pero debe pensar que es const char[] porque la asignación de literales dentro de cadena como "abc"[1]='D'; es un comportamiento indefinido con mal gusto , y gcc -Wall te lo advertiría). Los arreglos pueden entenderse (y generalmente se entienden) como el puntero a su primera celda (del índice 0); en otras palabras, los arreglos se descomponen en punteros. Por lo tanto, puede asignar un literal de cadena a un puntero de caracteres.

Sin embargo, los arreglos no son punteros en C; por ejemplo, sizeof some array es un múltiplo adecuado del tamaño de cada elemento, en particular sizeof("abcde") == 6 (debido al byte nulo de terminación en cada literal de cadena). Pero el tamaño de algún puntero es independiente del tamaño de la zona señalada, y en la mayoría de los sistemas, todos los punteros tienen el mismo tamaño, el tamaño de la palabra de la máquina.

gcc -Wall solicitar explícitamente al comstackdor todas las advertencias (por ejemplo, gcc -Wall en Linux) para obtenerlas.