strings pointer how array c string pointers sizeof

pointer - string in c



¿Qué devuelve sizeof(& array)? (3)

Diferencia entre &str y str , cuando str se declara como char str[10] ?

sizeof lectura del operador:

6.5.3.4 El operador de tamaño, 1125:
Cuando aplica el operador sizeof a un tipo de matriz, el resultado es la cantidad total de bytes en la matriz.

Entonces, de acuerdo con su declaración, sizeof(str2) da el tamaño completo de la matriz que es de 10 bytes (porque N se define como 10 y el tamaño del carácter es de 1 byte).
Mientras que en la expresión sizeof(&str2) , &str2 es la dirección de la matriz y el tamaño de la dirección que tiene 4 bytes en su sistema. (el tamaño de la dirección puede ser de 8 bytes en algunos sistemas, por ejemplo, 64 bits).

Además, &str2 es también la dirección del primer elemento en arr str2 ?

No , los valores en ambos &str2 y str son los mismos, pero semánticamente ambos son diferentes . Una es la dirección de una matriz de 10 caracteres, mientras que la otra es una dirección de un char.

Una diferencia que ha visto en su propio ejemplo es cómo son diferencias (y @ouah se explica en esta respuesta).

  • tipo de str es char[10]
  • tipo de &str es char(*)[10]

Segundo: el siguiente diagrama te ayudará a observar la otra diferencia.

for declaration: #define N 10 char str2[N] = {"Hello"}; str2 Array in memory is something like: ---------------------------------------- str +----+----+----+----+----+----+----+----+----+----++----+ |''H'' |''e'' |''l'' |''l'' |''o'' |''/0''|''/0''|''/0''|''/0''|''/0''|| ''@''| +----+----+----+----+----+----+----+----+----+----++----+ 201 202 203 204 205 206 207 208 209 210 211 ▲ ▲ ▲ ▲ | | | | |(str2) (str2 + 1) | | | |-----------------------------------------------------| |201 | | | | | (&str2) = 201 (&str2 + 1) = 211 * assuming str address start from 201 * str[N] is 10 char long 201-210, partially initialized * at uninitialized position, str2[i] = ''/0'' * location 211 is unallocated, having garbage value, access to this location is illegal-Undefined Behavior

Para el diagrama de arriba puedes escribir un código:

#include <stdio.h> #define N 10 int main(){ char str2[N]={"Hello"}; printf("/n %p, %p/n",str2, str2+1); printf("/n %p, %p/n",(&str2), (&str2+1)); }

Salida:

0xbf67e142, 0xbf67e143 0xbf67e142, 0xbf67e14c

Un enlace para la pantalla de códigos:

Observe que la primera diferencia de dirección de salida de línea es de un byte, pero en la segunda línea la diferencia es de 10 bytes porque el puntero de su matriz (como se muestra arriba en el diagrama).

De acuerdo con las reglas de matemáticas de puntero cuando agrega 1 a la variable de puntero, comienza puntos al siguiente elemento de su propio tipo que es la razón por la que las diferencias de 10 bytes porque &str2 es la dirección de la matriz.

Tercera diferencia:

Al hacer *str2 puedes acceder al primer elemento. Mientras que *(&str2) no le dará primer elemento, pero es la dirección del primer elemento.

Un ejemplo ayudará aquí:

#include <stdio.h> #define N 10 int main(){ char str2[N]={"Hello"}; printf("/n%p %c, %p %c/n",str2, *(str2), *(&str2), **(&str2)); }

salida:

0xbf587046 H, 0xbf587046 H

Enlace de teclado

En salida

str2 gives 0xbf587046 *(str2) H *(&str2) 0xbf587046 **(&str2) H

Eso significa *(&str2) == str2 y el valor es la dirección. Y, por lo tanto, *(str2) = **(&str2) valores son H

Editar: Arriba, mostré la diferencia entre &str y str donde str es una matriz de tipo char[10] .

Diferencia entre char *str y char str[] y cómo se almacenan ambos en la memoria

Supongamos que tenemos dos declaraciones como a continuación:

char *str1 = "hello"; char str2[] = "hello";

En las declaraciones anteriores str1 es un puntero a char , que apunta a un literal de cadena constante (manteniendo la dirección de la primera char h en la cadena "hello" ).

Una cadena en C es de tipo char[N] (matriz) por eso sizeof("hello") da 6 porque "hello" es una cadena de 6 caracteres largos (incluye /0 nul, terminación de cadenas, tipo de hola es char[6] ).

En la memoria, la cadena "hello" se almacena como se muestra a continuación:

str1 23 24 25 26 27 28 +----+ +----+----+----+----+----+----+ | 23 | | h | e | l | l | o | /0 | +----+ +----+----+----+----+----+----+ +-----------▲ here address of hello string is first address = 23. str1: is pointer capable to store address. "hello" consists of 6 chars

char* str1 = "hello"; básicamente almacena la dirección de la cadena de hola a la variable de puntero str1 como se muestra arriba en la figura.

Nota: Si lo que quiere últimamente en su código, cambie change str1 para señalar otra cadena. Pero no puedes modificar la cadena de hello . por ejemplo, el siguiente código es válido:

char* str1 = "hello"; // str1 points to hello str1-->"hello" str1 = "world"; //Now, str1 points to world str1-->"world"

Ahora str1 apunta a otro mundo de cuerdas constante.

