capítulo 3 - tipos de datos y expresiones en c.pdf

23
ITSON Manuel Domitsu Kono Capítulo 3 Tipos de Datos y Expresiones en C Tipos De Datos Los programas que escribimos para resolver un problema dado, reciben información del usuario, la procesan y después nos regresan resultados. Esta información puede ser números o textos (secuencia de caracteres alfanuméricos). Debido a esto, todos los lenguajes proveen al programador con una serie de facilidades para manejar algunos tipos de datos. Los tipos de datos son el conjunto de valores que una variable puede asumir. En C estos tipos de datos se pueden clasificar en tipos básicos y tipos derivados: Los tipos básicos son los tipos enteros y los tipos flotantes. Los tipos derivados son tipos de datos construidos a partir de los tipos básicos y son los apuntadores, los arreglos, las estructuras y las uniones. Los arreglos se estudiarán en el Capítulo 7: Arreglos, los apuntadores en el Capítulo 8: Apuntadores, las estructuras y uniones en el Capítulo 12: Tipos de Datos Definidos por el Usuario. Tipos Enteros Los tipos enteros de C nos permiten representar un subconjunto de los números enteros. Cada uno de los tipos enteros cubre un rango de los números enteros y requiere para almacenarse de un cierto número de bytes. Los tipos enteros básicos de C son: char e int. Al tipo int se le puede aplicar el calificador short, long o long long para producir enteros de otras longitudes: short int (o simplemente short), long int (o simplemente long) y long long int (o simplemente long long). El estándar de C sólo establece el tamaño del tipo char, los tamaños de los otros tipos enteros dependen de la implementación del compilador de C. Las únicas restricciones son las siguientes: El tipo char es siempre de un byte (8 bits). El tipo short es de al menos 16 bits. El tipo int es mayor o igual al tipo short .

Upload: rholvis-brito

Post on 14-Apr-2016

91 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Capítulo 3 - Tipos de Datos y Expresiones en C.pdf

ITSON Manuel Domitsu Kono

Capítulo 3

Tipos de Datos y Expresiones en C

Tipos De Datos Los programas que escribimos para resolver un problema dado, reciben información del usuario, la procesan y después nos regresan resultados. Esta información puede ser números o textos (secuencia de caracteres alfanuméricos). Debido a esto, todos los lenguajes proveen al programador con una serie de facilidades para manejar algunos tipos de datos. Los tipos de datos son el conjunto de valores que una variable puede asumir. En C estos tipos de datos se pueden clasificar en tipos básicos y tipos derivados: Los tipos básicos son los tipos enteros y los tipos flotantes. Los tipos derivados son tipos de datos construidos a partir de los tipos básicos y son los apuntadores, los arreglos, las estructuras y las uniones. Los arreglos se estudiarán en el Capítulo 7: Arreglos, los apuntadores en el Capítulo 8: Apuntadores, las estructuras y uniones en el Capítulo 12: Tipos de Datos Definidos por el Usuario.

Tipos Enteros Los tipos enteros de C nos permiten representar un subconjunto de los números enteros. Cada uno de los tipos enteros cubre un rango de los números enteros y requiere para almacenarse de un cierto número de bytes. Los tipos enteros básicos de C son: char e int. Al tipo int se le puede aplicar el calificador short, long o long long para producir enteros de otras longitudes: short int (o simplemente short), long int (o simplemente long) y long long int (o simplemente long long). El estándar de C sólo establece el tamaño del tipo char, los tamaños de los otros tipos enteros dependen de la implementación del compilador de C. Las únicas restricciones son las siguientes:

• El tipo char es siempre de un byte (8 bits). • El tipo short es de al menos 16 bits. • El tipo int es mayor o igual al tipo short.

Page 2: Capítulo 3 - Tipos de Datos y Expresiones en C.pdf

26 Tipos de Datos y Expresiones en C

ITSON Manuel Domitsu Kono

• El tipo long es de al menos 32 bits. • El tipo long es mayor o igual al tipo int. • El tipo long long es de al menos 64 bits. • El tipo long long es mayor o igual al tipo long.

A todos los tipos enteros anteriores se les puede aplicar los calificadores signed y unsigned. Los enteros unsigned son siempre positivos o cero. Los enteros signed pueden ser positivos, cero o negativos. Si en el tipo char se omite el calificador de signo, depende de la implementación si es signed o unsigned. Sin embargo char, signed char y unsigned char deben tratarse como tres tipos distintos y para almacenar números sólo deben usarse los tipos signed char y unsigned char. En los demás tipos enteros si se omite el calificador de signo el entero es signed. En la tabla 3.1, se muestran los rangos de valores que se pueden almacenar en los diferentes tamaños de enteros.

Tabla 3.1. Rango de Enteros Tamaño (Bits) Con o sin signo Rango

8 Sin 0 – 255

Con -128 – 127

16 Sin 0 - 65,535

Con -32,768 - 32,767

32 Sin 0 - 4,294,967,295

Con -2,147,483,648 - 2,147,483,647

64 Sin 0 - 18,446,744,073,709,551,615

Con -9,223,372,036,854,775,807 – 9,223,372,036,854,775,807

Para almacenar texto en una computadora, cada carácter se codifica mediante un número entero. Estos códigos pueden almacenarse en variables de cualquiera de los tipos enteros, normalmente en variables de tipo int o char. Una de las formas de codificación más empleada se conoce como Código ASCII. ASCII son las siglas de un organismo (American Standard Code for Information Interchange) que establece normas para el intercambio de información en dispositivos de comunicación y de cómputo. En este código cada carácter se representa mediante 7 bits, lo que nos permite tener 27 = 128 caracteres diferentes. En la tabla 3.2, se muestra la tabla de caracteres del código ASCII. Los caracteres de control, que son los primeros 32 de la tabla no son caracteres desplegables o imprimibles sino que permiten realizar ciertas funciones de control en los dispositivos de entrada / salida. Por ejemplo podemos usar algunos de esos caracteres para hacer saltos de línea, de página, etc.

