0% encontró este documento útil (0 votos)
34 vistas21 páginas

Expresiones y Operadores en C

1. Las expresiones son elementos o conjuntos de elementos que son evaluados numéricamente. Incluyen operadores, operandos, constantes, variables y funciones. 2. Las operaciones aritméticas incluyen suma, resta, multiplicación, división y módulo. Existen asignaciones combinadas y operadores de incremento/decremento. 3. Cuando los tipos de datos son diferentes, la operación se realiza con el tipo más fuerte, pero la asignación usa el tipo del operando izquierdo. El operador de "cast" puede forzar un tipo.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
34 vistas21 páginas

Expresiones y Operadores en C

1. Las expresiones son elementos o conjuntos de elementos que son evaluados numéricamente. Incluyen operadores, operandos, constantes, variables y funciones. 2. Las operaciones aritméticas incluyen suma, resta, multiplicación, división y módulo. Existen asignaciones combinadas y operadores de incremento/decremento. 3. Cuando los tipos de datos son diferentes, la operación se realiza con el tipo más fuerte, pero la asignación usa el tipo del operando izquierdo. El operador de "cast" puede forzar un tipo.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

Operaciones

1. Noción de expresión

En el código informático, a todo elemento o conjunto de elementos que son objeto de una evaluación numérica se le
llama expresión:

a + b, a / b, a = b, &b, !b son expresiones.

En estas expresiones +, /, =, & y ! son operadores y las variables a y b son los operandos.

Estas combinaciones de variables con operadores se llaman expresiones más que operaciones, ya que no solo hay
operadores aritméticos. Además, un valor constante, una variable o una llamada a una función por sí solos también
se consideran expresiones. Son expresiones elementales. A las expresiones que usan operadores y varios
argumentos se les llama expresiones compuestas.

El valor numérico de una expresión, compuesta o elemental, es el resultado de la expresión en sí misma. Si se trata
de una operación aritmética o de una asignación, el valor numérico de la expresión es el resultado de esta
operación. Si se trata de una llamada a una función, es el valor de retorno de la función. La expresión vale este
valor, es este valor y, como tal, una expresión puede integrarse dentro de otra más grande, en una asignación o
como un operando. Por ejemplo, el programa:

#include <stdio.h>
#include <stdlib.h>

int main()
{
int a, b=20;
printf("%d--",a=10); // asignación
printf("%d--",a=a*b); // multiplicación
printf("%d\n",a%b); // módulo (resto de la división)
return 0;
}

Imprime:

10--200--0

2. Operaciones aritméticas

a. Operadores +, ­, *, /, %

Los operadores aritméticos son los siguientes:

+ más :
el resultado de la expresión a+b es la suma

- menos :
el resultado de la expresión a-b es la resta

© Éditions ENI – Todos los derechos reservados – Copia personal de RONALD PECHO QUINTANA - 1-
* multiplicar :
el resultado de la expresión a*b es la multiplicación

/ dividir :
el resultado de la expresión a/b es la división

% módulo :
el resultado de la expresión a%b es el resto de la división de a entre b

¿Qué resultado devuelve el programa siguiente?

#include <stdio.h>
#include <stdlib.h>

int main()
{
int a=10,b=20,c=0; // 1
c=a+b; // 2
a=b/c; // 3
b=a*c; // 4
printf("a=%d, b=%d, c=%d\n",a,b,c); // 5
printf("res=%d\n",c%4); // 6
printf("c=%d\n",c); // 7
return 0;
}

línea 1: a vale 10, b vale 20, c vale 0

línea 2: a vale 10, b vale 20, c vale 30

línea 3: a vale 0, b vale 20, c vale 30

línea 4: a vale 0, b vale 0, c vale 30

línea 5: visualización: a=0, b=0, c=30

línea 6: visualización: res=2

línea 7: visualización: c=30

¡Atención! En la línea 6 el resultado de la operación se muestra, pero no hay asignación que modifique el valor de c
y c conserva su valor, que es el que se muestra en la línea 7.

b. Asignaciones combinadas

Los operadores siguientes permiten asociar una operación con una asignación; la operación se realiza antes que
la asignación:

a += b es una contracción de a = a+b


a -= b es una contracción de a = a-b
a *= b es una contracción de a = a*b

- 2- © Éditions ENI – Todos los derechos reservados – Copia personal de RONALD PECHO QUINTANA
a /= b es una contracción de a = a/b
a %= b es una contracción de a = a%b

