En C99, una cadena generalmente se inicializa usando el tipo de datos char* ya que no hay un tipo de datos primitivo de "cadena". Esto crea efectivamente una matriz de caracteres al almacenar la dirección del primer carácter en la variable:
FILE* out = fopen("out.txt", "w"); char* s = argv[1]; fwrite(s, 12, 1, out); fclose(out); //successfully prints out 12 characters from argv[1] as a consecutive string. ¿Cómo sabe el compilador que char* s es una cadena y no solo la dirección de un char singular? Si uso int* , solo permitirá un int , no una matriz de ellos. ¿Por qué la diferencia?
Mi enfoque principal es comprender cómo funcionan los punteros, las referencias y las desreferencias, pero todo el char* sigue jugando con mi cabeza.
¿Cómo sabe el compilador que
char* ses una cadena y no solo la dirección de un char singular?
no lo hace En lo que respecta al "compilador", char* s es un puntero a char.
Por otro lado, hay muchas funciones de biblioteca que asumen que char* apunta a un elemento de una secuencia de char terminada en nulo (ver, por ejemplo, strlen , strcmp , etc.).
Tenga en cuenta que fwrite no hace esta suposición. Requiere que le diga cuántos bytes desea escribir (y que este número no lo lleve más allá de los límites del búfer señalado por el primer argumento).
Si uso
int*, solo permitirá un int, no una matriz de ellos. ¿Por qué la diferencia?
Eso es incorrecto. El lenguaje C no tiene un caso especial para char* . Un int* también puede apuntar a un elemento de una matriz de int . De hecho, podría escribir una biblioteca que use 0 u otro valor centinela para indicar el final de una secuencia de int , y usarlo de la misma manera que char* se usa por convención.
en tu codigo
fwrite(s, 12, 1, out);es equivalente a escribir
escriba 12 elementos de tamaño 1 byte, ubicación a partir de la dirección
shasta el archivo señalado porout.
Aquí. un char es de un byte exactamente, por lo que obtiene el resultado deseado.
¿Cómo sabe el compilador que
char* ses una cadena y no solo la dirección de uncharsingular?
Bueno, no lo hace (y no es necesario). Usted pidió (leer de s y) escribir 12 bytes, así que lo hará. Si la memoria es inaccesible, eso es un error de programación . fwrite() en sí mismo no manejará eso.
Cuidado :
s no se le asigna memoria para acceder hasta s[11] (técnicamente), será un comportamiento indefinido . Depende del programador pasar los valores válidos como argumento. En el caso de int , el tamaño es 4 bytes (generalmente, en un sistema de 32 bits) y la impresión byte por byte no le dará el resultado deseado.
En ese caso, debe utilizar fprintf() para imprimir la salida formateada .
El compilador no tendrá otra idea que char* es una dirección de un personaje. Podemos hacer que lea los siguientes caracteres incrementando la dirección del primer carácter. El caso es similar a cualquier puntero int*,long* etc., el compilador simplemente trata un puntero como algo que apunta a una dirección de su tipo.