TEMA 7 ELEMENTOS DEL LENGUAJE C INTRODUCCIÓN Básicamente, C está compuesto por los siguientes elementos: • Constantes • Identificadores • Palabras reservadas • Comentarios • Operadores Una característica importante del lenguaje C es que todos los elementos anteriormente enumerados distinguen entre mayúsculas y minúsculas. • Constantes: Las constantes que se pueden usar en C se clasifican en: • enteras • reales • de carácter • Enteras: Son números sin parte fraccionaria. Pueden expresarse en: • decimal • octal • hexadecimal Una constante octal debe comenzar con un 0. 016 ! 16 octal !14 decimal Una constante hexadecimal debe comenzar por un 0 seguida de una x o una X. 0xA3 ! A3 hexadecimal ! 163 decimal 0XA3 0xa3 Las constantes enteras se pueden considerar positivas a menos que vayan seguidas de un menos (−) −153 decimal −063 octal 1
−0xA hexadecimal • Reales: También se denominan de coma flotante. Éste sería el formato general de una constante real: [parte entera][.parte fraccionaria][exponente de 10] Cualquiera de las tres partes es opcional. El exponente de 10 tiene el siguiente formato: {E|e} exponente Ej: 13.21 −81e8 21.37E1 −.39E7 0.320001 −3.9 32e2 • de carácter: Pueden ser de dos tipos: • simples: formada por un solo carácter. Se encierran entre comillas simples Ej: `a' `A' Los caracteres ASCII no imprimibles se definen mediante la barra invertida (\) CÓDIGO ASCII 7 8 9 10 11 12 13 34 39 92
CARÁCTER BARRA \a \b \t \n \v \f \r \ \' \\
SIGNIFICADO Alarma (Beep) Retroceso (BS) Tabulador Horizontal (HT) Nueva Línea (LF) Tabulador Vertical (VT) Nueva Página (FF) Retorno Comillas Dobles Comillas Simples Barra Invertida
Se pueden representar caracteres ASCII mediante su código octal o hexadecimal usando el siguiente formato: `\numoctal' !'\x4', `A', `\101' `\xnumhexadecimal\'
2
• cadena de caracteres: Son secuencias de caracteres simples encerradas entre . A las cadenas de caracteres el compilador les añade un carácter nulo, aparece después de las cadenas y se representan `\0', y los almacena como una matriz de carácter. Ej: HOLA\0 ! `H', `O', `L', `A', `\0' ! donde \0 es el carácter de terminación • Identificadores: Son los nombre dados a variables, funciones, etiquetas u otros objetos definidos por el programador. Un identificador está formado por letras (mayúsculas o minúsculas), números y carácter de subrayado, con la condición de que le primer carácter no sea un número. Ej: Precio_Venta Verdadero Precio Venta Falso 1Num Falso _123 Verdadero De un identificador, sólo son significativos los primeros 32 caracteres. • Palabras reservadas: Son palabras especiales que no se pueden usar para nombrar otros elementos del lenguaje. NOTA: C hace distinción entre mayúsculas y minúsculas Ej: int, float (no se pueden usar) • Comentarios: El compilador reconoce como comentario cualquier grupo de caracteres situados entre \* *\ aunque estén en diferentes líneas. Se pueden definir comentarios en una sola línea mediante // Ej: //Esto es un comentario En este caso, no es necesario poner indicador de línea. • Operadores, expresiones, sentencias: Un operador es un símbolo que indica alguna operación sobre uno o varios objetos del lenguaje a los que se denominan operandos. − Atendiendo al número de operandos sobre los que actúa un operador, estos se clasifican en: • unitarios: cuando actúan sobre un solo operando • binarios: 2 operandos • ternarios: 3 operandos
3
− Atendiendo al tipo de operación que realizan, se clasifican en: • aritméticos • aritméticos • relacionales • lógicos • de tratamiento de bits • especiales Los operadores, junto con los operandos, forman expresiones. En una expresión, los operandos pueden ser constantes, variables o llamadas a funciones que devuelvan valores. Una expresión se convierte en una sentencia cuando va seguida de un ;. Cuando un grupo de sentencias se encierran entre llaves, { }, forman un bloque sintácticamente equivalente a una sentencia. OPERADORES ARITMÉTICOS
UNARIOS
BINARIOS
OPERADOR −
DESCRIPCIÓN Cambio de signo
−−
Decremento
++ −
Incremento Resta
+
Suma
*
Producto
/
División
%
Resto de división entera
− El valor devuelto por el operador de división (/) depende del tipo de operandos. Si éstos son enteros, devuelve la parte entera del cociente. Si alguno de ellos es real, devuelve el resultado como número real. − El operador de resto de división entera (%) equivale a mod Ej: X/Y siendo int x, y; el resultado es 4. X=9 Y=2 − Los operadores + + y − − aumentan o disminuyen respectivamente en una unidad el operando sobre el que actúan. Ej: C++ es lo mismo que C ! C + 1 C − − es lo mismo que C ! C − 1 Si el operador está antes de la variable, la operación de incremento o decremento se realiza antes de usar el valor de la variable. 4
Si el operador está después, primero se usa el valor de la variable y después se realiza la operación de incremento o decremento. − Los operadores relacionales se usan para expresar condiciones y describir una relación entre dos valores.
BINARIOS
OPERADOR >
DESCRIPCIÓN Mayor que
<
Menor que
>=
Mayor o igual que
<=
Menor o igual que
==
Igual que
!=
Diferente que
If (a==b) printf (Son iguales); Si el contenido de la variable a es igual al de b, muestra en pantalla la frase Son iguales El resultado de una expresión relacional solo puede ser verdadero o falso, lo que en C se identifica con los valores "0 y 0 respectivamente. La expresión a==b se evaluará como 0 si a y b son diferentes y como distinto de 0 si son iguales. Falta¿?¿?¿?¿? Actúan sobre expresiones booleanas, es decir, sobre valores V o F generados por expresiones como las del caso anterior. Son los siguientes: OPERADOR ! &&
UNARIOS BINARIOS
DESCRIPCIÓN NOT AND ||
OR
El resultado de una operación lógica viene dado por su tabla de verdad. a F F V V
b F V F V
a! V V F F
a&&b V F F V
a||b F V V F
Ej: X=20 x==y ! F(0) Y=4 x=y ! V
5
Z=5 x==(y*z) ! V − Operadores de tratamiento de bits: C incorpora ciertas operaciones sobre bits, propias del lenguaje ensamblador, como desplazamientos o manipulación individual de bits. Los operadores que realizan estas operaciones son los siguientes: OPERADOR DESCRIPCIÓN UNARIOS ~ not & and | ^ BINARIOS >> <<
or or exclusivo desplazamiento a la derecha desplazamiento a la izquierda
Los operadores and, or y not, se rigen por la misma tabla de verdad que gobierna los operadores lógicos equivalentes. La diferencia entre unos y otros consiste en que estos tres actúan a nivel de bits individuales y no sobre valores completos (&&, ||, !). Así, las variables a y b almacenan respectivamente los valores a ! 0xA1B2 B ! 0xF0F0 Las siguientes expresiones se evalúan de la forma: a&&b ! 1(V) a||b !1 (V) !a ! 0 (F) a&b ! 0xA0B0 a|b ! 0xF1B2 ~a ! 0x5E4D Los operadores &, |, ~, 0 y not, son idénticos respectivamente a las instrucciones del lenguaje ensamblador and, or y not. Por lo tanto, el operador and (&) permite poner ciertos bits a 0 dejando el resto inalterado, y el operador not (~), cambia los bit 1 por 0 y viceversa. El operador or exclusivo (^) es idéntico a ^XOR del lenguaje ensamblador. Su tabla de verdad es la siguiente: a F F V V
b F V F V
a^b F V V F
Ej:
6
a ! 0xA1B2 b ! 0x1234 a^b ! 0xB386 Los operadores de desplazamiento (>>,<<) derecha, izquierda, mueven todos los bits de una variable a la derecha o al la izquierda, respectivamente, un número de posiciones determinado. Su formato general es: variable<
>n Ej: a=b<<4 ! almacena en a el contenido de b después de realizar un desplazamiento de b de 4 bits a la izquierda. Al igual que en el lenguaje ensamblador, C distingue entre desplazamientos aritméticos y lógicos. El desplazamiento aritmético lo hacen sobre datos enteros y mantienen el signo. El desplazamiento lógico se realiza sobre datos declarados como sin signo (unsigned) y simplemente añade 0s. Son de tipo int. Ej: Sea a una variable declarada como entera (con signo) que almacena el valor hexadecimal A1B2, con lo que a ! 0xA1B2 a=a<<4 produce a ! 0x1B20 a=a>>4 produce a ! 0x0A1B − Operadores de asignación: Las asignaciones se realizan mediante el operador =. El uso de este operador tiene ciertos aspectos que lo distinguen de otros lenguajes. Son los siguientes: En primer lugar, se puede emplear cualquier número de veces en una expresión, por ejemplo, a=b=c=3; x=3; y=x+(z=6); El operador de asignación combina con los siguientes operadores: *, /, %, +, −, <<, >>, &, \, ^, para operaciones acumulativas. Ej: m*=5 equivale a m=m*5 m+=5 equivale a m=m+5 m+=y−3 equivale a m=m+y−3 m−=(y=5) equivale a m=m−(y=5)
7
m>>=(2*x+1) equivale a m=m>>(2*x+1) INSTRUCCIONES DE E/S − DE SALIDA: La instrucción de salida por excelencia es PRINTF. Nos permite mostrar por pantalla desde una constante, ya sea una cadena, número, hasta una variable de cualquier tipo. STDIO.H es la librería que contiene printf. Estándar input/output. El formato de printf es el siguiente: printf(cadena de control, lista de variables); * Se pueden omitir cosas de este formato. Ej: printf(se ha cometido un error); Si queremos mostrar el valor de una variable por pantalla, hacemos lo siguiente: printf(El valor de la variable es:%d, var); Lo que imprimiría por pantalla sería, El valor de la variable es: 3 Printf(Los valores de las variables son: %d, %d, var1, var2); Los valores de las variables son: 3, 5 TIPOS DE IDENTIFICADORES %D, %I ! toda variable definida como int. Los números enteros. %C ! con ella mostramos una variable de tipo char. %S ! nos permite representar una cadena de caracteres (un array de char (varias letras)). %E ! Nos permite representar coma flotante de forma exponencial. Un número de forma exponencial. %F ! número en coma flotante con notación decimal. Un float. %U ! un número entero sin signo %P ! nos permite mostrar el valor de un puntero (que almacena una dirección de memoria) %LD %LI ! muestran enteros largos (long int). Si un entero tiene 2 byte, un entero largo tiene 4 byte. %LT ! representamos un double.
8
%2.2f 25.38261 escala (2) y precisión (2) %.2f si no me importa el número de parte entera que saque. Esto se llama flash CÓDIGOS DE CONTROL Y CONSTANTES DE BARRA \ BARRA INVERTIDA \n ! a partir de este código se produce en la pantalla un salto de línea. \n\n\n (3 saltos de línea). La posición es importante. Siempre tiene que estar dentro de la cadena de control. \t ! se produce una tabulación. Cinco caracteres de desplazamiento por defecto. \t\t ( dos desplazamientos. \a ! Alerta. Cuando se pone, emite un beep, un sonido. Un aviso. \r ! para indicar un retorno de carro, que es un código ASCII 13. Cuando por ejemplo, pulsa intro. Cuando se pone \n, es un \r y un salto de línea. Si queremos que aparezca algo entrecomillado ponemos: \\ − DE ENTRADA: SCANF también está en STDIO.H. Nos sirve para introducir datos por el teclado, cualquier tipo de variable. Su formato es: scanf(cadena de control, lista de variables); Dentro de esta cadena, lo único que nos admite son los identificadores (%d, %i, etc), que son los mismos que en printf. p.e. scanf(%d, &variable); donde & es dirección de (variable). Si no se pone esto, no lo hace; toma variable como dirección y no lo ejecuta correctamente. scanf/%d, cadena); cadena 20 ! aquí no se pone &, por que el nombre del array de caracteres es un puntero a la posición del array (esto es para introducirlo de golpe). Si queremos meter carácter a carácter a carácter, ponemos scanf(%d, cadena) Sólo en estas situaciones es la excepción; por regla general siempre &.
9
Para introducir más de una variable en un scanf: scanf(%d %d %d %d, var1, var2, var3, var4); pero es preferible hacer varios scanf, 1 por variable. Se pueden introducir diferentes identificadores. Hay algunas veces que en el buffer del teclado se quedan 2 retornos de carro almacenados, esto implica que se salten algunas líneas. Para solucionarlo ponemos: fflush(stdin); siempre encima de scanf. Una excepción a esto es cuando queremos leer más de un carácter del teclado, teclas especiales (intro, sangría, etc.) Si ponemos scanf(3d, &var), estamos limitando la introducción a tres dígitos. BUCLES WHILE: While (condición) { sentencias; } Ejecuta las sentencias mientras se cumpla la condición. Si la condición es falsa, no entra en las sentencias. p.e. #include void main () int a=0, b=0; { while (a<=5) { b=b+a; a++ } } ej: programa que nos permita introducir dos números por teclado y nos diga cual es el mayor. 10
#include void main () { int a, b; printf(Introduce un numero); scanf(%d, &a); printf(Introduce un numero); scanf(%d, &b); if (a>b) { printf(\nEl mayor es %d, a); } else { printf(\nEl mayor es %d, b); } } IF_ELSE: if (condición) { sentencias } else { sentencias }
11
If evalúa la condición; si es V ejecuta las sentencias sino, se pasa a else. Con una sola sentencia: If(x==0) { printf(HOLA); } else { printf(ADIOS); } Si tenemos varias sentencias por ejecutar: if(x==0) { a=a+1; b=b+1; printf(Suma %d, a+b); } else {
} Aquí podemos utilizar los operadores lógicos AND OR. También podemos tener varios if y varios else. SWITCH: Es una condición múltiple y comprueba el valor de la variable sucesivamente frente a una lista de variables. Su formato: switch variable { 12
case constante 1: sentencias; break; case constante 2: sentencias; break; . default: sentencias; break; } Si la variable es igual a constante 1, salta a la sentencia, hace break y pasa al final del switch. Si no coincide ninguna, salta directamente a default (valor por defecto). p.e. #include void main () { char ch; printf(\n1.− Comprueba la ortografía); printf(\n2.− Corrige errores); . scanf(%c, ch); switch (ch) { case 1: . break; 13
case 2: . Break;
default: printf(Ninguna es valida); } } WHILE: Toda condición que en C devuelve un 0 es falsa y cualquier otro número, verdadero. Ejemplo de bucle infinito que da 0, puede que nos convenga tenerlo: #include void main () { int a=0, b=0; while (a) { b=b+a; a++ } printf(%d, b); } DO WHILE: do { sentencias; }while (condición)
14
Éste es prácticamente igual que while pero éste ejecuta al menos una vez, porque la condición se ejecuta al final, al contrario que en while, que se ejecuta al principio. FOR: Es uno de los más útiles y de los más usados. Se utiliza mucho para arrays. for(valor inicial; condición; incremento o decremento) { sentencias } p.e. for(a=7; a>10; a++) { sentencias } p.e. for(a=o, b=7; a<10; a++, b++) for(a=0, b=7; a<10&&b>20;a++,b++) CONTINUE: Provoca un salto en la ejecución del bucle continuando a la siguiente iteración. for( ; ; ) { −− −− if(condición) {continue;} −− −− } 15
En distintas circunstancias puede haber iteraciones que no se ejecuten. GOTOXY: gotoxy (columna, fila); Normalmente se pone antes de un scanf o un printf para posicionar el cursor en un lugar determinado de la pantalla. Esto está en la librería #include SECUENCIAS DE ESCAPE CARÁCTER Campana (alerta) Retroceso Tabulador Horizontal Nueva Línea Tabulador Vertical Nueva Página Retorno de carro Comillas Apóstrofe Interrogación Barra Invertida Nulo
SECUENCIA DE ESCAPE \a \b \t \n \v \f \r \ \' \? \\ \0
VALOR ASCII 007 008 009 010 011 012 013 034 039 063 092 000
RESUMEN DE OPERADORES GRUPO DE PROCEDENCIA Función, formación, miembro de estructura, puntero a miembro Operadores monarios Multiplicación, división y resta aritmética Suma, resta aritmética Operadores de desplazamiento a nivel de bits Operadores racionales Operadores de igualdad y a nivel de bits 0 exclusivo a nivel de bits 0 a nivel de bits y lógica 0 lógico Operador condicional Operadores de asignación Operador coma
OPERADORES
ASOCIATIVIDAD
() [] . −>
Izq ! Dcha.
−− ++− ! ~ * & sizeof */% +− << >> <<= >>= == != & ^ | && || ? = += −= *= /= %= &= ^= <<= >>= /
D!I I!D I!D I!D I!D I!D I!D I!D I!D I!D I!D D!I D!I I!D
16
TIPOS DE DATOS Y REGLAS DE CONVERSIÓN DE DATOS TIPO DE DATO DESCRIPCIÓN REQUISITO DE MEMORIA int Cantidad entera 2 bytes o 1 palabra (varia de un pc a otro) Cantidad entera corta (puede contener short 2 bytes o 1 palabra menos dígitos que int) Cantidad entera larga (puede contener long 1 o 2 palabras más dígitos que int) Cantidad entera sin signo (no negativa) (la unsigned cantidad máxima permisible es 2 bytes o 1 palabra aproximadamente el doble de int) char Carácter 1 byte Carácter con valores en el rango −128 a signed char 1 byte +127 unsigned char Carácter con valores en el rango 0 a 255 1 byte Número en coma flotante (un número que 1 palabra float contiene un punto decimal) Número en coma flotante de doble double precisión (+ cifras significativas y un 2 palabras exponente que puede ser mayor absoluto) Número en coma flotante de doble long double precisión (puede tener mayor precisión 2 o más palabras que un double) Tipo de dato especial para funciones que No aplicable void no devuelven ningún valor Constante de enumeración (tipo especial 2 bytes o una palabra enum de int) CARÁCTER C D E F G
PRINTF El dato se muestra como carácter El dato se muestra como decimal El dato se muestra como coma flotante con exponente El dato se muestra como coma flotante sin exponente El dato se muestra como coma flotante usando la falta?
LA INSTRUCCIÓN CONTINUE Se utiliza para saltarse el resto de la pasada actual a través de un bucle. El bucle no termina cuando se encuentra una instrucción continua, sencillamente, no se ejecutan las sentencias que se encuentren en el bucle y se salta directamente a la siguiente pasada a través del bucle. La instrucción continua se puede incluir dentro de una instrucción while, do while o for. Su sintaxis es: continue; Ej: do{ 17
scanf(%f, &x); if(x<0){ printf(ERROR − VALOR NEGATIVO DE X); continue; } −−−− }while (x>=100) for (cont=1;x>=100;cont++){ scanf(%f, &cont); if (cont>0){ printf(ERROR − VALOR NEGATIVO DE X); continue;} } En cada caso no se ejecutará la parte en la que se procesa el valor actual de cont si éste es negativo, se continuará en este caso con la siguiente pasada del bucle. SCANF: Se puede utilizar para introducir cualquier combinación de valores numéricos, caracteres sueltos cadenas de caracteres. La función devuelve el número de datos que se ha conseguido introducir correctamente. Su sintaxis es: scanf(cadena de control, arg1, arg2,, argn); En la cadena de control se incluyen los grupos individuales con un grupo de caracteres por cada dato de entrada. Cada grupo de caracteres debe comenzar por el signo de porcentaje seguido de un carácter de conversión que indica el tipo de dato correspondiente. Los argumentos pueden ser variables o formaciones y sus tipos deben coincidir con los indicados por los grupos de caracteres correspondientes. Cada nombre de variable debe ser precedido por un &, sin embargo, los nombres de formaciones no deben ir con &. La cadena de caracteres introducida por el dispositivo de caracteres estándar puede tener cualquier código ASCII excepto el de nueva línea. Falta Los caracteres consecutivos que no sean de espaciado y que componen un dato definen, en conjunto, un campo. Es posible limitar el número de caracteres espaciados, una longitud de campo máxima para cada dato. 18
Para hacer esto, se introduce en la cadena de control un entero sin signo que indica la longitud de campo entre el % y el carácter de conversión %3d. El dato puede estar compuesto por menos caracteres de los que especifique la longitud del campo, sin embargo, el número de caracteres del dato real no puede exceder la longitud del campo especificado. No se leerán los caracteres que se encuentren más allá de la longitud de campo especificada. Estos caracteres sobrantes pueden interpretarse de forma incorrecta como los componentes del siguiente dato. La mayoría de las versiones de C permiten que ciertos caracteres de conversión, en la cadena de control, sean precedidos por un prefijo de una sola letra, que indica la longitud del argumento correspondiente, por ejemplo, l se utiliza para indicar un argumento entero largo, tanto con signo como sin signo o un argumento de doble precisión. La h se utiliza para indicar un entero corto tanto con signo como sin signo y también en algunas versiones, la L para tipo doble largo. #include void main () { short ix, iy; long lx, ly; double dx, dy; .. scanf(%hd %ld %lf, &ix, &lx, &dx);
scanf(%3ho %7lx %15le2, &iy, &ly &dx); %hd ! indica que el primer dato será asignado a una variable entera corta en decimal. %ld ! será asignado a una variable larga en decimal. %3ho ! tendrá una longitud máxima de campo de 3 caracteres y será asignado a una variable entera corta octal. %7lh ! longitud máxima de 7 caracteres asignada a una variable entera larga en hexadecimal. %15le ! longitud máxima de 15 caracteres asignada a una variable de doble precisión. En la mayoría de las versiones de C es posible saltarse un dato sin que le sea asignado a una determinada variable o formación. Esto se denomina supresión de asignación (*). char concepto [80]; int no_part;
19
float coste; scanf(%s %*d %f, concepto, &no_part, &coste); Si la cadena de control contiene varios grupos de caracteres sin estar separados por caracteres de espaciado, se debe tener cuidado con la conversión de tipo c. En estos casos ¿falta? se interpretará como un dato más. Para saltarse estos espacios y leer el siguiente carácter que no sea espacio, se debe utilizar el grupo de conversión %15. #include void main () { char c1, c2, 3;
scanf(%c%c%c, &c1, &c2, &c3);
Cuando se encuentren dentro de la cadena de control caracteres no reconocidos, se espera que aparezcan estos en los datos de entrada. Estos caracteres de entrada se leerán pero no se asignarán a ningún identificador. Si la entrada no coincide con los caracteres de la cadena de control, terminará la ejecución de la función scanf. #include void main () { int i; float x; .. scanf(%d a %f, &i, &x); PRINTF: Se utiliza para escribir cualquier (falta) caracteres sueltos y cadenas de caracteres. Es análoga a la función de entrada scanf con la diferencia de que su propósito es visualizar datos en lugar de introducirlos en el ordenador. La función printf se ocupa de transferir datos de la memoria del ordenador al depósito de salida estándar. Su sintaxis es: printf(cadena de control, arg1, arg2, , argn);
20
Donde cadena de control hace referencia a una cadena de caracteres que contiene información sobre el formato de salida. Los argumentos (arg) representan los datos de salida. Éstos pueden ser: • constantes • variables simples • nombres de formaciones En contraste con scanf, los argumentos de printf no representan direcciones de memoria por lo que no están precedidos de &. La cadena de control está compuesta por grupos de caracteres, con un grupo de caracteres por cada saldo de salida. Cada grupo de caracteres debe empezar por %. En su forma más sencilla, un grupo de caracteres consistirá en un % seguido de un carácter de conversión que indica un carácter correspondiente. Pueden incluirse varios grupos de caracteres seguidos o muchos separados. Es muy común el uso de espacios en blanco como separadores de grupo de caracteres. #include #include > void main () { char concepto [20]; int no_part; float coste;
printf(%s %d %f, concepto, no_part, coste);
La conversión tipo f y la de tipo e se utilizan para visualizar valores en coma flotante, sin embargo, la última hace que se incluya en la salida el exponente, mientras que en la primera no. #include #include void main () {
21
double x=5000.0, y=0.0025; printf(%f %f %f \n\n, x, y, x*y, x/y); printf(%e %e %e %e, x, y, x*y, x/y);
En la función printf se utiliza la conversión de tipo s para visualizar una cadena de caracteres que acaba en el carácter nulo \0. Se pueden incluir caracteres de espaciado en la cadena de caracteres. #include void main() { char línea [20]; scanf( %[^\n], línea); printf(%s, línea); Se puede especificar una longitud de campo mínima anteponiendo al carácter de conversión un entero sin signo. Si el número de carácter del dato correspondiente es menos que la longitud de campo especificado, entonces, el dato será precedido por los espacios en blanco necesarios para que se consiga la longitud del campo especificado. Si el número de caracteres del dato excede de la longitud de campo especificada, se visualizará el dato completo. #include main () { int i=12345; printf(%3d %5d %8d, i, i, i); saldría: 123645 12345 12345 También es posible especificar el máximo número de cifras decimales para un valor en coma flotante o el máximo número de caracteres para una cadena de caracteres. Esta especificación e denomina precisión. La precisión es un entero sin signo que siempre es precedido por un punto decimal. Si se especifica la longitud de campo mínima, además de la precisión como es habitual, entonces la especificación de la precisión sigue a la especificación de la longitud de campo. Estas dos especificaciones enteras preceden al carácter de conversión. Un número en coma flotante se redondeará si se debe recortar para ejecutar la precisión. #include 22
main () { float x=123.456; printf(%7f %7.3f %7.1f\n\n, x, x, x); printf(%12e %%12.5e %12.3e, x, x, x); } saldría: 123.456000 123.456 123.5 1.234560e+03 1.23456e+02 1.235e+02 Las expresiones de campo mínima y de precisión, se pueden aplicar a datos de tipo carácter además de los datos numéricos. Cuando se aplica a una cadena de caracteres, la longitud de campo mínima se interpreta de la misma forma que con una cantidad numérica, es decir, se añaden espacios en blanco si la cadena de caracteres es más corta que la longitud de campo mínima especificada, por tanto, la especificación de la longitud de campo mínima no impedirá nunca que se visualice la cadena de caracteres completa. Sin embargo, la especificación de la precisión determina el máximo número de caracteres que pueden ser visualizados. Si la precisión especificada es menor que el número total de caracteres de la cadena, no se mostrarán los caracteres sobrantes de la parte de la derecha de la cadena. Esto ocurrirá aún cuando la longitud de campo mínima sea mayor que la cadena de caracteres añadiéndose en este caso carácter en blanco a la cadena truncada. #include main () { char línea [12]; printf(%1os %15s %.5s, línea, línea, línea); } La mayoría de las versiones de C: permiten el uso de prefijos dentro de la cadena de control para indicar la longitud del argumento correspondiente. Los prefijos permitidos son los mismos que los prefijos utilizados con la función scanf. Algunos caracteres de conversión se escriben en mayúsculas (p.e.: X, L, G); hacen que cualquier letra de los datos de salida se presenten en mayúsculas en este caso Además de la longitud de campo mínima, la precisión y el carácter de conversión, cada grupo de la cadena de control puede incluir un indicador que afecta a cómo aparecerá en la salida. Algunos compiladores permiten que aparezcan 2 o más indicadores seguidos dentro del mismo grupo de caracteres. 23
INDICADORES MÁS COMUNES
#include void main () { int 1=123 float x=12.0, y=−3.3 printf(:%6d %7.0f %10.1e:\n\n, i, x, y); printf(:%−6d %−7.0f %−10.1e:\n\n, i, x, y); printf(:%+6d %+7.0f %+10.1e:\n\n, i, x, y); printf(:%−+6d %−+7.0f %−+10.1e:\n\n, i, x, y); printf(:%7.0f %#7.0f %7g %#7g:\n\n, x, x, y, y); } INTRODUCCIÓN A LAS SENTENCIAS DE CONTROL EN C SENTENCIA IF: Es una de las sentencias de selección o condicional, su funcionamiento se rige por el resultado de una prueba condicional que evalúa si es verdadero o falso. Sintaxis: if(expresión)sentencia; Donde (expresión) puede ser válida en C; si la expresión se evalúa como verdadera se ejecutará la sentencia, sino lo es, se pasa por alto la sentencia y se ejecuta la línea de código que sigue a if. 24
En C, una expresión es verdadera si se evalúa a cualquier valor distinto de cero; si se evalúa a cero es falsa. A la sentencia que sigue a if se la conoce habitualmente como el objetivo de la sentencia if. p.e. #include void main () { int num; printf(\nIntroduce un número:); scanf(%d, &num); if(num>0) printf(El numero es positivo) if(num<0) printf(El número es negativo); } SENTENCIA IF_ELSE: Sintaxis: if(expresión) sentencia1; else sentencia2; Si la expresión es verdadera entonces se ejecutará el objetivo de if, y saltará a else. Si la expresión es falsa, se pasa por alto el objetivo de if y se ejecutará el objetivo de else. Nunca se ejecutarán las dos sentencias. p.e. #include void main () { int num; 25
printf(\nIntroduce un número:); scanf(%d, &num); if(num>0) printf(El numero es positivo) else printf(El número es negativo); } CREACIÓN DE BLOQUES DE CÓDIGO: En C se pueden enlazar dos o más sentencias, a esto se le llama bloque de código. Para crearlo, se rodean las sentencias en el bloque con llave de apertura y cierre. Una vez hecho esto, las sentencias forman una unidad lógica que se puede utilizar en cualquier lugar donde pueda hacerlo una sentencia sencilla. Sintaxis: if (expresión){ sentencia1; sentencia2; . sentenciaN; } else{ sentencia1; sentencia2; sentenciaN; } Un bloque de código presenta una unidad lógica indivisible, esto significa que bajo ninguna circunstancia se podría ejecutar una de las sentencias printf sin que se ejecuten también las otras. p.e. #include void main () { 26
float num; int cambio; printf(\n\n1. Pies a metros \n2. Metros a pies); printf(\Elige una opción:); scanf(%d, &cambio); if(cambio==1){ printf(\nIntroducir pies: ); scanf(%f, &num); printf(Metros: %f, num/3.28); } else{ printf(\nIntroducir metros: ); scanf(%f, &num); printf(Pies: %f, num*3.28); } } ANIDAMIENTO DE SENTENCIAS IF: Cuando una sentencia if es el objetivo de otro if o else, se dice que está anidada dentro del if más externo. Un if anidado puede aparecer dentro de un bloque de sentencias que sean el objetivo del if más externo. Un compilador del estándar ANSI permitirá al menos hasta 15 niveles de anidamientos de if. Se pueden poner juntos varios if y else en la misma cadena o escalera if_else_if. En esta situación, un if anidado tiene como objetivo otro if. Sintaxis: if(expresión) sentencia; else if(expresión)sentencia; else if(expresión)sentencia; ..
27
else sentencia; Las condiciones se evalúan de arriba abajo, tan pronto como se encuentre una condición verdadera se ejecuta la sentencia asociada a ella y se pasa por alto el resto de la escalera; si ninguna de las condiciones es verdadera, se ejecutará el último else. INTRODUCCIÓN DE CARACTERES: La versión original de C definía una función llamada getchar() que devuelve un carácter introducido por teclado. Una vez llamada la función, espera a que se pulse una tecla, entonces, getchar() devuelve el valor de la tecla solicitante. La función getchar() está definida por el estándar ANSI y requiere del archivo de cabecera p.e. #include void main () { char c; c= getchar(); printf(Ud. Escribió: %c, c); } GETCH( ): Se utiliza igual que getchar() excepto que devolverá su valor inmediatamente después de haberlo introducido, sin necesidad de pulsar intro. Para la mayoría de los compiladores, esta función requiere el archivo de cabecera . En C podemos comparar caracteres, igual que se comparan números ya que están asociados al código ASCII y en secuencia ordenada. p.e. #include #include void main () { char c; printf(\nIntroduce un carácter: );
28
c=getch(); printf(\nSu código ASCII es %d, c); } UTILIZACIÓN DEL BLOQUE FOR: Se utiliza para repetir una sentencia o bloque de sentencias un número de veces especificado. Sintaxis: for(inicialización; comprobación adicional; incremento) sentencia; Inicialización: se utiliza para un valor inicial que controla el bucle, se suele denominar como variable de control del bucle; se ejecuta una sola vez antes de que comience el bucle. Comprobación adicional: verifica la variable de control del bucle frente a un valor objetivo cada vez que se repite el bucle. Si la comprobación condicional es verdadera, el bucle se repite. Si es falsa, el bucle se detiene y la ejecución del programa se reanuda en la siguiente línea de código que sigue al bucle. Esta comprobación se lleva a cabo al principio del bucle, cada vez que el bucle se repite. Incremento: se ejecuta después de que se haya ejecutado la sentencia o bloque de sentencias, pero antes que la comprobación condicional. Su propósito es aumentar o disminuir el valor de control del bucle en una cierta cantidad. p.e. #include main() { int num; for(num=1; num< 11; num=num+1) { printf(%d, num); } printf(Terminado); } Para repetir varias sentencias utilizaremos un bloque de código como objetivo del bucle for. Ej: Producto y suma de los números del 1 al 10. #include
29
main() { int num, sum, prod; sum=0; prod=1; for(num=1; num< 11; num++) { sum=sum+num; prod=prod*num; } printf(Producto y suma %d %d, prod, sum); } Un bucle for se puede ejecutar de forma negativa, esto sería decremento en vez de incremento. Además, la variable de control del bucle, se puede incrementar o decrementar en más de uno. #include main() { int num=0; for(num=0; num< 101; num=num+5) printf(%d, num); } Si la variable de control del bucle ya se ha inicializado desde fuera del bucle for, no es necesario una expresión de inicialización. Ej: Programa que se ejecuta hasta que se introduzca una `q' #include #include main()
30
{ int i; char c; c= `a'; for(i=0; c= `q'; i++){ printf(paso: %d\n, i); c=getch(); } } En lugar de comprobar una variable de control del bucle, la prueba condicional de este for verifica el valor de un carácter introducido por el usuario. Ej: Programa que pide un nº al usuario. #include main() { int i; printf(Introducir un entero: \n); scanf(%d, &i); for ( ; i ; i −−){ printf(%d, i); } } Ej: Programa que se ejecuta hasta que introduzcas una `q' #include #include main() { 31
char c; for(c= getch(); c!= `q'; c= getch()){ printf(entrada a la q); } } La razón por la que el objetivo de for puede estar vacío es porque C permite sentencias nulas; utilizando for es posible crear un bucle que no se detenga nunca, esto es, un bucle infinito. for( ; ; ) Cuando no hay expresión en la porción condicional, el compilador asume que es verdadero, por eso, el bucle continúa ejecutándose. En C, a diferencia de la mayoría de los lenguajes, es perfectamente válido alterar la variable de control del bucle desde fuera de la sección de incremento. Ej: Programa que incrementa la i al final del bucle #include main() { int i; for(i= 0; i<10 ;){ printf(%d, i); i++; } } BUCLE WHILE: El objetivo de un while es también un bucle de código; el bucle while funciona repitiendo su objetivo mientras la expresión sea cierta. Cuando ésta es falsa, el bucle se detiene. while (expresión) sentencia; El valor de la expresión se comprueba al principio del bucle, esto significa que, si la expresión es falsa al iniciarse, el bucle no se ejecutará ni una sola vez. #include 32
#include main() { char c; c= getch(); while (c!= `q'){ c= getch(); printf(encontrada la q);} } Ej: Programa que traduce los caracteres que se escriban a un formato codificado; anadiendo un 1 a cada letra. El programa se detiene cuando se pulsa intro. #include #include main() { char c; printf(Introduce un mensaje: \n); c= getch(); while (c!= `\n'){ printf(%c, c+1); c= getch(); } } BUCLE DO WHILE: El bucle do repite la/s sentencia/s mientras la expresión es verdadera, se detiene cuando la expresión se convierte en falsa. El bucle do es único, ya que siempre ejecuta el código de dentro del bucle al menos una vez dado que la expresión que controla el bucle se comprueba al final del mismo. do{ sentencias; }while (expresión); Ej: Pide al usuarío qué quiere hacer con dos números. 33
#include #include main() { int a, b; char c; printf(\n\nQuiere\n); printf(Sumar, Restar, Multiplicar o Dividir\n); do{ printf(Introduzca la primera letra: \n); c=getch(); printf(\n); }while (c!= `S' && c!= `R' && c!= `M' && c!= `D'); printf(Introduzca el primer número: \n); scanf(%d, &a); printf(Introduzca el segundo número: \n); scanf(%d, &b); if (c== `S'){ printf(%d, a+b); else if (c== `R') printf(%d, a−b); else if(c== `M') printf(%d, a*b), else
34
if(c== `D') printf(%d, a/b); } } El bucle do es especialmente útil cuando el programa que está esperando a que ocurra un suceso. CREACIÓN DE BUCLES ANIDADOS Cuando el cuerpo de un bucle contiene otro, se dice que el segundo está anidado en el primero. Cualquiera de los bucles de C puede estar anidado dentro de cualquier otro bucle. En C, el estándar ANSI especifica que los bucles pueden estar anidados hasta 15 niveles. Ej:Imprime en pantalla los números del 1 al 10. for(i=0;i<10;i++){ for(j=1; j<10; j++){ printf(%d, j); } } Utiliza for para imprimir el alfabeto 3 veces, y cada vez las letras 2 veces. #include #include main() { int i, j, k; for(i=0; i<3;i++){ for(j=0; j<26;i++){ for(k=0; k<2;i++){ printf(%c, \'+j); } }
35
} } UTILIZACIÓN DE BREAK PARA SALIR DE UN BUCLE Permite Salir de un bucle desde cualquier puntode su cuerpo, pasando por alto su espresión de finalización normal. Cuando break se encuentra dentro de un bucle, el bcle termina inmediatamente y el control del progranama continua en la sentencia que continua al bucle. Programa que imprima del 1 al 100 pero cuando llegue al 10 salte. #include #include main() { int i; for(1=1;i<100;i++){ printf(%d, i); if(i==10){ break; } } } La sentencia breaK se utiliza en bucles en los que una condición especial puede causar una terminación inmediata. Todos los numeros múltiplos de 6 #include #include main() { char c; int i; 36
for(i=1;i<10000;i++){ if(!=(i%6)){ printf(%d ¿mas? (S/N), i); c=getch(); if(c= `N'){ break; printf(\n); } } } } BUCLE SWITCH: Es una sentencia de selección múltiple de C. Se utiliza para elegir un camino entre varios caminos alternativos de la ejecución del programa y funciona asi: se compara una variable con una lista de constantes enteras o de carácter, cuando concuerda con alguna se ejecuta la secuencia de sentencias asociadas con esa constante. switch (variable){ case 1: secuencia de sentencias; break; case n: secuencia de sentencias; break; default: secuencia de sentencias; break; } Donde la secuencia de sentencias de default se ejecutan si no coincide con ninguna de las otras. Default es opcional. Si no hay coincidencias y no existe el default, no se lleva a cabo ninguna opción. Cuando se encuentra alguna coincidencia, se ejecutan las sentencias asociadas con el `case' hasta que se 37
encuentra con un `break', o en el caso de default o en el último case, hasta que se alcance el final del switch. Programa que recorre los numeros 1, 2, 3 y 4 e imprime el nombre del que se ha introducido: #include main() { int i; printf(Introduce un numero del 1 al 4: \n); scanf(%d, &i); switch(1){ case 1: printf(uno); break; case 2: printf(dos); break; case 3: printf(tres); break; case 4: printf(cuatro); break; default printf(número desconocido); break; } } La sentencia `switch' se diferencia de `if' en que `switch' solamente puede verificar la igualdad, mientras que el `if', puede ser de cualquier tio, a demás, `switch' sólo funcionará con tipos int y char. Las secuencias de sentencias asociadas con cada case no son bloques, por lo tanto, no van encerrados entre llaves. El estándar ANSI estable que se permiten, por lo menos, 257 sentencias case. No puede haber dos constantes case con valores idénticos en el mismo switch. Es posible tener un switch como parte de una secuencia de sentencias de otro switch más externo, esto se llama switch anidado. Si las constantes case del switch más externo y más interno contienen valores comunes, no surgirá error.
38
La sentencia switch se utiliza a menudo para procesar órdenes de menú. #include #include main() { int a, b; char c; printf(\n\n¿Quiere\nSumar, Restar, Multiplicar, Dividir?\n); do{ printf(Introduzca la primera letra: ); c=getch(); printf(\n); }while ((c!= `S')&&(c!= `R')&&(c!= `M')&&(c!='D')) printf(Introduzca el primer numero: ·); scanf(%d, &a); printf(Introduzca el segundo numero: ·); scanf(%d, &b); switch (c){ case S: printf(%d, a+b); break; case R: printf(%d, a−b); break; case M: printf(%d, a*b); break; case D: if(b!=0){ printf(%d, a/b);
39
break;} } } La sentencia `break' es opcional. Cuando no existe, la ejecución pasa al siguiente `case' y solo se detiene cuando encuentra una sentencia `break' o el final del switch. La sentencia de secuencias asociada a `case' puede estar vacía, esto permite que dos o mas `case' compartan una secuencia de sentencias común sin duplicación de código. #include #include main() { char c; printf(Introduce una letra: ); c=getch(); switch (c){ case a: case e: case i: case o: case u: printf(es una vocal\n); break; default: printf(Es una consonante); } } ARRAYS Y CADENAS: DECLARACION DE ARRAYS UNIDIMENSIONALES 40
En C, un array es una lista de variables del mismo tipo que se referencian por un nombre común a una variable individual del array. Los arrays constituyen un modo adecuado de gestionar grupos de datos relacionados. Sintaxis: tipo nombre_de_variable [tamaño] Tipo: es un tipo válido de datos en C. Nombre de variable: nombre del array. Tamaño: número de elementos del arrray. Ej: array entero de 20 elementos ! int miarray[20]; Se accede a un elemento de un array mediante un índice utilizando el nº del elemento. En C, todos los arrays empiezan por 0, esto significa, que si se quiere acceder al primer elemento de un array, se utiliza 0 para el índice. Para acceder por índice a un array, especificamos dentro de corchetes el número del índice del elemento deseado. Por ejemplo, asignamos al primer elemento de miarray un valor 100. miarray[0]=100; C almacena los arrays unidimensionales en una posición de memoria contigua con el primer elemento en la dirección más baja. Ej: .. int i[5]; int j; for(j=0;j<5;j++) i[j] = j;
El array tendría este aspecto:
I
0 0
1 1
2 2
3 3
4 4
Se puede utilizar el valor de un elemento del array en cualquier lugar en el que se utilizaríz una variable o una constante. Ej: Programa que carga el array sqrs con los cuadrados de los números del 1 al 10 y despues los muestra. #include main () { int sqrs[10];
41
int i; for (i=1; i<10; i++){ printf(%d, sqrs[1]); } } Cuando se quiere utilizar scanf para introducir un valor numérico en un elemento del array, basta con poner & delante del elemento del array. Ej: scanf(%d, &cont[9]); C no realiza ninguna comprobación de los límites de los arrays, esto significa que ees posible que sobrepase el límite de un array. Por ejemplo, si se declara que un array llamado `a' tiene 5 elementos, el compilador permitirá el acceso al décimo elemento inexistente con una sentencia como a[9]; por supuesto, intentar acceder a elementos inexistentes del programa dará error en el programa. En C, no se puede asignar un array completo a otro. Ej: char a1[10], a2[10];
a2=a1 NO!! se puede hacer esto . Si se quieren copiar los valores de todos los elementos de un array en otro array se debe hacer copiando cada elemento por separado. Ej: Programa que lee la temperatura al mediodia de cada día del mes y después informa de la media de temperatura mensual así como de los días más fríos y más calurosos. Min 200, Max 0. #include main() { int temp[31], i, min, max, med, tot; int dias; printf(¿Cuántos días tiene el mes?); scanf(d, &dias); for(i=0;i
42
} /*media*/ tot=0; for(i=0; itemp[i]){ min=temp[i]; } if (max>temp[i]){ max=temp[i]; } } printf(Temperatura mínima: %d, min); printf(Temperatura máxima: %d, max); } Para copiar los contenidos de un array en otro se debe copiar cada elemento explícitamente por separado. Ej: Programa que carga a1 con los números del 1 al 10 y después los copia en a2. #include main()
43
{ int a[10], a2[10]; int i; for(i=1;i>11;i++){ a1[i−1]=i; } for(i=1;i>11;i++){ a2[i−1]=a1[i−1]; } for(i=1;i>11;i++){ printf(%d, a2[i−1]; } } Ej: Programa que lee una cadena y la codifica; el usuario introduce primero el mensaje que se almacena en una cadena de caracteres cuando el usuario pulsa intro y se codifica el mensaje añadiendo una a cada letra. #include #include main() { char men[80]; int i; printf(Introducir mensaje(menos de 80 caracteres)); for(i=0;i<80;i++){ men[i]=getch(); if(men[i]== `\r'){ break; } 44
} for(i=0;men[i]!= `\r';i++){ printf(%c, men[i]+1); } } Los arrays son especialmente útiles cuando se quiere ordenar la información. Un método de ordenar la información es el llamado `métoso de la burbuja', que consiste en la comparación repetitiva y, si es necesario, el intercambio de elementos adyacentes. Son como pequeñas burbujas en un tanque de agua en el que cada burbuja busca su propio nivel. UTILIZACIÓN EN CADENAS El uso más común de un array unidimensional en C es la cadena. C no tiene incorporado un tipo de datos de cadena sino que soporta cadenas utilizando arrays unidimensionales de caracteres. Una cadena se define como un array de caracteres con un carácter de terminación nulo (\0). El hecho de que la cadena deba terminar en un carácter nulo significa que para declarar un array de caracteres, es necesario que sea de un carácter más que la cadena más larga que tenga que contener para dejar sitio al carácter nulo. En una constante de cadena, el compilador pone automáticamente un carácter nulo de terminación. Para leer una cadena es necesario utilizar la función gets() con el archivo de cadena stdio.h. Para utilizar gets(), se le llama utilizando un array de caracteres sin ningún índice. La función gets lee caracteres hasta que se pulsa intro. El retorno de carro no se almacena pero lo reemplaza por un carácter nulo que termina la cadena. Ej: Programa que lee y escribe una cadena introducida por teclado. #include #include main() { char str[80]; int i; printf(Introduzca cadena (máximo 80 caracteres)\n); gets(str); for(i=0;str[i];i++){ printf(%c, str[i]); } 45
} Este programa utiliza el hecho de que un carácter nulo es falso, para controlar el bucle que muestra la cadena. La función gets no utiliza comprobación de límites, por eso el usuario no puede introducir más caracteres de los que puede contener el array con el que se llama a gets. #include #include main() { char str[80]; int i; printf(Introduzca cadena (máximo 80 caracteres)\n); gets(str); printf(str); } Dado que el primer argumento para printf es una cadena, simplemente se utiliza str, sin ningún índice, como el primer argumento para printf. Si se quisiera mostrar una nueva línea, se mostraría str así: printf(/%s\n, str); Este métodso utiliza el especificador de formato %s seguido del carácter de nueva línea y utiliza el array como segundo argumento para que concuerde con el especificador %s. La biblioteca de C suministra muchas funciones relacionadas con cadenas, las cuatro más importantes son: strcpy(), strcmp(), strcat(), strlen(). − strcpy(hacia, desde); ! Copia el contenido del `desde' en `hacia'. Los contenidos de `desde' no se cambian. Ej: Programa que copia la cadena hola en str y los muestra por pantalla. #include #include main() {
char str[80];
46
strcpy(str, hola); printf(%s, str);
Esta función no realiza comprobación de límites, por tanto, debemos asegurarnos de que el arra receptor es lo suficientemente grande para contener lo que está copiando, incluyendo el carácter de terminación nulo. − strcat(hacia, desde); ! Añade los contenidos de ua cadena en otra, esto es, los concatena (concatenación). Añade los contenidos de `desde' a los contenidos de `hacia'. No realiza comprobación de límites. Ej: #include #include main() {
char str[80]; strcpy(str, hola); strcat(str, ahí); printf(str);
Esto se muestra: hola ahí − strcmp(C1, C2); ! Compara dos cadenas. Devuelve 0 si las cadenas son iguales. Devuleve un valor negativo si C1 es menor que C2. Devuelve positivo si C1 es mayor que C2. Las cadenas se comparan según el diccionario. La comparación no se basa en la longitud de la cadena. Esta comparación es sensible a las mayúsculas y minúsculas, siendo estas últimas mayores que las mayúsculas. Ej: Imprimiría 0 Printf(%d, strcmp(uno, uno); − strlen(str); ! Devuelve la longitud de la cadena de caracteres. No tiene en cuenta el carácter de terminación nulo. Ej: Programa que pide que se introduzcan dos cadenas y hace una demostración de las cuatro funciones de cadena con ellas. #include 47
#include main() { char str1[80], str2[80]; int i; printf(Introducir la 1ª cadena: ); gets(str1); printf(Introduce la 2ª cadena: ); gerts(str2); /*longitud*/ printf(%s es de %d caracteres de largo\n, str1, strlen(str1)); printf(%s es de %d caracteres de largo\n, str2, strlen(str2)); /*comparar*/ i=strcmp(str1, str2); if(!i){ printf(Las cadenas son iguales\n); } else{ if(i
48
strcat(str1+str2); printf(%s\n, str1); /*copiar str2 en str1*/ strcpy(str1, str2) printf(%s %s\n, str1, str2); } LIBRERIAS
para funciones de clasificación de caracteres. para adaptar distintas convenciones culturales funciones matematicas comunes para ejecutar sentencias goto no locales entre funciones para acceder a listas de argumentos de longitud variable para funciones de entrada y salida válidas para asignacion de almacenamiento, clasificacion y búsqueda, y varias funciones de conversion para funciones que manipulan cadenas para manejo de la hora y fecha para definir el macro assert que es útil para el diagnóstico de errores lógicos en el programa para comprobar el valor almacenado en errno por ciertas funciones de librería. Al arrancar el programa el valor almacenado en errno es cero. Las funciones de librería almacenan solo valores mayores que cero en errno. se incluye para determinar varias propiedades de las representaciones de tipo real. para determinar varias propiedades de las representaciones de tipos enteros para especificar cómo maneja señales el programa cuando se ejecuta. Una señal puede informar de algún comportamiento especial dentro del programa, tal como una división por cero, o puede informar de algún acontecimiento asíncrono fuera del programa tal como una pulsación de una tecla de atención interactiva del teclado. Para definir tipos y macros que son de uso general en los programas.
Un uso común de las cadenas es para implementar una interfaz basada en órdenes. A diferencia de un menú que permite que el usuario haga una elección, una interfaz basada en érdenes muestra un mensaje indicativo, espera que el usuario introduzca una órden y despues hace lo que le pida la orden. Muchos sistemas operativos utilizan interfaces de linea de orden. En el siguiente ejemplo vamos a utilizar la funcion de biblioteca estandar atoi(); que devuelve un entero equivalente al numero representado en su argumento de cadena. La función atio() utiliza el archivo de cabecera . Este programa permite que el usuario sume, reste, multiplique o divida pero sn utilizar menú. En lugar de eso, utiliza una interfaz de linea de orden. 49
#include #include #include main() { char com[80], temp[80]; int i, j; for( ; ; ){ printf(\n¿Operación?); gets(com); if(!strcmp(com, salir)){ break; } printf(\nIntroduce el primer numero: ); gets(temp); i=atoi(temp); printf(\nIntroduce el segundo numero: ); gets(temp); j=atoi(temp); if(!strcmp(com, sumar)){ printf(%d, i+j); } else{ if(!strcmp(com, restar)){ printf(%d, i−j); }
50
else{ if(!strcmp(com, dividir){ if(j<0){ printf(%d, i/j); } else{ if(!strcmp(com, multiplicar){ printf(%d, i*j); } else{ printf(Orden desconocida); } } } } } } La razón por la que no se utiliza scanf para leer numeros es que es incompatible con gets. Podemos crear una cadena de longitud cero utilizando una sentencia strcpy(str, );. Esta clase de cadena se llama cadena nula, contiene solo un elemento, el carácter de terminación nulo. 5 1
51