que - ¿Por qué se puede asignar una cadena a un puntero char*, pero no a una matriz char[]?
punteros y arreglos en c (5)
¿Alguien puede explicar por qué esto funciona con el puntero?
char * str1;
str1 = "Hello1";
str1 = "new string";
// but not this
char str2 [] = "hello";
str2 = "four";
// or this
char str3 [];
str3 = "hello";
str3 = "hello";
En pocas palabras, porque una matriz no es un objeto de primera clase en C / C ++. La única forma de asignar una matriz es usar str (n) cpy o memcpy.
Mientras una matriz colapsa en un puntero cuando se pasa a una función, no es posible asignarla a una matriz, excepto en tiempo de compilación como inicialización.
Es simplemente porque, cuando escribes este código:
char str2 [] = "hello";
o incluso:
int arr[] = {1,2,4,4,5};
crea str2
o arr
como un puntero constante. Es por eso que no puede reasignar ningún otro valor a estos punteros, mientras que en el caso posterior está creando un puntero normal y puede asignarle cualquier valor.
Una matriz y un puntero son cosas diferentes, es por eso. Puede asignar a un puntero, pero no puede asignarlo a una matriz. Se hace una excepción especial para la inicialización de matrices de caracteres con literales de cadena.
char a[] = "Hello"; //initialize a char array with string literal. Special case, OK
char* p = "Hello"; //initializa a pointer with an array(which gets converted to pointer)
p = "My"; //assign pointer to point to another value. OK
a = "My"; //error, arrays cannot be assigned to. Use `strcpy`
Los literales de cadena (como "Hello") tienen type char[N]
donde N
es el número de caracteres (incluida la terminación ''/0''
). Una matriz se puede convertir en un puntero a su primer elemento, pero las matrices y punteros no son lo mismo, independientemente de lo que digan algunos libros malos o maestros.
El caso con punteros Funciona porque cuando asigna como str1="Hello"
, en realidad está creando un literal de cadena llamado hello asignándolo en algún lugar de la memoria, y asignando la dirección del primer carácter del literal al puntero, y como el puntero no es constante, puede asignarlo nuevamente con diferentes direcciones. Y un punto más importante a tener en cuenta es que el literal de cadena creado está en la memoria de solo lectura.
El caso con la matriz de caracteres Puede asignarle una cadena literal durante la inicialización, ya que es compatible con el idioma. Y no confundas la tarea con la inicialización. Durante la asignación, dado que es una matriz de caracteres, debe cambiar el carácter de carácter por carácter. Está intentando direccionar la primera dirección del literal de cadena al primer carácter de la matriz (el nombre de la matriz devuelve la dirección del primer elemento de la matriz). array). Y esto claramente no es correcto ya que el primer elemento no es puntero, no puede almacenar la dirección.
Por qué funciona con punteros:
Cuando dice char * str1
en C, está asignando un puntero en la memoria. Cuando escribe str1 = "Hello";
, está creando un literal de cadena en la memoria y haciendo que el puntero apunte a él. Cuando crea otra cadena literal "new string"
y la asigna a str1
, todo lo que está haciendo es cambiar hacia donde señala el puntero.
Por qué no funciona con arrays:
Cuando dice char str2 [] = "Hello"
, está creando un literal de cadena y lo está colocando en la matriz durante su definición. Está bien no dar un tamaño, ya que la matriz lo calcula y le agrega un ''/0''
. No puede reasignar nada a esa matriz sin cambiar el tamaño. Es por eso que str2 = "four"
no funcionará.
En el caso de str3
, es el mismo caso. No ha definido el tamaño de la matriz en la definición, por lo que calculó su tamaño en 0. No puede asignar nada nuevo sin cambiar el tamaño de la matriz.