¿Qué imprime el programa siguiente?

#include <stdio.h>
#include <stdlib.h>

int main()
{
int a=7,b=232,c=4; // 1

c+=a; // 2
b-=c; // 3
a%=10; // 4
printf("a=%d, b=%d, c=%d\n",a,b,c); // 5
c+=(b-a); // 6
printf("c=%d\n",c); // 7
}

línea 1: a vale 7, b vale 232, c vale 4

línea 2: c vale 11

línea 3: b vale 221

línea 4: a vale 7

línea 5: visualización: a=7 b=221 c=11

línea 6: c vale 225

línea 7: visualización: c=225

c. Pre y posincrementos o decrementos

También hay que dominar los operadores ++ y ­­. Se utilizan muy a menudo. Se usan a la izquierda o a la derecha
de su operando.

Sea, por ejemplo, un entero i:

i++ y ++i son equivalentes a i = i+1, también


i-- y --i son equivalentes a i = i-1

¡Pero atención! Ambos operadores se comportan distinto si se colocan delante de la variable o se colocan detrás.
La diferencia es visible cuando i++ o ++i se utiliza en expresiones, como por ejemplo en la llamada de una función
o en una operación:

printf("%d %d",++i, i++);

Si el operador ++ se coloca delante del operando: ++i, entonces, en una expresión, el valor de i es el valor de i+1,
es decir, i se incrementa en 1 antes de usarse en la expresión.

© Éditions ENI – Todos los derechos reservados – Copia personal de RONALD PECHO QUINTANA - 3-
En cambio, si ++ se coloca detrás del operando: i++, entonces, en una expresión, el valor de i sigue siendo i y se
incrementa en 1 después de que la expresión haya sido evaluada.

Por ejemplo, ¿qué muestra la siguiente serie de comandos?

int i=0;
printf("%d",i++); // el resultado da 0
printf("%d",i); // pero i se incrementa después de usarse
// y vale 1 después
printf("%d",++i); // i se incrementa antes de su uso,
// el resultado da 2

El principio es el mismo con el operador ­­. Si se coloca antes de la variable, se realizará la resta de 1 antes de que
se use la variable en la expresión. Si se coloca después de la variable, la variable se usará sin modificarse en la
expresión y después se decrementará en 1.

d. Operaciones entre tipo distintos, operador de «cast»

¿Qué sucede si se realizan operaciones con variables de tipos distintos? Por ejemplo:

#include <stdio.h>
#include <stdlib.h>

int main()
{
int entero = 10;
float flotante = 34.9;
int eRes;
float fRes;
eRes=entero+flotante;
fRes=entero+flotante;
printf("eRes: %d, fRes: %f\n", eRes, fRes); // 1

eRes=entero / (entero+5);
fRes=entero / (entero+5);
printf("eRes: %d, fRes: %f\n", eRes, fRes); // 2

eRes=flotante / entero;
fRes=flotante / entero;
printf("eRes: %d, fRes: %f\n", eRes, fRes); // 3
return 0;
}

A continuación, la regla que debe saber:

La operación aritmética se realiza con el tipo del operando más fuerte. La asignación se realiza con el tipo del
miembro de la izquierda, el de la variable que recibe el valor.

1) La primera impresión muestra eRes: 44, fRes: 44.900000.

- 4- © Éditions ENI – Todos los derechos reservados – Copia personal de RONALD PECHO QUINTANA
La operación se hace en float, el tipo más fuerte. Con la asignación, el resultado se transforma a tipo int para eRes
y sigue siendo un float con fRes.

2) La segunda impresión muestra eRes: 0, fRes: 0.000000.

La operación se realiza con el tipo int, el más fuerte. Por lo tanto, no hay cifras decimales y el resultado es 0 en
ambos casos.

3) La tercera impresión muestra eRes: 3, fRes: 3.490000.

La operación se realiza en float, el resultado se convierte a int en el primer caso y sigue siendo un float en el
segundo.

Operador de cast

A veces es necesario forzar una operación para que trabaje con un tipo en particular. Para ello, existe un operador
que permite convertir el tipo de una expresión a otro tipo. Es el operador llamado «cast». Por ejemplo, en el
caso //2, mostrado a continuación:

fRes = entero / (entero+5);

