Me confundí bastante sobre qué es qué. ¿Podría decirme cuál es cada tipo de variable?

char foo[] = "bar";
char *bar = nullptr;
char const *qux = nullptr;

Además, ¿cuál es el tipo de "bar"?

-4
Swordfish 16 oct. 2018 a las 05:39

2 respuestas

La mejor respuesta

El tipo de foo es char[4], es decir, un carácter matriz que contiene 4 char s (incluido el carácter nulo final '\0').

Los literales de cadena se pueden usar para inicializar matrices de caracteres. Si una matriz se inicializa como char str[] = "foo";, str contendrá una copia de la cadena "foo".

El tipo de bar es char *, qux es char const *, tal como lo declaró.

"bar" es literal de cadena con el tipo {{X1} }, es decir, una matriz que contiene 4 const char s (también incluye el carácter nulo final '\0').

El carácter nulo ('\0', L'\0', char16_t(), etc.) siempre se agrega al literal de cadena: así, un literal de cadena "Hello" es un const char[6] sosteniendo los caracteres 'H', 'e', 'l', 'l', 'o' y '\0'.

Aquí hay una clase auxiliar que podría dar el tipo exacto en tiempo de compilación (la idea está tomada de Effective.Modern.C ++ escrito por Scott Meyers ).

template <typename>
struct TD;

Luego úsalo como

TD<decltype(foo)> td1;
TD<decltype("bar")> td2;
TD<decltype(bar)> td3;
TD<decltype(qux)> td4;

P.ej. de clang obtendrá un mensaje de error que contiene información de tipo como:

prog.cc:12:23: error: implicit instantiation of undefined template 'TD<char [4]>'
    TD<decltype(foo)> td1;
                      ^
prog.cc:13:25: error: implicit instantiation of undefined template 'TD<char const (&)[4]>'
    TD<decltype("bar")> td2;
                        ^
prog.cc:14:23: error: implicit instantiation of undefined template 'TD<char *>'
    TD<decltype(bar)> td3;
                      ^
prog.cc:15:23: error: implicit instantiation of undefined template 'TD<const char *>'
    TD<decltype(qux)> td4;
                      ^    

Por cierto: porque los literales de cadena se tratan como lvalues y decltype da el tipo de T& para lvalues, por lo que el mensaje anterior de clang da el tipo de "bar" como una referencia de lvalue a una matriz, es decir, char const (&)[4].

2
Swordfish 16 oct. 2018 a las 10:52

La variable foo es una matriz de caracteres. Algo así como.

En algún lugar de la memoria de su computadora, el compilador ha organizado las cosas para que contenga los bytes [ 0x62, 0x61, 0x72, 0x00 ] "bar\0". El compilador agregó el \0 (0x00) final para usted, para marcar el final de la cadena. Digamos que el compilador colocó estos bytes en la dirección de memoria 0x00001000, el byte 4096.

Entonces, aunque pensamos en foo como una matriz de caracteres, la variable foo es en realidad la dirección del primer elemento de esos cuatro bytes, entonces foo = 0x00001000.

La variable bar es un puntero , que es solo un número. El número que contiene es la dirección en la memoria de lo que sea que esté "apuntando". Inicialmente, estableces bar para que sea nullptr, entonces (probablemente) bar = 0x00000000.

Está bien decir:

bar = foo;

Lo que significaría que bar ahora apunta a foo. Como dijimos que los bytes para foo se almacenaron en algún lugar de la memoria (una "dirección"), ese número simplemente se copia en bar. Así que ahora también bar = 0x00001000.

La variable qux es un puntero a una variable constante. Esta es una nota especial del compilador, por lo que puede generar un error si intenta modificar lo que apunta.

Está bien codificar:

qux = foo;
qux = bar;

Dado que todas estas cosas son indicadores de personajes.

-1
Kingsley 16 oct. 2018 a las 03:14