str1 93 94 95 96 97 98 +----+ +----+----+----+----+----+----+ | 93 | | w | o | r | l | d | /0 | +----+ +----+----+----+----+----+----+ +-----------▲ here address of world string is first address = 93. str1: value change to point string world.

Es importante tener en cuenta: str1 apunta a cadenas constantes, por lo que no puede modificar cadenas accediendo / indexando la ubicación de la memoria, por ejemplo, str1[i] = ''A'' ; será ilegal porque está escribiendo en memoria de solo lectura y los comportamientos de esto no están definidos en el tiempo de ejecución (aunque no hay error de compilación porque sintácticamente es correcto).

De nuevo porque str1 es un sizeof(str1) puntero de sizeof(str1) dará 4 en la misma máquina.

Mi siguiente código y su ejecución:

#include <stdio.h> int main(){ char* str1="Hello"; printf("/nstr1: %s, address: %p, sizeof(str1): %u", str1, str1, sizeof(str1)); str1 = "world"; printf("/nstr1: %s, address: %p, sizeof(str1): %u", str1, str1, sizeof(str1)); return 1; }

Salida:

str1: Hello, address: 0x80485e8, sizeof(str1): 4 str1: world, address: 0x8048619, sizeof(str1): 4

Enlace de teclado

Entonces, para asignar una nueva cadena, simplemente asigno la dirección de la nueva cadena. Pero no puedo llamar a strcpy() que intentará escribir en la ubicación de memoria de solo lectura y eso es ilegal.

En la segunda declaración, char str2[] = "hello"; , str2[] es una matriz terminada /0 de caracteres (o cadena) pero NO apunta. Aviso porque en esta declaración el tamaño no se da el tamaño por defecto , tendremos ese tamaño de cadena constante "hello" que es 6. El tipo de str2 es char[6] .

Cuando hacemos char str2[] = "hello"; una matriz de char creada y una cadena de hola se copiarán en esa matriz Entonces str2 no es simplemente un puntero sino una matriz que almacena la cadena completa.

Su conceptualmente en like.

str2: 103 104 105 106 107 108 +----+----+----+----+----+----+ | h | e | l | l | o | /0 | +----+----+----+----+----+----+

Y en este caso, últimamente en su código no está str2[] = "world"; hacer str2[] = "world"; o str2 = "world" infectará será un error de tiempo de compilación.

Código de ejemplo:

#include<stdio.h> int main(){ char str2[] = "hello"; str2[] = "world"; str2 = "world"; return 1; }

Errores de compilación:

In function ''main'': Line 4: error: expected expression before '']'' token Line 5: error: incompatible types in assignment

Enlace de Codescape

Donde esta matriz str2 no es constante, podemos modificar su contenido, por ejemplo haciendo str2[2] = ''A'' es perfectamente válido. También podemos llamar a strcpy para cambiar el contenido (y el espacio de direcciones no cambiará)

strcpy(str2, "world"); str2: 103 104 105 106 107 108 +----+----+----+----+----+----+ | w | o | r | l | d | /0 | +----+----+----+----+----+----+ Note world coped into same memory space, address of world and hello string is name.

Ejemplo de código:

#include<stdio.h> int main(){ char str2[] = "hello"; printf("/nstr2: %s, address: %p, sizeof(str2): %u", str2, str2, sizeof(str2)); str2[2] = ''A''; printf("/nstr2: %s, address: %p, sizeof(str2): %u", str2, str2, sizeof(str2)); strcpy(str2, "world"); printf("/nstr2: %s, address: %p, sizeof(str2): %u", str2, str2, sizeof(str2)); return 1; }

Salida:

str2: hello, address: 0xbf58d056, sizeof(str2): 6 str2: heAlo, address: 0xbf58d056, sizeof(str2): 6 str2: world, address: 0xbf58d056, sizeof(str2): 6

Enlace de teclado

Nota: los valores de cadena son diferentes en el mismo espacio de direcciones. sizeof(str2) = 6 perfectamente entendido a partir de una respuesta anterior que es el tamaño de la matriz en bytes.

Para leer una descripción similar sobre la lectura de matriz bidimensional: ¿ Diferencia entre char* str[] y char str[][] y cómo ambas tiendas están en la memoria?

Después de la pregunta: ¿Cómo es que la dirección de una matriz es igual a su valor en C?

#include <stdio.h> #define N 10 char str2[N]={"Hello"}; int main(){ printf("sizeof(str2): %d bytes/n", sizeof(str2)); printf("sizeof(&str2): %d bytes/n", sizeof(&str2)); return 0; }

Salida:

sizeof(str2): 10 bytes sizeof(&str2): 4 bytes

Sé que str2 solo es la dirección del primer elemento en el conjunto str2 . Y que cuando str2 es un argumento de sizeof , devuelve el tamaño de la matriz completa str2.

Además, &str2 es también la dirección del primer elemento en arr str2 pero de tipo diferente ( char (*)[N] == puntero a matriz). Pero ¿cómo se comporta &str2 cuando se trata de un argumento de sizeof ?


&str2 es un puntero. Entonces, solo está viendo el tamaño de un puntero en su plataforma.


str2 es de tipo char [10] (es decir, matriz 10 of char`)

&str2 es del tipo char (*)[10] (es decir, apunta a una matriz 10 de char ).

Entonces sizeof (&str2) produce el tamaño de un objet de tipo de puntero char (*)[10]