si se necesita el resultado en float de una operación hay que forzar esta operación a que se realice en float. Para
ello basta con especificar entre paréntesis el tipo deseado a la izquierda de alguna de las dos variables:

fRes = (float)entero / (entero+5);


o
fRes = entero / (float)(entero+5);

Atención: no es el resultado lo que se convierte, sino una de las variables para que la operación se realice en un
tipo más fuerte. Pero también funciona a la inversa, si se desea, por ejemplo, forzar una operación realizada en
float para que se haga en tipo int:

fRes= (int)flotante / entero;

e. Prioridades entre operadores

La máquina siempre ejecuta las instrucciones una tras otra y nunca ejecuta dos operaciones a la vez. Para poder
realizar una operación compuesta de varios cálculos, hay un orden de prioridad entre operadores. Por ejemplo, el
operador * es prioritario en relación con el operador +, y una expresión como:

a + b * c

se interpreta como:

a + (b * c)

A continuación se muestra una tabla de prioridades para los operadores que hemos estudiado hasta ahora (la
tabla completa que incluye todos los operadores de C está en el anexo y haremos referencia a ella en los capítulos
siguientes). Cada fila corresponde a un nivel. Tenemos cuatro niveles y están clasificados en orden decreciente de
prioridad, de la prioridad más alta a la más baja.

© Éditions ENI – Todos los derechos reservados – Copia personal de RONALD PECHO QUINTANA - 5-
Operadores Función del operador Asociatividad

++ pre y posincremento derecha


­­ pre y posdecremento
+ ­ signo más o signo menos
(tipo) cast
sizeof tamaño

* / % multiplicación, división, módulo izquierda

+ ­ suma y resta izquierda

= asignación y derecha
+= ­ = *= /= %= asignación combinada

, evaluación secuencial (coma) izquierda

Pero ¿qué sucede si los operadores tienen la misma prioridad? Hay una regla de asociatividad que determina el
orden de evaluación de la expresión y de sus subexpresiones si las hay. Por ejemplo, * y / son asociativos a la
izquierda, es decir, que el cálculo se descompone empezando por la izquierda:

a * b / c

se interpreta como

(a * b) / c

No es obligatorio basarse exclusivamente en las prioridades predefinidas con los operadores. También se puede
forzar una prioridad añadiendo paréntesis; por ejemplo:

(a + b) * c

a + b será lo que se calculará primero y, a continuación, la multiplicación por c.

En caso de duda, siempre es bueno clarificar la expresión con los paréntesis apropiados.

¿Qué imprime el programa siguiente?

#include <stdio.h>
#include <stdlib.h>

int main()
{
int x,y,z;

x= -3+4*5-6;
printf("%d\n",x);

x= 3+4%5-6;
printf("%d\n",x);

x=-3*4%-6/5;
printf("%d\n",x);

x= (7+6)%5/2;

- 6- © Éditions ENI – Todos los derechos reservados – Copia personal de RONALD PECHO QUINTANA
printf("%d\n",x);

x=2;
x*=3+2;
printf("%d\n",x);

x*=y=z=4;
printf("%d\n",x);
}

Muestra:

11
1
0
1
10
40

Para averiguarlo, lo más sencillo es añadir los paréntesis correspondientes a las prioridades e ir descomponiendo
progresivamente la expresión en el orden ejecutado por la máquina.

Descomposición del primer ejemplo:

x = -3+4*5-6
x = (-3)+4*5-6 - como signo
x = (-3)+(4*5)-6 * multiplicar
x = ((-3)+(4*5))-6 + suma debido a la asociatividad izquierda
x = (((-3)+(4*5))-6) - menos antes de la asignación
(x = (((-3)+(4*5))-6)) = asignación

lo que resulta en:


(x= ((-3+20)-6))
(x= (17-6))
(x= 11)
11

Descomposición del segundo ejemplo:

x = 3+4%5-6
x = 3+(4%5)-6
x = (3+(4%5))-6
x = ((3+(4%5))-6)
(x = ((3+(4%5))-6))

Descomposición del tercer ejemplo:

x = -3*4%-6/5
x = (-3)*4%(-6)/5
x = ((-3)*4)%(-6)/5
x = (((-3)*4)%(-6))/5
x = ((((-3)*4)%(-6))/5)

© Éditions ENI – Todos los derechos reservados – Copia personal de RONALD PECHO QUINTANA - 7-
(x = ((((-3)*4)%(-6))/5))