Tabla 3.2. Tabla de caracteres del Código ASCII

Page 3: Capítulo 3 - Tipos de Datos y Expresiones en C.pdf

Capítulo 3 Tipos de Datos y Expresiones en C 27

ITSON Manuel Domitsu Kono

Dec. Hex Car. Nem. Dec. Hex. Car. Dec. Hex. Car. Dec. Hex. Car. 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F

\a \b \t \n \v \f \r

NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI

DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM

SUB ESC FS GS RS US

32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63

20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F

SP ! " # $ % & , ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ?

64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95

40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F

@ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _

96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127

60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F

` a b c d e f g h i j k l

m n o p q r s t u v w x y z { | } ~

Como el conjunto de caracteres del Código ASCII sólo contiene los caracteres empleados en el idioma inglés, cuando el uso de las computadoras se extendió a otros países de Europa y Latinoamérica se vio la necesidad de extender el código ASCII. Como normalmente cada caracter se almacena en un byte, hay un bit extra y esto permite agregar 128 caracteres extra al código ASCII. Al código resultante se le llama código ASCII extendido. Hay varias variantes de código ASCII para acomodarse a diferentes regiones del mundo, pero en todas ellas, los primeros 128 caracteres son los caracteres del código ASCII

Tipos Flotantes Los tipos flotantes de C nos permiten representar un subconjunto de los números reales. Cada uno de los tipos flotantes cubre un rango de los números reales y requiere para almacenarse de un cierto número de bytes. Los tipos flotantes básicos de C son: float, punto flotante de precisión normal y double, punto flotante de doble precisión. Al tipo doble se le puede aplicar el calificador long para obtener long double un punto flotante de

Page 4: Capítulo 3 - Tipos de Datos y Expresiones en C.pdf

28 Tipos de Datos y Expresiones en C

ITSON Manuel Domitsu Kono

precisión extendida. Igual que con los enteros, el tamaño de los flotantes depende de la implementación del compilador. Las únicas restricciones son las siguientes:

• El tipo double tiene al menos la misma precisión que el tipo float. • El tipo long double tiene al menos la misma precisión que el double.

En la mayoría de los compiladores de C, los tipos float y double siguen el formato del estándar IEEE 754. En la tabla 3.3 se muestran el tamaño, rango y precisión de los tipos float y double de acuerdo al estándar IEEE 754.

Tabla 3.3. Tipos float y double de acuerdo al estándar IEEE 754

Tipos flotantes Tamaño (Bytes) Rango Precisión

(cifras)

float (flotante) 4 3.4E-38 - 3.4E+38 7

double (doble) 8 1.7E-308 - 1.7E+308 15

La precisión nos dice cual es la mínima diferencia que pueden tener dos números para que se les considere diferentes. Por ejemplo en el caso de los números flotantes, si dos números son iguales hasta la séptima cifra y sólo difieren de la octava cifra en adelante, son considerados como iguales. Un punto importante acerca del tipo flotante es el hecho de que no todos los números reales pueden representarse en los tipos flotantes aunque su valor esté en el rango de uno ellos.

Expresiones Procesar datos implica combinarlos de alguna forma, dando como resultado otros datos. Para especificar como deben de combinarse esos datos se utilizan las expresiones. Una expresión es una combinación de operandos y operadores. Los operandos representan valores y los operadores indican las operaciones a realizarse con ellos, para obtener un resultado.

Operandos Hay tres tipos de operandos en C: Constantes, Variables y Llamadas a funciones.

Constantes

Page 5: Capítulo 3 - Tipos de Datos y Expresiones en C.pdf

Capítulo 3 Tipos de Datos y Expresiones en C 29

ITSON Manuel Domitsu Kono

Un valor que no es modificado durante la ejecución del programa se denomina constante. Las constantes en un programa en C pueden ser de los siguientes tipos: Enteras, flotantes, de carácter y de cadena.

Constantes Enteras Una constante entera es un número entero en el rango 0 al valor máximo permitido en el tipo unsigned long long (las constantes negativas son simplemente constantes sin signo con el operador unario menos). Si el número es mayor al que puede representarse en el tipo unsigned long long, ocurre un sobreflujo1 sin aviso. El tipo entero en el que se almacena la constante se determina de la siguiente manera:

• Si el número es está en el rango de los tipos char, signed char unsigned char, short, unsigned short o int el compilador lo almacena como un int. Si deseamos que ese número se almacene como de un tipo entero de mayor rango deberá agregársele el sufijo del tipo deseado, U para unsigned, L para long, UL para unsigned long, LL para long long, o ULL para unsigned long long. (Los sufijos se pueden escribir en minúsculas también).

• Cualquier otro número por encima del rango int, se almacenará como del tipo del

entero de menor rango que lo contenga y deberá escribirse con el sufijo de ese rango. Si deseamos que ese número se almacene como de un tipo de un entero de mayor rango deberá agregársele el sufijo del tipo deseado.

Por ejemplo, si en un compilador de C, el tipo short ocupa dos byte, los tipos int y long ocupan 4 bytes y el tipo long long ocupa 8 bytes, entonces, las siguientes constantes se almacenan como de tipo int:

183 -16 43871 -9074 1234567809 -12345678209

Las siguientes constantes se almacenan como de tipo unsigned:

183U 43871U 1234567809U 3423451000U

Las siguientes constantes se almacenan como de tipo long (que para el compilador de este ejemplo, también se almacenan en 4 bytes, como el tipo entero:

183L

1 El concepto de sobreflujo se explica en la sección sobre operadores aritméticos.

Page 6: Capítulo 3 - Tipos de Datos y Expresiones en C.pdf

30 Tipos de Datos y Expresiones en C

ITSON Manuel Domitsu Kono

-16L 43871L -9074L 1234567809L -12345678209L

Las siguientes constantes se almacenan como de tipo unsigned long:

183UL 43871UL 1234567809UL 3423451000UL

Las siguientes constantes se almacenan como de tipo long long:

183LL -16LL 43871LL -9074LL 1234567809LL -1234567809LL 1234567890123456789LL -1234567890123456789LL

Por último, Las siguientes constantes se almacenan como de tipo unsigned long long: 183ULL; 43871ULL; 1234567809ULL; 1234567890123456789ULL;

Constantes de punto flotante Las constantes de punto flotante contienen un punto decimal (por ejemplo 123.4) o un exponente (1e-2) o ambos. Todas las constantes de punto flotante son dobles. Podemos forzar a una constante al tipo float usando el sufijo f o F, y a long double con el sufijo l o L. Las siguientes constantes son de tipo float: 1.34F; 1.256e-03F Las siguientes constantes son de tipo double: 1.34; 1.256e-03 Las siguientes constantes son de tipo long double: 1.34L; 1.256e-03L

Constantes de carácter

Page 7: Capítulo 3 - Tipos de Datos y Expresiones en C.pdf

Capítulo 3 Tipos de Datos y Expresiones en C 31

ITSON Manuel Domitsu Kono

Una constante de carácter se almacena en un entero y representa el código asociado al carácter en la implementación del compilador. En la mayoría de los casos, el código es el Código ASCII. Una constante de carácter puede escribirse de las siguientes formas:

• Un carácter delimitado por apóstrofes. Por ejemplo: 'a', 'Z'.

• Los caracteres de control y algunos caracteres difíciles de imprimir pueden representarse mediante una secuencia de escape delimitada por apóstrofes. Una secuencia de escape son ciertos caracteres precedidos por una diagonal invertida (\) o uno o más dígitos hexadecimales precedidos de los caracteres \x. Por ejemplo: '\n', '\a'. En la tabla 3.4 se muestra la lista de las secuencias de escape soportadas por C.

Tabla 3.4. Caracteres expresados como secuencias de escape

Secuencia Código ASCII Mnemónico Significado

\a \b \f \n \r \t \v \\ \' \" \?

\xHHH

7 8 12 10 13 9 11 92 39 34 63

\xHHH

BEL BS FF LF CR HT VT \ ' " ?

Suena la bocina Regresa un espacio Salto de página Salto de línea Regreso de carro Tab horizontal Tab vertical Diagonal invertida Apóstrofe Comillas Signo de interrogación Valor hexadecimal de uno a tres dígitos

Expresión constante Una expresión constante es una expresión cuyos operandos son sólo constantes. Estas expresiones son evaluadas por el compilador al tiempo de compilación en lugar de evaluarse al tiempo de ejecución y por lo tanto pueden utilizarse en el lugar en que se usa una constante. Por ejemplo, en cualquier lugar en que podamos usar la constante

8 también podemos usar la expresión constante

4 + 4 o

4 * 2

Constantes de tipo cadena

Page 8: Capítulo 3 - Tipos de Datos y Expresiones en C.pdf

32 Tipos de Datos y Expresiones en C

ITSON Manuel Domitsu Kono

Una constante de tipo cadena es una secuencia de caracteres delimitada por comillas. La secuencia de caracteres puede contener secuencias de escape. Por ejemplo:

"Hola" "Instituto Tecnológico de Sonora" "\aDespierta!\a"

Variables Un dato que puede variar su valor durante la ejecución de un programa es considerado como una variable. Podemos tener variables de cualquier tipo de datos. Todas las variables deben declararse antes de usarse. Al declarar una variable estamos haciendo dos cosas: Primero, le informamos al compilador de la existencia de una variable cuyo nombre y tipo se especifican en la declaración; y segundo le pedimos al compilador que nos reserve espacio en la memoria para la variable. La sintaxis para declarar una variable es la siguiente:

tipo nomVar1[ = exp1][, nomVar2[ = exp2]...] nomVar1, nomVar2 ... son los nombre de las variables que se están declarando. Las variables son del tipo de dato tipo. Las variables pueden inicializarse al momento de su declaración. exp1, exp2, ... son las expresiones a cuyos valores se inicializan las variables nomVar1, nomVar2 ..., respectivamente. Por lo general exp1, exp2, ... son expresiones constantes aunque en el Capítulo 6: Funciones se verá que las variables locales pueden inicializarse a cualquier expresión que pueda evaluarse al momento en que las variables son creadas. Por ejemplo:

int a, b, c, x = 10; float l, resultado, producto = 8.75; char respuesta;

Calificador const El calificador const puede aplicarse a la declaración de cualquier variable para especificar que su valor no cambia, comportándose como una constante. Por ejemplo:

const int x = 8; const float g = 9.81;

Una variable con el calificador const debe ser inicializada al momento de su declaración. Cualquier intento de modificar su valor posteriormente, genera un error por parte del compilador.

Page 9: Capítulo 3 - Tipos de Datos y Expresiones en C.pdf

Capítulo 3 Tipos de Datos y Expresiones en C 33

ITSON Manuel Domitsu Kono

Llamadas a funciones Una función es un subprograma que realiza una determinada tarea y que al terminar regresa un valor. La llamada a la función es la orden de que se ejecute ese subprograma. Llamamos a una función cuando escribimos su nombre dentro de una expresión. Al evaluar la expresión, el programa substituye la llamada a la función por el valor que regresa ésta. Por ejemplo suponga la siguiente expresión:

3.0 + sqrt(4.0) Al estar evaluando esta expresión, la computadora se encuentra con el término sqrt(4.0). sqrt es el nombre de una función de la biblioteca estándar de C que nos regresa la raíz cuadrada de su argumento, 4.0 en este caso sqrt(4.0) es la llamada a la función, esto es, le pedimos a la computadora que ejecute las instrucciones que calcularán la raíz cuadrada de 4.0. El programa substituye el valor regresado por la función: 2.0, en lugar de sqrt(4.0), quedando la expresión:

3.0 + 2.0

Algunas Funciones de la Biblioteca Estándar de C En la tabla 3.5 se muestran algunas de las funciones matemáticas y de conversión de la biblioteca estándar de C.

Tabla 3.5. Algunas funciones de la biblioteca estándar de C atan() Función: Regresa: Parámetros:

Calcula el arco tangente del argumento. Un doble en el rango de -π/2 a π/2, que representa el ángulo en radianes. Un doble.

cos() Función: Regresa: Parámetros:

Calcula el coseno de un ángulo expresado en radianes. Un doble en el rango -1.0 a 1.0, que representa el coseno. Un doble que representa el ángulo en radianes.

exp() Función: Regresa: Parámetros: Comentarios:

Calcula ex. Un doble. Un doble. Algunos valores del argumento producen resultados que exceden el rango de un doble o que no se pueden calcular. Cuando el valor correcto excede el rango de un doble, la función regresa el valor HUGE_VAL. Si el resultado es menor al valor mínimo en el rango de los dobles, la función regresa 0.0.

Tabla 3.5. Algunas funciones de la biblioteca estándar de C. (Cont.) fabs() Función:

Calcula el valor absoluto de un número doble.

Page 10: Capítulo 3 - Tipos de Datos y Expresiones en C.pdf

34 Tipos de Datos y Expresiones en C

ITSON Manuel Domitsu Kono

Regresa: Parámetros:

Un doble positivo. Un doble.

log() Función: Regresa: Parámetros: Comentarios:

Calcula el logaritmo natural de un número. Un doble. Un doble mayor que 0.0. Si el valor del argumento es menor o igual a cero, la función regresa el valor negativo HUGE_VAL.

pow() Función: Regresa: Parámetros: Comentarios:

Calcula xy. Un doble, el valor de xy. Dos dobles. Si x es menor o igual a cero y debe ser un número entero. Algunos valores de los argumentos producen resultados que exceden el rango de un doble o que no se pueden calcular. Cuando el valor correcto excede el rango de un doble, la función regresa el valor HUGE_VAL. Si el valor del argumento x es menor o igual a cero y el argumento y no es un número entero, la función regresa el valor negativo HUGE_VAL. Si ambos argumentos son cero la función regresa 1.

sin() Función: Regresa: Parámetros:

Calcula el seno de un ángulo expresado en radianes. Un doble en el rango -1.0 a 1.0 que representa el seno. Un doble que representa el ángulo en radianes.

sqrt() Función: Regresa: Parámetros: Comentarios:

Calcula la raíz cuadrada positiva de un número. Un doble positivo. Un doble positivo. Si x es negativo, la función regresa 0.

tan() Función: Regresa: Parámetros: Comentarios:

Calcula la tangente de un ángulo expresado en radianes. Un doble, la tangente del argumento. Un doble que representa el ángulo en radianes. Para ángulos cercanos a π/2 o -π/2, la función regresa 0.

toupper() Función: Regresa: Parámetros:

Convierte las letras minúsculas a mayúsculas. Un entero, el código ASCII de la mayúscula del código ASCII del argumento si éste representa una minúscula, si no regresa el carácter sin cambio. Un entero en el rango EOF (-1) a 255.

Operadores De C

Page 11: Capítulo 3 - Tipos de Datos y Expresiones en C.pdf

Capítulo 3 Tipos de Datos y Expresiones en C 35

ITSON Manuel Domitsu Kono

En el lenguaje C, cada uno de los tipos de datos básicos: Enteros y flotantes, tiene su propia aritmética, la aritmética de enteros y la aritmética de punto flotante. Cada aritmética tiene sus propias reglas y opera sólo sobre los datos de su mismo tipo. La aritmética de enteros opera sólo con enteros y produce resultados enteros. Lo mismo sucede con los flotantes. No se permiten mezclas de enteros y flotantes. Cuando una operación existe en ambas aritméticas, éstas comparten el mismo símbolo para el operador. Por ejemplo el símbolo para la suma en las dos aritméticas es (+). El compilador sabe que aritmética aplicar de acuerdo al tipo de los operandos. Algunos de los operadores de C son unarios, es decir, operan sobre un sólo operando, otros son binarios, operan sobre dos operandos y hay un operador terciario, trabaja sobre tres operandos.

Operadores aritméticos

Operadores más (+) y menos (-) El operador unario menos, -, le cambia el signo al operando al que está asociado. Si el operando es un entero, el resultado es un entero, si el operando es flotante el resultado es flotante. El operador unario más, +, sólo existe por simetría ya que no hace nada. Ejemplos:

-56 -34.78 +25 igual a 25

Operadores de multiplicación (*), división (/) y módulo (%) El operador de multiplicación, *, nos da el producto de sus operandos. Si los operandos son enteros, el resultado es un entero, si los operandos son flotantes el resultado es flotante. El operador de división, /, nos da la parte entera del cociente si sus operandos son enteros. Si los operandos son flotantes el resultado es flotante. El operador módulo, %, sólo opera con operandos enteros y nos da el residuo de la división de sus operandos. Ejemplos:

Expresión Resultado

45 * 23 1035 18.27 * 2.975 54.3532 25 / 4 6 25.0 / 4.0 6.25 25 % 4 1

Page 12: Capítulo 3 - Tipos de Datos y Expresiones en C.pdf

36 Tipos de Datos y Expresiones en C

ITSON Manuel Domitsu Kono

Operadores de suma (+) y resta (-) Los operadores de suma, +, y resta, -, nos dan la suma y la diferencia de sus operandos, respectivamente. Si los operandos son enteros, el resultado es un entero, si los operandos son flotantes el resultado es flotante. Ejemplos:

Expresión Resultado 4 + 23 27 8.2 * 29.75 37.95 25 – 4 21 2.5 - 1.4 1.1

Sobreflujo Es posible que cuando un programa está ejecutando, una expresión tome un valor incorrecto. Por ejemplo suponga la siguiente declaración de variable: unsigned x = 4000000000; Si para el compilador el entero ocupa 4 bytes, la expresión: 2 * x no toma el valor de 8000000000. Como la operación de multiplicación es entre dos números enteros sin signo, el resultado debe ser un entero sin signo. Sin embargo el número 8000000000 se sale del rango de los enteros sin signo que es 0 - 4294967295. Esta condición se conoce como sobreflujo entero. Normalmente, cuando ocurre un sobreflujo entero, el programa continúa su ejecución, pero los resultados son erróneos. Por esta razón, el programador debe asegurarse que durante la ejecución del programa, los valores que toma una expresión, estén dentro de los rangos permitidos.

Precedencia y asociatividad de operadores Los operadores tienen reglas de precedencia y asociatividad que determinan precisamente como se evalúan las expresiones. La tabla 3.7 resume las reglas de precedencia y asociatividad de todos los operadores, incluyendo algunos que aún no han sido tratados. Los operadores situados en la misma línea tienen la misma precedencia, las filas están colocadas por orden de precedencia decreciente. Si una expresión contiene más de un operador, el orden en que se efectúan las operaciones está dado por las siguientes reglas.

Tabla 3.6. Precedencia y asociatividad de los operadores de C

Page 13: Capítulo 3 - Tipos de Datos y Expresiones en C.pdf

Capítulo 3 Tipos de Datos y Expresiones en C 37

ITSON Manuel Domitsu Kono

Operador Asociatividad

() [] -> . Izquierda a derecha

! ~ ++ -- - (tipo) * & sizeof Derecha a izquierda

* / % Izquierda a derecha

+ - Izquierda a derecha

<< >> Izquierda a derecha

< <= > >= Izquierda a derecha

== != Izquierda a derecha

& Izquierda a derecha

^ Izquierda a derecha

| Izquierda a derecha

&& Izquierda a derecha

|| Izquierda a derecha

?: Derecha a izquierda

= += -= *= /= %= <<= >>= &= ^= |= Derecha a izquierda

, Izquierda a derecha

• Las expresiones encerradas entre paréntesis son evaluadas primero.

• Si en una expresión hay operadores de diferente precedencia, la operación del

operador de mayor precedencia se realiza primero.

• Si en una expresión hay operadores de igual precedencia, las operaciones se realizan en el orden dado por la asociatividad de los operadores.

Conversión de tipos implícita Cuando un operador tiene operandos de diferente tipo, estos se convierten a un tipo común, en forma implícita o automática, de acuerdo con las siguientes reglas:

Promoción entera

Un char o un short con o sin signo se convierten a int. Si el tipo int puede representar todos los valores de unsigned short, este se convierte a int. Si no se convierte a unsigned. Este proceso se conoce como promoción entera.

Conversiones aritméticas

Page 14: Capítulo 3 - Tipos de Datos y Expresiones en C.pdf

38 Tipos de Datos y Expresiones en C

ITSON Manuel Domitsu Kono

• Si algún operando es de tipo long double, el otro operando es convertido a long double y el resultado es de tipo long double.

• Si no se aplica la regla anterior y si algún operando es de tipo double, el otro se

convierte a double y el resultado es double.

• Si no se aplica la regla anterior y si algún operando es de tipo float, el otro se convierte a float y el resultado es float.

• Si no se aplica la regla anterior entonces se realiza la promoción entera en ambos

operandos y si algún operando es de tipo unsigned long long, el otro se convierte a unsigned long long y el resultado es unsigned long long.

• Si no se aplica la regla anterior, y si algún operando es de tipo long long y el otro es

de tipo unsigned long, entonces si un long long puede representar todos los valores de un unsigned long el operando unsigned long es convertido a long long y el resultado es long long. Si no ambos operandos son convertidos a unsigned long long y el resultado es unsigned long long

• Si no se aplica la regla anterior y si algún operando es de tipo unsigned long, el otro se convierte a unsigned long y el resultado es unsigned long.

• Si no se aplica la regla anterior, y si algún operando es de tipo long y el otro es de

tipo unsigned, entonces si un long puede representar todos los valores de un unsigned el operando unsigned es convertido a long y el resultado es long. Si no ambos operandos son convertidos a unsigned long y el resultado es unsigned long.

• Si no se aplica la regla anterior, y si algún operando es de tipo long, el otro se

convierte a long y el resultado es long.

• Si no se aplica la regla anterior, y si algún operando es de tipo unsigned, el otro se convierte a unsigned y el resultado es unsigned.

• Si no se pueden aplicar ninguna de las reglas anteriores, los operandos deben de

ser del tipo int y el resultado será de tipo int. En resumen cuando un operador tiene operandos de diferente tipo, el operando del tipo es promovido al tipo mayor y el resultado es del menor tipo mayor. Suponga que una variable es el operando al que se le cambia el tipo en una conversión implícita. Esto no quiere decir que la variable ni su contenido cambian de tipo. Lo que cambia de tipo es una copia del valor de la variable la cual se almacena en una localidad de memoria temporal (que puede ser en la memoria principal o en un registro en el CPU) y la cual se utiliza para efectuar los cálculos. Ejemplos:

Page 15: Capítulo 3 - Tipos de Datos y Expresiones en C.pdf

Capítulo 3 Tipos de Datos y Expresiones en C 39

ITSON Manuel Domitsu Kono

Expresión Resultado 12 + 3.45 * 2 12 + 6.9000000000000000000 18.90000000000000000 Un flotante. 4 % 3 - sqrt(45.89) 4 % 3 - 6.774216000000000000 1 - 6.774216000000000000 -5.774216000000000000 Un flotante. (89 / 7)/(95 % 15) 12 / 5 2 Un entero.

Conversión de tipos explícita Se puede forzar la conversión explícita de una expresión a un tipo dado usando el operador cast, cuya sintaxis es la siguiente:

(tipo)expresión En este caso la expresión se convierte al tipo dado de acuerdo a las reglas ya establecidas. Por ejemplo supongamos la siguiente declaración:

int x = 1000000, y = 4000; la expresión

x * y no da como resultado 4000000000 ya que como x e y son enteros su producto es un entero. El número 4000000000 excede el rango de los enteros y por lo tanto ocurre un sobreflujo. Una solución es usar el operador cast para cambiar uno de los operandos a long de manera que dada las conversiones implícitas la operación sea entre long y el resultado sea long, con lo cual ya no hay sobreflujo.

(long)x * y Como segundo ejemplo suponga que se va a promediar una serie de números que representan las edades de los alumnos de un grupo y que la suma de las edades y el número de alumnos se encuentra en las variables enteras sumaEdades y nAlumnos. El cociente:

sumaEdades/nAlumnos producirá como resultado sólo la parte entera del cociente. Si se desea un resultado con parte fraccionaria, podemos hacer lo siguiente:

(float)sumaEdades/nAlumnos

Page 16: Capítulo 3 - Tipos de Datos y Expresiones en C.pdf

40 Tipos de Datos y Expresiones en C

ITSON Manuel Domitsu Kono

Al igual que en el caso de la conversión implícita, la conversión de tipo explícita tampoco modifica el tipo ni contenido de la variable cuyo valor es convertido. Sólo se modifica una copia temporal usada para realizar los cálculos.

Operadores relacionales Muchas de las operaciones de C nos dan como resultado un valor que deseamos interpretarlo como falso o verdadero. En C un dato que puede ser falso o verdadero se representa mediante un entero. El valor de falso se representa mediante un cero, mientras que cualquier entero diferente de cero es interpretado como verdadero. Los operadores relacionales nos permiten comparar dos valores. El resultado de la comparación es un entero: 0 si es falso o 1 si es verdadero. Todos los operadores relacionales de C son binarios. Esto es, operan sobre dos operandos. Los operadores relacionales son:

Operador menor que (<) El operador menor que, < da como resultado 1 (verdadero) si su operando izquierdo es menor que el derecho y 0 (falso) en caso contrario.

Operador menor o igual que (<=) El operador menor o igual que, <= da como resultado 1 (verdadero) si su operando izquierdo es menor o igual que el derecho y 0 (falso) en caso contrario.

Operador mayor que (>) El operador mayor que, > da como resultado 1 (verdadero) si su operando izquierdo es mayor que el derecho y 0 (falso) en caso contrario.

Operador mayor o igual que (>=) El operador mayor o igual que, >= da como resultado 1 (verdadero) si su operando izquierdo es mayor o igual que el derecho y 0 (falso) en caso contrario. Ejemplos:

Expresión Resultado 4 < 3 0 5 >= 2 1

Al trabajar con operadores relacionales hay que tener cuidado con expresiones como la que sigue:

Page 17: Capítulo 3 - Tipos de Datos y Expresiones en C.pdf

Capítulo 3 Tipos de Datos y Expresiones en C 41

ITSON Manuel Domitsu Kono

13 > 9 > 4 Aquí aparentemente tratamos de decir que 13 es mayor que 9 y 9 es mayor que 4 por lo tanto esperaríamos que el resultado fuera 1 (verdadero). Sin embargo, si vemos la asociatividad del operador >, vemos que es de izquierda a derecha y por lo tanto la expresión anterior equivale a:

(13 > 9) > 4 1 > 4 0

por lo tanto el resultado obtenido es 0 (falso) en lugar de verdadero. La forma correcta de escribir la expresión a fin de que dé el resultado esperado se verá en la sección: Operadores lógicos.

Operadores de igualdad Al igual que los operadores relacionales, los operadores de igualdad nos permiten comparar dos valores. El resultado de la comparación es un entero: 0 si es falso o 1 si es verdadero. Los operadores relacionales también son binarios. Los operadores relacionales son:

Operador igual a (==) El operador igual a, == da como resultado 1 (verdadero) si su operando izquierdo es igual al derecho y 0 (falso) en caso contrario.

Operador diferente a (!=) El operador diferente a, != da como resultado 1 (verdadero) si su operando izquierdo es diferente al derecho y 0 (falso) en caso contrario. Ejemplos:

Expresión Resultado 4 == 3 0 5 != 2 1

Al igual que con los operadores relacionales, ciertas expresiones formadas con los operadores de igualdad pueden producir resultados inesperados. Por ejemplo, suponga que tenemos tres variables enteras: a, b y c todas con el mismo valor. La expresión:

a == b == c Aquí aparentemente nos preguntamos si el contenido de las tres variables es el mismo. La respuesta esperada es 1. Sin embargo, si vemos la asociatividad del operador ==, vemos que es de izquierda a derecha y por lo tanto la expresión anterior equivale a:

Page 18: Capítulo 3 - Tipos de Datos y Expresiones en C.pdf

42 Tipos de Datos y Expresiones en C

ITSON Manuel Domitsu Kono

(a == b) == c 1 == c

por lo tanto el resultado obtenido sólo puede ser verdadero si c vale 1 o falso en los demás casos.

Operadores lógicos Los operadores lógicos sólo operan sobre operandos enteros los cuales representan valores de falso (cero) o verdadero (diferente de cero). Los operandos lógicos normalmente se utilizan para construir expresiones más complejas a partir de expresiones que contienen los operadores relacionales o de igualdad.

Operador de negación (!) El operador unario de negación, !, convierte un operando con valor de falso (0) a verdadero (1) y un valor de verdadero (diferente de cero) a falso (0).

Operador de intersección (&&) El operador de intersección, &&, nos da como resultado verdadero (1) sólo sí los dos operandos son verdaderos (diferentes de cero) y falso (cero) en caso contrario.

Operador de unión (||) El operador de unión, ||, nos da como resultado verdadero (1) si al menos uno de los dos operandos es verdadero (diferentes de cero) y falso (cero) en caso contrario.

Evaluación en corto circuito En la evaluación de expresiones que tienen operandos && y ||, el proceso de evaluación se detiene tan pronto se conoce si el resultado es falso o verdadero. Esto se conoce evaluación en corto circuito. Suponga que tenemos la siguiente expresión: exp1 && exp2 donde exp1 y exp2 son expresiones. Supóngase que al comenzar a evaluar la expresión anterior se encuentra que exp1 es falsa (vale 0), entonces exp2 no evalúa ya que independientemente del valor de exp2, el valor de exp1 && exp2 es falso. En forma similar, en la evaluación de la expresión exp1 || exp2 si se encuentra que exp1 es verdadera, entonces exp2 no evalúa ya que independientemente del valor de exp2, el valor de exp1 && exp2 es verdadero.

Page 19: Capítulo 3 - Tipos de Datos y Expresiones en C.pdf

Capítulo 3 Tipos de Datos y Expresiones en C 43

ITSON Manuel Domitsu Kono

Ejemplos:

Expresión Resultado !7 0 13 > 9 && 9 > 4 1 && 1 1 3 != 4 || 7 < 15 1 Aquí sólo fue necesario evaluar 3 != 4 ya que al dar

como resultado verdadera, toda la expresión es verdadera.

Operadores de asignación Los operadores de asignación permiten reemplazar el valor de una variable. Estos son: = += -= *= /= %= El operador de asignación = debe de tener como operando izquierdo una variable y como operando derecho una expresión: nomVar = expresión La operación de asignación reemplaza el valor que tiene la variable por el valor de la expresión. Además, nomVar = expresión constituye a su vez una expresión cuyo valor es expresión de tal forma que se permiten construcciones como: nomVar1 = nomVar2 = expresión En este caso, tanto nomVar1 como nomVar2 toman el valor de expresión. Si en una asignación el tipo del valor de expresión es diferente al tipo de nomVar, tienen lugar una conversión implícita. El valor de expresión se convierte al tipo de nomVar de acuerdo a las siguientes reglas:

Conversiones enteras

Cuando cualquier tipo entero se convierte a un tipo con signo, el valor no se cambia si puede ser representado en el nuevo tipo. En el otro caso el resultado no está definido.

Enteros y flotantes

Cuando un valor de tipo flotante se convierte a un tipo entero, la parte fraccionaria se descarta; si el valor resultante no puede ser representado en el tipo entero, el resultado no está definido. En particular la conversión de flotantes negativos a enteros sin signo no está definida.

Page 20: Capítulo 3 - Tipos de Datos y Expresiones en C.pdf

44 Tipos de Datos y Expresiones en C

ITSON Manuel Domitsu Kono

Conversiones flotantes

Cuando un valor flotante menos preciso se convierte a un flotante igual o más preciso, el valor no se modifica. Cuando un flotante más preciso se convierte a un flotante menos preciso, y el valor esta dentro del rango representable, entonces el valor se redondea a la menor precisión. Si el resultado esta fuera de rango el comportamiento no esta definido. Las expresiones como

i = i + 2

donde la variable de la izquierda se repite en la derecha, pueden escribirse en forma más compacta como:

i += 2 mediante el operador de asignación +=. La mayor parte de los operadores binarios poseen un correspondiente operador de asignación, cuya sintaxis es la siguiente:

nomVar operador= expresión que es equivalente a la expresión:

nomVar = nomVar operador expresión donde operador puede ser uno de los siguientes:

+ - * / % Ejemplo: Suponga que a, b, c, x, y, z, son variables de los siguientes tipos y valores asignados:

int a = 83, b = 305, c; float x = 4.32, y = 0.85, z, w;

Determine el valor y el tipo de las siguientes expresiones:

a) c = b / (b - a) b) b *= a - 39 c) c = z = 3 * sqrt(fabs(x + e)) d) a = 'a' - 'A'

a) c = b / (b - a)

c = 305 / (305 - 83) c = 305 / 222 c = 1 1 Entero

b) b *= a - 39

b *= 83 - 39

Page 21: Capítulo 3 - Tipos de Datos y Expresiones en C.pdf

Capítulo 3 Tipos de Datos y Expresiones en C 45

ITSON Manuel Domitsu Kono

b *= 44 13420 Entero. Este también es el valor en la variable b.

c) c = z = 3 * sqrt(fabs(y - x))

c = z = 3 * sqrt(fabs(0.85 - 4.32)) c = z = 3 * sqrt(fabs(-3.470000000000000000)) c = z = 3 * sqrt(3.470000000000000000) c = z = 3 * 1.862793601000000000 c = z = 5.588380803000000000 c = 5.5883808 5 Entero. La variable c tiene también el valor de 5 y la variable z el

valor de 5.5883808.

d) a = 'a' - 'A' a = 97 - 65 a = 32 32 Entero

Operadores de incremento y decremento Los operadores de incremento y decremento son operadores unarios que solo se aplican a variables enteras. El operador de incremento ++ es un operador que le suma 1 a su operando. El operador de decremento -- es un operador que le resta 1 a su operando. Estos tipos de operadores se pueden usar como prefijos (antes de su operando, como en ++n ó --n) o como sufijos (después de su operando, como en n++ ó n--). En ambos casos se produce el mismo efecto, incrementar o decrementar el operando en 1. Sólo que, si el operador se usa como prefijo, el operando es incrementado o decrementado antes de ser usado y si el operador se usa como sufijo, el operando es incrementado o decrementado después de ser usado. Por ejemplo considera las siguientes asignaciones: n = 5; n = 5; x = n++; y = ++n; en ambos casos el valor final de n es 6. El valor asignado a x es 5 y el valor asignado a y es 6.

Operador condicional El operador condicional, ?: es un operador ternario y su sintaxis es la siguiente:

exp1 ? exp2 : exp3 exp1 debe ser una expresión entera, esto es, que se pueda evaluar a falso (0) o verdadero (!= 0). exp2 y exp3 pueden ser de cualquier tipo. El valor de exp1 ? exp2 : exp3 se determina de la siguiente manera: Primero se evalúa exp1, si es verdadera exp1 ? exp2 : exp3 toma el valor de exp2. Si es falsa exp1 ? exp2 : exp3 toma el valor de exp3

Page 22: Capítulo 3 - Tipos de Datos y Expresiones en C.pdf

46 Tipos de Datos y Expresiones en C

ITSON Manuel Domitsu Kono

Por ejemplo:

y = x > 7? 0: 10; Aquí, y tomará el valor de 0 para x > 7 y de 10 para x ≤ 7.

Operador coma El operador coma (,) se utiliza esencialmente para ejecutar una secuencia de operaciones. La sintaxis de este operador es la siguiente:

exp1, exp2[, exp3] ... Las expresiones exp1, exp2, etc. son evaluadas de izquierda a derecha. La expresión completa exp1, exp2[, exp3] ... toma el valor de la última expresión. Por ejemplo,

y = (x = 5, x + 8) Aquí primero se le asigna 5 a la variable x, luego y toma el valor de 13.

Problemas

1. Para cada una de las siguientes funciones, investiga lo siguiente: ¿Qué hace la función?, ¿qué valor regresa, qué tipo y en qué rangos?, ¿que parámetros recibe, de que tipo y en qué rangos?. Incluye comentarios sobre qué pasa si el valor del valor regresado o el de los parámetros se salen de rango.

a) abs() b) ceil() c) floor() d) fmod() e) labs() f) log10() g) random() h) tolower()

2. Escríbase una expresión en C para cada una de las siguientes expresiones

matemáticas:

a) 3 +

zy

y + x

b) )y + x( 222

c) 2a

4ac - b - b - 2

Page 23: Capítulo 3 - Tipos de Datos y Expresiones en C.pdf

Capítulo 3 Tipos de Datos y Expresiones en C 47

ITSON Manuel Domitsu Kono

d) xyz - y + 2xz -y + x

2

3. Escríbase una expresión matemática equivalente a cada una de las siguientes

expresiones de C

a) a*b*c/d/e b) x + y/z*(a + b) c) a - b*c/d + e*f d) k*q1*q2/r/r

4. Calcular el valor de cada expresión si es una expresión válida. Indicar si el valor es

real o entero. Si la expresión no es válida indicar porqué.

a) 10/3 + 5*2 b) 10++ + 5 % 2 c) 12.5 + (2.5/(6.2/3.1)) d) -4 * (-5 + 6) e) sqrt(4 * 2 + 2) f) '7' + 12

5. Suponga que a, b, c, d, e, y, son variables de los siguientes tipos y valores

asignados:

int a = 583, b = 35, c; float x = 4.3, y = 0.8, z = -2.2, w; char l = 'Y';

Determine el valor y el tipo de las siguientes expresiones:

a) c = (a / b)/(a % b) b) a *= a / (a - b) c) w = 3 * sqrt(fabs(x + y)) d) c = (x < y < b) || (l != 'Y') e) l -= ('@' - '+')

6. Explique que ocurre en las siguientes expresiones:

a) (x < y) ? (x < z ? x : z) : (y < z ? y : z) b) x % 2 ? x++ : x-- c) z = (y = 20, y = y-5, y % 3? 6: 5)