sintaxis funcion array c sizeof

funcion - sizeof implementation



Comportamiento confuso de sizeof con caracteres (5)

Como han mencionado otros, el estándar de lenguaje C define el tipo de constante de carácter que debe ser int . La razón histórica de esto es que C, y su predecesor B, se desarrollaron originalmente en minicomputadoras DEC PDP con varios tamaños de palabra, que admitían ASCII de 8 bits pero solo podían realizar operaciones aritméticas en registros. Las primeras versiones de C definían que int era el tamaño de palabra nativo de la máquina, y cualquier valor más pequeño que un int necesitaba ampliarse a int para pasarlo a una función, o usarlo en una expresión lógica, aritmética o bitwise , porque así era como funcionaba el hardware subyacente.

Es también por eso que las reglas de promoción de enteros aún dicen que cualquier tipo de datos más pequeño que un int se promueve a int . Las implementaciones de C también pueden usar las matemáticas de complemento en lugar de las de complemento a dos por razones históricas similares, y el hecho de que los caracteres se escapen por defecto a octal y las constantes octales comienzan con solo 0 y hex necesita /x 0x es que esos minicomputadores de DEC el tamaño de las palabras era divisible en trozos de tres bytes, pero no en nibbles de cuatro bytes.

La promoción automática a int no causa más que problemas hoy. (¿Cuántos programadores saben que multiplicar dos expresiones uint32_t juntas es un comportamiento indefinido, debido a que algunas implementaciones definen int en 64 bits de ancho, el lenguaje requiere que cualquier tipo de rango inferior al int sea ​​promovido a un int firmado , el resultado de multiplicar dos? int multiplicands tiene el tipo int , la multiplicación puede desbordar un producto firmado de 64 bits, ¿y este es un comportamiento indefinido?) Pero esa es la razón por la que C y C ++ están atascados.

Esta pregunta ya tiene una respuesta aquí:

#include <stdio.h> #include <string.h> int main(void) { char ch=''a''; printf("sizeof(ch) = %d/n", sizeof(ch)); printf("sizeof(''a'') = %d/n", sizeof(''a'')); printf("sizeof(''a''+''b''+''C'') = %d/n", sizeof(''a''+''b''+''C'')); printf("sizeof(/"a/") = %d/n", sizeof("a")); }

Este programa utiliza sizeof para calcular tamaños. ¿Por qué el tamaño de ''a'' diferente del tamaño de ch (donde ch=''a'' )?

sizeof(ch) = 1 sizeof(''a'') = 4 sizeof(''a''+''b''+''C'') = 4 sizeof("a") = 2


En C, ''a'' es constante de tipo int . No es un char . Entonces, sizeof(''a'') será igual que sizeof(int) .

sizeof(ch) es lo mismo que sizeof(char) . (El estándar C garantiza que todas las constantes alfanuméricas, y algunas otras, de la forma ''a'' pueden encajar en un char , por lo que char ch=''a''; siempre está bien definida).

Tenga en cuenta que en C ++, ''a'' es un literal de tipo char ; otra diferencia más entre C y C ++.

En C, sizeof("a") es sizeof(char[2]) que es 2. sizeof no incita la descomposición de un tipo de matriz a un puntero.

En C ++, sizeof("a") es sizeof(const char[2]) que es 2. sizeof no incita la descomposición de un tipo de matriz a un puntero.

En ambos idiomas, ''a''+''b''+''C'' es un tipo int debido, en C ++, a la promoción implícita de tipos integrales.


En primer lugar, el resultado de sizeof es el tipo size_t , que debe imprimirse con el especificador de formato %zu . Ignorando esa parte y asumiendo que int es de 4 bytes, entonces

  • printf("sizeof(ch) %d/n",sizeof(ch)); imprimirá 1 en C y 1 en C ++.

    Esto se debe a que se garantiza que un char por definición es de 1 byte en ambos idiomas.

  • printf("sizeof(''a'') %d/n",sizeof(''a'')); Imprimirá 4 en C y 1 en C ++.

    Esto se debe a que los caracteres literales son de tipo int en C, por razones históricas 1) , pero son de tipo char en C ++, porque eso es lo que dicta el sentido común (e ISO 14882).

  • printf("sizeof(''a''+''b''+''C) %d/n",sizeof(''a''+''b''+''C'')); Imprimirá 4 en ambos idiomas.

    En C, el tipo resultante de int + int + int es naturalmente int . En C ++, tenemos char + char + char . Pero el + invoca reglas de promoción de tipo implícitas, por lo que terminamos con int al final, no importa.

  • printf("sizeof(/"a/") %d/n",sizeof("a")); Imprimirá 2 en ambos idiomas.

    La cadena literal "a" es de tipo char[] en C y const char[] en C ++. En cualquier caso, tenemos una matriz que consta de un terminador a y un terminador nulo: dos caracteres.

    Como nota al margen, esto sucede porque la matriz "a" no se descompone en un puntero al primer elemento cuando se opera con el sizeof . Si provocamos una caída de la matriz, por ejemplo, escribiendo sizeof("a"+0) , obtendríamos el tamaño de un puntero (probablemente 4 u 8).

1) En algún lugar de la Edad Oscura no había tipos y todo lo que escribías se reducía a int no importaba. Luego, cuando Dennis Ritchie comenzó a cocinar juntos algún tipo de estándar de facto para C, aparentemente decidió que los literales de los personajes siempre deberían ser promovidos a int . Y luego, más tarde, cuando C se estandarizó, dijeron que los literales de los personajes son simplemente int .

Al crear C ++, Bjarne Stroustrup reconoció que todo esto no tenía mucho sentido e hizo que los literales de caracteres escribieran caracteres como debían ser. Pero el comité de C se niega obstinadamente a corregir esta falla lingüística.


Estoy asumiendo que el código fue compilado en C.
En C, ''a'' se trata como un tipo int y int tiene un tamaño de 4. En C ++, ''a'' se trata como un tipo char , y si intenta compilar su código en cpp.sh, debería devolver 1.


TL; DR : sizeof trabaja en el tipo de operando.

  • sizeof(ch) == sizeof (char) ------------------- (1)
  • sizeof(''a'') == sizeof(int) -------------------- (2)
  • sizeof (''a''+ ''b'' + ''c'') == sizeof(int) --- (3)
  • sizeof ("a") == sizeof (char [2]) ---------- (4)

Veamos cada caso ahora.

  1. ch se define para ser de tipo char , por lo que, bastante sencillo.

  2. En C, sizeof(''a'') es lo mismo que sizeof (int) , ya que una constante de caracteres tiene un tipo entero.

    Citando a C11 ,

    Una constante de carácter entero tiene tipo int . [...]

    En C ++, un literal de carácter tiene el tipo char .

  3. sizeof es un operador en tiempo de compilación (excepto cuando el operando es un VLA), por lo que se usa el tipo de expresión. Como antes, todas las constantes de caracteres enteros son de tipo int , por lo que int + int + int produce int . Así que el tipo de operando se toma como int .

  4. "a" es una matriz de dos caracteres s, ''a'' y 0 (terminador nulo) ( no, no decae al puntero hacia el primer elemento del tipo de matriz ), por lo tanto, el tamaño es el mismo que el de una matriz con dos elementos de char .

Dicho esto, finalmente, sizeof produce un resultado de tipo size_t , por lo que debe usar el especificador de formato %zu para imprimir el resultado.