Descomposición del cuarto ejemplo:

x = (7+6)%5/2 // el cálculo entre paréntesis se realiza primero


x = ((7+6)%5)/2
x = (((7+6)%5)/2)
(x = (((7+6)%5)/2))

Descomposición del quinto ejemplo:

x vale 2
x *= 3+2
x *= (3+2)
(x *= (3+2))

Descomposición del sexto ejemplo:

x vale 10
x *= y = z = 4
x *= y = (z = 4) asociatividad a partir de la derecha
x *= (y = (z = 4))
(x *= (y = (z = 4)))

3. Puesta en práctica: operaciones aritméticas, cast

Ejercicio 1

Sean las declaraciones:

char c =’\x01’ ; /* ’\xhh’ para un número hexadecimal


(0...9, a...f o A...F) en un byte máx*/
short p=10;

¿Cuáles son los tipos y los valores de cada una de las expresiones siguientes?

p + 3
c + 1
p + c
3 * p + 5 * c
6.8 /7 + ’a’ * 560

Ejercicio 2

Sean las declaraciones:

char c=’\x05’;
int n=5;
long p=1000;
float x=1.25;
double z=5.5;

- 8- © Éditions ENI – Todos los derechos reservados – Copia personal de RONALD PECHO QUINTANA
¿Cuáles son los tipos y los valores de cada una de las expresiones siguientes?

n + c + p
2 * x + c
(char) n + c
(float) z + n / 2

Ejercicio 3

Escribir un programa que, tras introducir un número entero, muestre su opuesto y su mitad exacta.

Ejercicio 4

Crear un conversor pesetas/euro... (un euro = 166,386 pesetas)

l ¿cuáles son las fases del programa?

l programar

Ejercicio 5

Para convertir los grados Fahrenheit en grados Celsius, se usa la siguiente fórmula:

C= 5/9 * (F-32)

Para convertir los grados Celsius en grados Fahrenheit, se usa esta otra:

F= ( (9*C ) / 5)+32

donde F es una temperatura en grados Fahrenheit y C es la temperatura correspondiente en grados Celsius.

l Escribir un programa que convierta en grados Celsius una temperatura entrada por el teclado en grados Fahrenheit.

l Hacer lo mismo con una temperatura expresada en grados Celsius para convertirla a grados Fahrenheit.

Ejercicio 6

Escribir un programa para comprobar todos los casos de la división en C con el objetivo de ilustrar el problema de
los cast:

l División de un int entre un int, guardada en un int mostrado con %d

l División de un int entre un int, guardada en un float mostrado con %f

l División de un int entre un float, guardada en un float y mostrado con %d y %f

¿En qué casos es necesario? Comprobar con cast.

Atención, es importante distinguir por un lado la división y su resultado, y por otro la visualización del resultado
según un formato u otro. Son dos problemas distintos.

Ejercicio 7

© Éditions ENI – Todos los derechos reservados – Copia personal de RONALD PECHO QUINTANA - 9-
Una tienda de informática anuncia unas rebajas del 10% en ordenadores portátiles. Escribir un programa que lea el
precio de un ordenador entrado por el teclado y muestre el nuevo precio con la rebaja.

Ejercicio 8

Sea una función matemática f cuya definición es f(x) = (2x+3)(3x2 +2).

Escribir el programa que calcule la imagen de f de un número introducido por el teclado.

Ejercicio 9

Escribir un programa que lea un número del teclado y muestre 1 si es par y 0 si es impar.

Ejercicio 10

Escribir un programa que muestre el número de las decenas, el de las centenas y el de los millares de un número
introducido por el teclado. Por ejemplo, para 31345, el número de las decenas es el 4, el de las centenas es el 3 y el
de los millares es el 1.

Ejercicio 11

Escribir un programa que redondee un número real entrado por el teclado a dos cifras decimales.

Ejercicio 12

Escribir un programa que lea un valor introducido por el usuario en una variable y que muestre i, i++ e ++i. ¿Qué es
lo que muestra? ¿Por qué?

Ejercicio 13

¿Qué resultados da el programa siguiente?

#include <stdio.h>

int main()
{
int i, j, n;
i=0;
n=i++;
printf("A : i = %d, n = %d \n", i, n);

i=10;
n=++i;
printf("B : i = %d, n = %d \n", i, n);

i=20;
j=5;
n=i++ * ++j;
printf("C : i = %d, j = %d, n = %d \n", i, j, n);

i=15;
n= i += 3;
printf("D : i = %d, n = %d \n", i, n);

- 10 - © Éditions ENI – Todos los derechos reservados – Copia personal de RONALD PECHO QUINTANA
i = 3;
j = 5;
n = i *= --j;
printf("E : i = %d, j = %d, n = %d \n", i, j, n);
return 0;
}

4. Obtener valores aleatorios

a. Principio de pseudoaleatoriedad

El concepto de azar es un problema en matemáticas; la aleatoriedad no existe en un ordenador. Sin embargo,


siempre es posible simular la aleatoriedad con un ordenador produciendo valores imprevisibles.

El principio es el de construir una serie de números. Se toma un número como punto de partida, al que se le aplica
un extraño cálculo que produce un valor imposible de predecir y aplicando cada vez el mismo cálculo al resultado
obtenido. En función del punto de partida y del cálculo, se obtiene una serie impredecible de números como si se
produjeran por azar. Por ejemplo, una serie poco previsible puede obtenerse con el cálculo siguiente: (x+3,14159)
8

En cada paso, hay un número intuitivamente improbable. Pero la serie será siempre la misma con un número de
partida y un cálculo idéntico. Para tener series distintas, el problema es poder obtener un punto de partida que
vaya cambiando.

Para obtener una serie de números (pseudo)aleatorios e inicializar el valor de partida, la librería estándar stdlib.h
proporciona dos funciones:

l La función rand() se dedica a realizar el cálculo y devuelve un número impredecible.

l La función srand() inicializa el valor de partida.

b. La función rand()

El cálculo operado por la función rand() es el siguiente, a partir de la variable de paso de tipo unsigned long (o int
en 32 bits en 4 bytes) y por defecto inicializada a 1 de partida:

paso = paso * 1103515245 + 12345


paso = (paso / 65536) % 32768

Cada nueva llamada a la función realiza un paso de más en la serie a partir del valor albergado en la variable
paso. El valor de la variable paso se devuelve al contexto de la llamada de la función, es decir, que hay que
recuperar este valor en una variable de la forma siguiente:

int prueba;

(...)

prueba=rand(); // en cualquier parte del programa

En el cálculo, el módulo 32768 hace que el valor máximo posible sea 32767. Este valor también se ha definido en
la librería por la macro constante RAND_MAX (una macro constante es un valor fijo que se reemplaza por un texto;

© Éditions ENI – Todos los derechos reservados – Copia personal de RONALD PECHO QUINTANA - 11 -
este tema se explica en el capítulo de Variables conjunto [estructuras y tablas]).

El programa siguiente prueba los cinco primeros valores devueltos por la función rand():

#include <stdio.h>
#include <stdlib.h>

int main()
{
int prueba;

prueba=rand();
printf("paso 1: %d\n",prueba);
prueba=rand();
printf("paso 2: %d\n",prueba);
prueba=rand();
printf("paso 3: %d\n",prueba);
prueba=rand();
printf("paso 4: %d\n",prueba);
prueba=rand();
printf("paso 5: %d\n",prueba);
return 0;
}

En cada nueva ejecución del programa, siempre salen los mismos números:

41
18467
6334
26500
19169

c. La función srand()

Para evitar tener siempre la misma serie, hay que comenzar la serie con números distintos. Este es el papel de la
función srand(), inicializar el primer valor de la serie. Para ello, hay que pasar a srand() el valor deseado para
iniciar la serie. Por ejemplo, para generar la serie a partir del número 2, la función se debe llamar de la siguiente
forma:

srand(2);

En un programa, con un número cualquiera sería:

#include <stdio.h>
#include <stdlib.h>

int main()
{
int val;

srand(689); // inicialización de partida

- 12 - © Éditions ENI – Todos los derechos reservados – Copia personal de RONALD PECHO QUINTANA
val = rand();
printf("val=%d\n",val); // cálculo del primer número
return 0;
}

Pero en cada ejecución el punto de partida será siempre el mismo: 689, en este ejemplo... ¿Cómo se puede
inicializar la serie con un valor distinto en cada ejecución?

La idea es capturar la hora con la función de la librería time.h, la función time(). Esta función devuelve el valor de
tiempo según una codificación que varía de un sistema a otro, o el valor ­1 si esta funcionalidad no está disponible.
En Windows la hora se devuelve en milisegundos. La llamada a la función se realiza de la siguiente forma en el
programa:

int partida;
partida=time(NULL);

Es necesario indicar el valor NULL entre los paréntesis, como parámetro de la función. A continuación solo falta
pasar esta variable a la función srand().

srand(partida);

En un programa se utilizaría del siguiente modo:

#include <stdio.h> // para utilizar la función printf()


#include <stdlib.h> // para utilizar las funciones rand() y srand()
#include <time.h> // para utilizar la función time()

int main()
{
int partida=time(NULL); // inicialización en la declaración de la variable
srand(partida);

(...)

printf("primer valor: %d\n",rand());


printf("segundo valor: %d\n",rand());
printf("tercer valor: %d\n",rand());
return 0;
}

Con este programa, la serie será diferente en cada nueva ejecución del programa.

La variable «partida» no es necesaria; puede colocar directamente la llamada a la función time() como parámetro
de la función srand(), quedando de este modo: srand(time(NULL));

d. Valores aleatorios en rangos definidos

Obtener valores enteros en un rango

© Éditions ENI – Todos los derechos reservados – Copia personal de RONALD PECHO QUINTANA - 13 -
El operador módulo devuelve el resto de una división entera, a%b vale el resto de la división de a entre b, siendo
un valor entero que va de 0 a b­1. Por ejemplo, el programa siguiente permite visualizar dos valores aleatorios
entre 0 y 9:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()

{
int prueba;
srand(time(NULL));

prueba=rand();
prueba%=10; // equivalente a prueba = prueba%10;
printf("prueba=%d\n",prueba);

// se puede escribir directamente


prueba=rand()%10;
printf("prueba=%d\n",prueba);
return 0;
}

Para obtener un valor en un rango con máximo «max» y con un valor mínimo «min» distinto de 0, basta con
extraer un valor aleatorio dentro del intervalo max­min y sumar min. Por ejemplo, para un valor entre 20 y 49,
deberíamos escribir:

int prueba;

prueba= (rand()%(50-20))+20;
// es decir:
prueba = 20 + rand()%30;

Si rand() %30 da 0, entonces 20 es el valor más pequeño y si rand() devuelve 29, 49 es exactamente el valor más
grande.

Obtener valores en coma flotante en un rango

La función rand() devuelve un valor entero de tipo int y el valor más grande de los posibles es el valor RAND_MAX
de tipo int, definido como macro constante en la librería stdlib.h. Para obtener un valor en coma flotante entre 0 y
1, basta con dividir el valor devuelto por rand() por el valor máximo posible RAND_MAX, sin olvidar de realizar un
casting a float, ya que, si no se se lleva a cabo, se calculará en el tipo int (int dividido entre int). Obtendremos el
código siguiente:

float prueba; // ¡atención, usar un float!


prueba= (float) rand() / RAND_MAX;

Para tener un número entre 0 y 50, basta con multiplicar el número obtenido entre 0 y 1 por 50. El extremo inferior
es 0, con 0*50, y el extremo superior es 50, con 1*50. Cualquier otro valor estará comprendido entre ambos
extremos.

- 14 - © Éditions ENI – Todos los derechos reservados – Copia personal de RONALD PECHO QUINTANA
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
float prueba;
srand(time(NULL));

prueba=(float) rand() / RAND_MAX; // entre 0 y 1


printf("prueba1=%f\n",prueba);

prueba=((float) rand() / RAND_MAX)*50; // entre 0 y 50


printf("prueba2=%f\n",prueba);

prueba=20+ ((float) rand() / RAND_MAX)*30; // entre 20 y 50


printf("prueba3=%f\n",prueba);

return 0;
}

5. Puesta en práctica: operaciones y números aleatorios

Ejercicio 1

Elegir cara o cruz mentalmente, y ejecutar un programa que escriba al azar 0 para cara y 1 para cruz... ¿ganó?

Ejercicio 2

Elegir mentalmente un número entre 2 y 12 y ejecutar un programa que simule una tirada con dos dados de seis
caras... ¿ganó?

Ejercicio 3

Escribir un programa que genere y muestre 7 números aleatorios según las restricciones siguientes:

l Mostrar un número aleatorio según el rango máximo del generador aleatorio.

l Mostrar un número aleatorio comprendido entre 0 y 367.

l Mostrar un número aleatorio comprendido entre 0 y un valor «umbral alto» entrado por el usuario.

l Mostrar un número aleatorio comprendido entre 678 y 7354.

l Mostrar un número aleatorio comprendido entre un valor umbral bajo y un valor umbral alto entrados por el usuario.

l Mostrar un número aleatorio comprendido entre 0 y 1.

l Mostrar un número aleatorio con decimales comprendido entre 0 y 50.

6. Operaciones bit a bit

En C tenemos seis operadores que permiten realizar operaciones a nivel de bit. Se usan únicamente con los tipos
enteros con signo y con char, short, int y long sin signo.

© Éditions ENI – Todos los derechos reservados – Copia personal de RONALD PECHO QUINTANA - 15 -
a. Y ­ operador &

El operador Y funciona bit a bit de la siguiente forma:

i & 0 siempre devuelve 0


i & 1 devuelve i, es decir, o 0 o 1

Por ejemplo, el resultado de 12 & 10 devuelve 8:

1 1 0 0 (12 en binario)
& 1 0 1 0 (10 en binario)
devuelve 1 0 0 0 (8 en binario)

Sirve para acceder a uno o a varios bits concretos de un entero. Para ello, consideremos un valor de máscara en la
que solo los bits a 1 son visibles. Por ejemplo:

Para saber el valor del primer bit de un entero, máscara 1:

10111001
& 00000001
devuelve 00000001

Para conocer el valor del segundo bit, máscara 2:

10111001
& 00000010
devuelve 00000000

Para conocer el valor del tercer bit, máscara 4:

10111001
& 00000100
devuelve 00000000

Para conocer el valor del cuarto bit, máscara 8:

10111001
& 00001000
devuelve 00001000

Para conocer el valor resultante de los cuatro primeros bits del byte:

10111001
& 00001111
devuelve 00001001

Para conocer el valor resultante de los cuatro últimos bits del byte:

10111001
& 11110000

- 16 - © Éditions ENI – Todos los derechos reservados – Copia personal de RONALD PECHO QUINTANA
devuelve 10110000

Lo interesante es poder tener en un solo entero varios interruptores booleanos distintos o poderlo descomponer
en varios rangos de bits.

b. O exclusivo ­ operador ˆ

Este operador devuelve 1 si sus operandos son distintos y 0 si son iguales:

0ˆ0 devuelve 0
1ˆ0 devuelve 1
0ˆ1 devuelve 1
1ˆ1 devuelve 0

Se utiliza en diferentes casos; por ejemplo, en el programa siguiente, los valores de ambas variables se
intercambian:

#include <stdio.h>
#include <stdlib.h>

int main()
{
int a=345, b=678;

printf("a: %d, b: %d\n,a,b);


aˆ=b;
bˆ=a;
aˆ=b;
printf("a: %d, b: %d\n,a,b);
return 0;
}

c. O inclusivo ­ operador |

Devuelve 1 si algún operando vale 1:

0 | 0 devuelve 0
1 | 0 devuelve 1
0 | 1 devuelve 1
1 | 1 devuelve 1

Permite acumular bits a 1 en una variable. Se utiliza especialmente en algunas funciones para especificar con una
sola variable qué tratamientos se deben aplicar (bits a 1) y cuáles ignorar (bits a 0). En tal implementación, cada
bit tiene asociado simbólicamente un tratamiento; si está a 1, el tratamiento deberá realizarse, y si está a 0, el
tratamiento correspondiente no debe realizarse.

d. COMPLEMENTO ­ operador ~

El complemento es un operador unario (con un solo operando a la derecha) que invierte el valor de los bits de una
variable:

© Éditions ENI – Todos los derechos reservados – Copia personal de RONALD PECHO QUINTANA - 17 -
~1100 devuelve 0011

Pone a 1 los bits que valen 0 y a 0 los que valen 1.

e. Operadores de desplazamiento a izquierda y derecha ­ operadores >> y <<

Los desplazamientos permiten mover los bits de una variable hacia la izquierda o hacia la derecha. Por ejemplo, un
desplazamiento a la derecha de 2 bits:

10110011 >> 2 devuelve 00101100

Los dos bits a 1 de la derecha han salido y han sido reemplazados por 0, que han entrado por la izquierda. Esta
operación es equivalente a una división entre 2 2 . n bits desplazamientos a la derecha es una división entre 2 n .

En el otro sentido, un desplazamiento de 4 bits:

11110011 << 4 devuelve 00110000

Los cuatro bits a 1 de la izquierda han salido y han sido reemplazados por 0, que han entrado por la derecha. Esta
operación equivale a una multiplicación por 24 . n bits desplazamientos a la izquierda es una multiplicación por 2n .

f. Prioridades de los operadores bit a bit

Su nivel de prioridad se sitúa entre el de la asignación y el de la suma y la resta. No tienen todos la misma
prioridad (ver Anexo 1 Prioridad y asociatividad de los operadores).

7. Puesta en práctica: operaciones bit a bit

Ejercicio 1

¿Que imprime por pantalla el programa siguiente?

#include <stdio.h>

int main()
{
int x,y,y;

x = 3;
y = 2;
z = 1
printf("%d\n", x | y & z);
printf("%d\n", x | y & ~z);
printf("%d\n", x ˆ y & ~z);
printf("%d\n", x & y & z);

x = 1;
y = -1;
printf("%d\n", ~x | x);
printf("%d\n", x & ~x);
printf("%d\n", x ˆ x);

- 18 - © Éditions ENI – Todos los derechos reservados – Copia personal de RONALD PECHO QUINTANA
x <<= 3;
y <<= 3;
y >>= 3;
}

8. Experimento: operaciones aritméticas, valores aleatorios

/*
2. OPERACIONES ARITMÉTICAS
*/
// librerías de funciones
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
int a=90, b=10;

// los operadores aritméticos son +, -, *, /, %

//--------------------------------------------------------
// a+b es una expresión
// el valor numérico de una expresión es el resultado
// de la operación (aritmética o no)
printf("%d\n",a+b);

//--------------------------------------------------------
// prioridad de los operadores aritméticos:
printf("%d\n",a/2+b*8%3); // (a/2)+((b*8)%3)

//--------------------------------------------------------
// tipo de una expresión aritmética:
// si los operandos son de tipos distintos, la expresión
// es del tipo del operando más fuerte
char c=12, res2;
float f=4.5, res1;
printf("%f\n",c+f);

//--------------------------------------------------------
// obtener un resultado: la asignación se realiza con el tipo
// de la variable que recibe el valor, posible truncamiento
res1=c+f;
printf("%f\n",res1);

res2=c+f;
printf("%d\n",res2);

//--------------------------------------------------------
// La operación se realiza con el tipo más fuerte:
int i1=10, i2=5;

© Éditions ENI – Todos los derechos reservados – Copia personal de RONALD PECHO QUINTANA - 19 -
i1=i2/i1;
printf("res i1 : %d\n",i1);

float res;
i1=10; // (atención div entre 0)
res=i2/i1;
printf("res float : %f\n",res);

//--------------------------------------------------------
// forzar una operación para que se realice en otro tipo que
// el de los operandos: operador de cast
res= (float)i2/i1;
printf("res float : %f\n",res);

//--------------------------------------------------------
//posibilidad de combinar la asignación y una operación aritmética
// +=, -=, *=, /=, %=

res+=10; // equivalente a res= res+10


printf("res float : %f\n",res);

//--------------------------------------------------------
// operadores de incremento/decremento
int i=0;
printf("%d\n",i++); // posincremento
printf("%d\n",++i); // preincremento

//--------------------------------------------------------
// obtener un valor aleatorio entero: función rand()
i=rand();
printf("%d\n",i);

// albergado en un rango
i=rand()%10; // comprendido entre 0 y 9
printf("%d\n",i);

i=5+rand()%10;// entre 5 y 14

//--------------------------------------------------------
// inicializar la serie de números aleatorios:
srand(time(NULL));

//--------------------------------------------------------
// obtener un valor aleatorio entre 0 y 1
res= (float)rand()/RAND_MAX;
printf("%f\n",res);

// obtener un valor aleatorio en coma flotante en un rango


res= ((float)rand()/RAND_MAX)*10; // comprendido entre 0 y 10
printf("%f\n",res);

// fin prog
return 0;

- 20 - © Éditions ENI – Todos los derechos reservados – Copia personal de RONALD PECHO QUINTANA
© Éditions ENI – Todos los derechos reservados – Copia personal de RONALD PECHO QUINTANA - 21 -

También podría gustarte