DAI 1 B, Crèdit 5: Programació estructurada i modular Curs 2002-2003 Tema 3: Tractament de dades simples 1. Estructura general d'un programa en C 1.1. Directives del preprocessador 1.2. Declaracions globals 1.3. Funció main() 1.4. Funcions definides per l'usuari 1.5. Comentaris 2. Elements bàsics del llenguatge 2.1. Identificadors 2.2. Paraules reservades 2.3. Tipus de dades 2.4. Constants 2.4.1. Constants enteres 2.4.2. Constants reals 2.4.3. Constants caràcter 2.4.4. Constants cadena 2.5. Variables 2.5.1. Inicialització de les variables 2.5.2. Àmbit d'una variable 3. Entrades i sortides 3.1. Sortida 3.2. Entrada 3.3. Entrada / sortida en C++ 4. Operadors i expressions 4.1. 4.2. 4.3. 4.4. 4.5. 4.6. 4.7. Operador d'assignació Operadors aritmètics Operadors d'incrementació i decrementació Operadors relacionals Operadors lògics Conversions de tipus implícites Prioritat i associativitat Apèndix: Biblioteca de problemes 1 DAI 1 B, Crèdit 5: Programació estructurada i modular Curs 2002-2003 Tema 3: Tractament de dades simples 1. Estructura general d'un programa en C Un programa en C es composa d'una o més funcions. Una de les funcions ha de ser obligatòriament main(). Una funció en C és un grup d'instruccions que realitzen una o més accions. L'estructura general d'un programa en C inclou: • • • • • Directives de preprocessador: #include, #define Declaracions globals de variables i funcions La funció main() Funcions definides per l'usuari Comentaris del programa: durant tot el programa /* Programa exemple 1: Benvinguda al C */ #include <stdio.h> /* Aquest programa imprimeix: Benvingut a la programació en C */ void main() { /* inici del cos de la funció */ printf("Benvingut a la programació en C\n"); } /* fi de la funció */ /* Programa exemple 2 */ void main() { int num; /* sentència de declaració */ num=1; /* sentència d'assignació */ printf("num val %d.\n", num); /* sentència d'escriptura */ } 1.1. Directives del preprocessador El preprocessador en un programa C es pot considerar com un editor de text intel·ligent que consta de directives (instruccions al compilador abans de què es compili el programa principal). Les dues directives més usades són #include i #define. Totes les directives del preprocessador comencen amb el símbol coixinet (#), que indica al compilador que llegeixi les directives abans de compilar la resta del programa. L'ús més freqüent de les directives és la inclusió d'arxius de capçalera (arxiu amb extensió .h que conté codi font C). Existeixen arxius de capçalera estàndard que s'utilitzen àmpliament, com ara stdio.h, stdlib.h, math.h, string.h i s'utilitzaran altres arxius de capçalera definits per l'usuari per al disseny estructurat. La directiva #include indica al compilador que llegeixi l'arxiu de capçalera que ve a continuació i insereixi el seu contingut en la posició on es troba la directiva. La directiva #include pot adoptar un del següents formats: #include <nomarx.h> o bé #include "nomarx.h" 2 DAI 1 B, Crèdit 5: Programació estructurada i modular Curs 2002-2003 El primer format significa que els arxius es troben en el directori per defecte include. El segon format significa que l'arxiu està al directori actual (al mateix lloc que l'arxiu font). Si l'arxiu està en un altre directori s'ha d'especificar la ruta completa. L'arxiu de capçalera més freqüent és stdio.h. Aquest arxiu proporciona al compilador C la informació necessària sobre les funcions de biblioteca que realitzen operacions d'entrada i sortida. Com quasi tots els programes que escriviu imprimiran informació en pantalla i llegiran dades de teclat, necessitaran incloure scanf() i printf(). La directiva #define indica al preprocessador que substitueixi en el programa l'identificador que el segueix per allò que ve a continuació. Se sol utilitzar per a declarar constants. #define NUM 20 1.2. Declaracions globals La zona de declaracions globals està situada abans de la funció main(), i inclou les declaracions de variables comuns a totes les funcions del programa així com les declaracions de funcions o prototips de les funcions definides pel programador. int nota; int mitjana(int a, int b); 1.3. Funció main() Cada programa C té una funció main() que és el punt d'entrada al programa. La seva estructura és: void main() { ... /* bloc de sentències */ } A més de la funció main(), un programa C consta d'una col·lecció de funcions. Una funció és un subprograma que torna un únic valor, un conjunt de valors o realitza alguna tasca específica. En un programa curt, el programa complet pot incloure's totalment en la funció main(). Un programa llarg, així però, té massa codi per incloure'l en aquesta funció. La funció main() en un programa llarg consta pràcticament de cridades a les funcions definides per l'usuari. void main() { obtenirdades(); ordenar(); veure(); } Les variables i constants globals es declaren i defineixen fora de la definició de les funcions, abans del main(), mentre que les variables i constants locals es declaren en la capçalera del cos de les funcions. Les sentències situades en l'interior de les funcions han d'acabar en punt i coma. 1.4. Funcions definides per l'usuari Un programa C és una col·lecció de funcions. Tots els programes es construeixen a partir d'una o més funcions que s'integren per crear una aplicació. 3 DAI 1 B, Crèdit 5: Programació estructurada i modular Curs 2002-2003 Les funcions definides per l'usuari s'invoquen pel seu nom i els paràmetres opcionals que puguin tenir. Després de què cada funció és cridada, el codi associat amb la funció s'executa i, a continuació, es retorna a la funció que ha cridat. Totes les funcions tenen nom i una llista de valors que reben. Es pot assignar qualsevol nom a una funció, però generalment es procura que aquest nom descrigui el propòsit de la funció. En C, les funcions requereixen una declaració o prototip en el programa: void tracarcorba(); Una declaració de funció indica al compilador el nom de la funció pel que aquesta serà invocada en el programa. La paraula reservada void significa que la funció no torna cap valor. void esvocal(char caracter); La definició d'una funció és l'estructura de la mateixa: tipus_retorn nom_funció(llista_de_paràmetres) { sentències } tipus_retorn nom_funció llista_de_paràmetres És el tipus de valor, o void, tornat per la funció Nom de la funció Llista de paràmetres, o void, passats a la funció. Es coneixen també com arguments de la funció. C proporciona també funcions predefinides que s'anomenen funcions de biblioteca (o llibreries). Les funcions de biblioteca són funcions llestes per executar que venen amb el llenguatge C. Requereixen la inclusió de l'arxiu de capçalera estàndard, com ara stdio.h, math.h, etc. 1.5. Comentaris Un comentari és qualsevol informació que s'afegeix a l'arxiu font per proporcionar documentació de qualsevol tipus. El compilador ignora els comentaris, no realitza cap tasca concreta. L'ús de comentaris és molt recomanable. Els comentaris en C comencen amb la seqüència /* i acaben amb la seqüència */. Tot el text situat entre les dues seqüències és un comentari ignorat pel compilador. /* Programa: Programador: Descripció: Data creació: prova1.c Jordi Pujol Primer programa en C Octubre 2001 */ scanf("%d",&x); /*sentència d'entrada d'un valor enter */ 4 DAI 1 B, Crèdit 5: Programació estructurada i modular Curs 2002-2003 2. Elements bàsics del llenguatge 2.1. Identificadors Un identificador és una combinació de lletres (a-z, A-Z), números (0-9) i subratllats (_), tenint com a primer caràcter una lletra o un subratllat. Atenent a aquestes normes, els següents identificadors són correctes: comptador X25 _sortida_75 M_32_A I els següents identificadors seran incorrectes: 6comptador X-25 valor total que? Comença amb un número El guió no és vàlid Són dos identificadors, els espais els separen Les interrogacions no són vàlides La longitud d'un identificador pot ser qualsevol, si bé només es reconeixen els primers 31 caràcters. Per tant els següents identificadors són el mateix: Aquest_identificador_es_de_longitud_38 Aquest_identificador_es_de_longitud_major_de_31 C distingeix les majúscules de les minúscules. Per tant, els següents 4 identificadors no són el mateix: total, TOTAL, Total, ToTal. A l'hora de definir un identificador no s'han d'escatimar caràcters, sempre és millor definir una variable que va a contenir el radi d'una circumferència com radi que no com r. Pot costar més escriure la paraula radi, però també té un nom autoexplicatiu, que permet entendre el programa amb major facilitat. 2.2. Paraules reservades Una paraula reservada o paraula clau (keyword o reserved word) té un significat definit pel llenguatge i només poden ser utilitzades per al propòsit establert pel llenguatge. Per tant, no poden ser utilitzades com a identificador. En C existeixen les següents paraules clau: auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while 5 DAI 1 B, Crèdit 5: Programació estructurada i modular Curs 2002-2003 2.3. Tipus de dades Els tipus de dades bàsics de C són: Tipus char Significat caràcter Exemple 'C' Bytes 1 int enter -1024 2 long enter llarg 262144 4 float real 10.5 4 double real de doble precisió 0.00045 8 void sense valor Rang 0..255 -32768..32767 -2147483648..2147483637 3.4*10-38..3.4*1038 1.7*10-308..1.7*10308 NOTA: la grandària en bytes depèn del compilador i de la màquina. Per saber-ho exactament es pot utilitzar la funció sizeof() 2.4. Constants En C existeixen quatre tipus bàsics de constants: enteres, reals, caràcter i cadena de caràcters. Quan s'utilitza una constant en diversos llocs del programa se sol declarar mitjançant la directiva #define utilitzant un identificador. 2.4.1. Constants enteres Són constants que representen nombres sense decimals. Es pot posar un signe – davant del nombre, el qual indicarà que el nombre és negatiu. Segons la base en què s'escrigui la constant tenim tres tipus: decimals (dígits del 0 al 9), octals (dígits del 0 al 7 i sempre començant per 0) i hexadecimals (dígits del 0 al 9 i lletres A, B, C, D, E, F, començant sempre per 0x o 0X). • Decimal: 19, -213, 3 • Octal: 023, -0325, -03 • Hexadecimal: 0x13, 0Xd5, 0x3 2.4.2. Constants reals Una constant real comprèn una part entera, un punt (forma anglosaxona de representar els decimals), una part fraccionària, una "e" o una "E" seguida d'un exponent amb signe (potència de 10). 4.7, -5.65, 5.0, 4E3, -7e-2, 4.8E4, -7.2e-2 És important fer notar que 5 és una constant entera, mentre 5.0 és una constant real. Quan apareix la lletra "E" s'anomena notació científica, on la lletra "E" substitueix al nombre 10. Així, el nombre 4.8 * 104 és el 4.8E4. Les següents constants representen el mateix valor: 0.00075E1, 0.0075, 0.075E-1, 0.75E-2, 75E-4 2.4.3. Constants caràcter Una constant caràcter està constituïda per un únic caràcter entre cometes simples ('). 'A', 'c', '?', ' ' Es pot utilitzar el conjunt de caràcters ASCII. Cada caràcter té associat un valor numèric, el qual també val per referenciar al caràcter. Per tant, si en C comparem la constant caràcter 'A' amb el 6 DAI 1 B, Crèdit 5: Programació estructurada i modular Curs 2002-2003 seu codi ASCII, que és el 65, l'ordinador ens dirà que són iguals. Això és perquè en realitat el que s'emmagatzema en memòria no és el caràcter en sí, sinó el seu codi corresponent. Hi ha caràcters que no es representar utilitzant el teclat, com ara el caràcter sigma (Σ). Com el seu codi ASCII és el 228, podem assignar a una variable caràcter directament el nombre 228 perquè contingui aquest caràcter. Existeixen alguns caràcters no imprimibles o que tenen un significat especial per al C i que poden ser expressats com seqüències d'escapament. Una seqüència d'escapament és una parella de caràcters que en realitat representen un sol caràcter. D'aquests dos caràcters, el primer sempre és la barra invertida \. En la següent taula tenim les seqüències d'escapament més usades: Seqüència d'escapament \n \r \t \b \f \\ \" \0 Significat nova línia retorn de carro tabulació horitzontal espai enrere salt de pàgina barra invertida cometa doble caràcter nul Mnemotècnic NL HT BS CR FF \ " NULL Codi ASCII 13 + 10 13 9 8 12 92 34 \0 Podem veure que la seqüència d'escapament '\n' representa el caràcter de nova línia. Aquest caràcter no té un símbol que el representi en pantalla, sinó que quan és visualitzat en la pantalla el que es produeix és un salt de línia. Com el caràcter barra invertida marca l'inici d'una seqüència d'escapament, per poder-lo expressar, el que s'ha de fer és escriure dues barres invertides seguides '\\'. 2.4.4. Constants cadena Una constant de tipus cadena de caràcters està constituïda per una seqüència de caràcters delimitada per cometes dobles ("). "Cadena de caràcters" "123" "23 d'abril de 1707" "El caràcter barra invertida: \\" "Per a posar \" mireu com es fa" Es pot escriure una cadena en vàries línies, acabant cada línia amb "\" "Açò és una cadena\ que té dues línies" Tota cadena de caràcters acaba amb el caràcter NULL (ASCII 0) que col·loca automàticament el compilador. Els programadors principiants en C a sovint confonen les cadenes d'un sol caràcter amb les constants caràcter. Així, no és el mateix el caràcter 'A' que la cadena de caràcters "A", i per tant no poden intercanviar-se en el seu ús. Mentre la primera té un valor numèric corresponent, la cadena no el té i inclou un nul al final. 7 DAI 1 B, Crèdit 5: Programació estructurada i modular Curs 2002-2003 2.5. Variables Una variable és un identificador que fa referència a una posició de memòria on és possible emmagatzemar valors d'un cert tipus de dades. Aquest valor pot ser modificat al llarg del programa, per això el nom de variable. Totes les variables han de ser declarades abans de seu usades. És a dir, abans d'usar una variable s'ha de dir a quin tipus pertany. Això es fa especificant un tipus, seguit d'una llista de variables. tipus nom_variable; int x, y, z; char a, b; 2.5.1. Inicialització de les variables S'anomena inicialitzar una variable al fet d'assignar-li un valor al mateix temps que se la declara. Per tant, es tracta de donar-li un valor inicial a la variable. La forma de fer-ho és posar un signe igual i el valor desitjat darrere de la declaració de la variable. tipus nom_variable = valor; char resposta = 'S'; int x, y = 10; 2.5.2. Àmbit d'una variable Depenent del lloc on es declaren les variables, aquestes es poden utilitzar en la totalitat del programa o només dintre d'una funció. La zona d'un programa en què una variable està activa s'anomena àmbit de la variable. Les variables poden ser declarades en tres llocs distints: • • • Dintre d'una funció. Se les anomena variables locals, i només podran ser usades dintre de la funció. Capçalera d'una funció. Aleshores se les anomena paràmetres de la funció, i contenen valors que són passats en la cridada de la funció. Fora de totes les funcions. Aleshores se les anomena variables globals, i poden ser usades en totes les funcions que segueixen a la seva declaració. Les variables globals s'han d'evitar, ja que ocupen memòria durant tota l'execució del programa i, a més, poden ser modificades per error en qualsevol lloc del programa, cosa que dificulta la seva depuració. Tant els paràmetres com les variables locals només existeixen mentre s'està executant la funció, per tant després deixen d'ocupar memòria. En conseqüència, podem utilitzar els mateixos identificadors de variables en diferents funcions. 3. Entrades i sortides Els programes interactuen amb l'exterior a través de dades d'entrada o dades de sortida. El llenguatge C no proporciona directament ordres d'entrada o sortida. Així però, en la biblioteca de funcions C trobem aquestes facilitats. 8 DAI 1 B, Crèdit 5: Programació estructurada i modular Curs 2002-2003 3.1. Sortida La funció més significativa per a la sortida de dades és la funció printf(), definida en la biblioteca stdio.h. printf(cadena de control, llista de variables); La cadena de control pot contenir bé caràcters normals o bé codis de format que comencen pel signe %. Codi de format %d %ld %e %f %g %s %c %número .número Significat enter enter llarg real amb notació exponencial (científica) real amb notació decimal real; representació més curta, %e o %f cadena de caràcters caràcter ajustar a l'esquerra amplitud del camp amplitud del camp després del punt decimal La llista de variables són les variables, separades per comes, els valors de les quals es van a mostrar per la sortida. Hauran d'haver tantes variables en la llista com caràcters % hi hagi en la cadena de control. Convé recordar l'existència de les seqüències d'escapament, ja que se solen utilitzar bastant en el printf(). Exemple: #include <stdio.h> void main() { int i = 1001; float x = 543.456; char a = 'A'; char c[11] = "1234567890"; printf printf printf printf printf printf printf printf ("i ("i ("i ("i ("i ("i ("i ("i = = = = = = = = %d, x = %f, a = %c, c = %s|", i, x, a, c); %3d, x = %3f, a = %3c, c = %3s|", i, x, a, c); %15d, x = %15f, a = %15c, c = %15s|", i, x, a, c); %.2d, x = %.2f, a = %.2c, c = %.2s|", i, x, a, c); %.12d, x = %.12f, a = %.12c, c = %.12s|", i, x, a, c); %-5d, x = %-5f, a = %-5c, c = %-5s|", i, x, a, c); %-12d, x = %-12f, a = %-12c, c = %-12s|", i, x, a, c); %12.2d, x = %12.2f, a = %12.2c, c = %12.2s|", i, x, a, c); } 9 DAI 1 B, Crèdit 5: Programació estructurada i modular Curs 2002-2003 3.2. Entrada La més important de les funcions d'entrada de dades des de teclat és scanf(), també de la biblioteca stdio.h. Podríem considerar que aquesta funció és la inversa de printf(). scanf(cadena de control, llista de variables); La cadena de control és idèntica al cas de printf(). Els paràmetres de la funció scanf() s'han de passar per referència, és a dir, s'ha de passar la seva adreça de memòria perquè puguin ser modificats. Per a això es necessita l'operador d'adreça, el prefix &. printf("Introdueixi v1 i v2: "); scanf("%d %f", &v1, &v2); /* lectura valors v1 i v2 */ printf(Preu de venda al públic"); scanf("%f", &preu_venda); printf("Base i altura: "); scanf("%f %f", &b, &h); A causa del funcionament un poc estrany de la funció scanf() sota Windows, després de la seva utilització deixa un caràcter Enter en la memòria que llegeix la següent instrucció de lectura, cosa que provoca problemes. Per tant, cada vegada que s'utilitzi la funció scanf() convé executar la instrucció fflush(stdin), que allibera la memòria. 3.3. Entrada / sortida en C++ El llenguatge C proporciona funcions per a l'entrada i sortida en la biblioteca stdio.h. Aquestes funcions són un poc incòmodes. El llenguatge C++ proporciona unes funcions equivalents en la biblioteca iostream.h. Aquestes funcions són cin i cout, i utilitzen respectivament els operadors >> i <<. Vegem alguns exemples: cout cin cout cout cin << >> << << >> "Quina és la teva edat? "; edat; "L'edat és " << edat << " anys"; "Introdueix nom, edat i sexe: "; nom >> edat >> sexe; 4. Operadors i expressions En els programes C també ens trobem amb expressions. Una expressió és una seqüència d'operacions i operants que especifiquen un càlcul. Ens trobarem amb operadors binaris, com ara el - quan actua com a resta, i operadors unaris, com ara el – com a indicador de signe. Els operadors tindran una precedència i una associativitat entre ells, que es pot alterar mitjançant l'ús dels operadors parèntesis ( i ). En cas de dubte o simplement per facilitar la llegibilitat, convé utilitzar parèntesis. 4.1. Operador d'assignació L'operador d'assignació (=) assigna el valor de l'expressió dreta a la variable situada a la seva esquerra. 10 DAI 1 B, Crèdit 5: Programació estructurada i modular Curs 2002-2003 codi = 3467; coordX = 525; pi = 3.1416; Aquest operador és associatiu per la dreta; això permet realitzar assignacions múltiples. Així, a = b = c = 45; equival a a = (b = (c = 45)); o dit d'una altra manera, a les variables a, b i c s'assigna el valor 45. Aquesta propietat permet inicialitzar vàries variables amb una sola sentència. int a, b, c; a = b = c = 5; /* s'assigna 5 a les variables a, b i c */ 4.2. Operadors aritmètics Els operadors aritmètics serveixen per realitzar operacions aritmètiques bàsiques. Els operadors aritmètics C segueixen les regles algebraiques típiques de jerarquia o prioritat. Aquestes regles especifiquen la precedència de les operacions aritmètiques. Per aquestes regles, l'expressió 3 + 5 * 2 equival a l'expressió 3 + (5 *2). Operador + * / % Significat Suma i signe positiu Resta i signe negatiu Producte Divisió entera o divisió real, depenent dels operants Residu de la divisió entera Precedència (major a menor) +, - (unaris) *, /, % +, - Exemple x + y b – c x * y b / 5 b % 5 Associativitat esquerra – dreta esquerra – dreta esquerra – dreta Exemple: Obtén el resultat de les següents expressions: 6 + 2 * 3 – 4 / 2 5 * (5 + (6 – 2) + 1 7 – 6 / 3 + 2 * 3 / 2 – 4 / 2 7 * 10 – 5 % 3 * 4 + 9 (7 * (10 – 5) % 3) * 4 + 9 4.3. Operadors d'incrementació i decrementació Unes de les característiques més particulars i útils de C són els operadors d'increment ++ i decrement --. Aquests operadors sumen o resten 1 respectivament a la variable a què s'apliquen. 11 DAI 1 B, Crèdit 5: Programació estructurada i modular Curs 2002-2003 Aleshores, a++; és igual que a = a + 1; Aquests operadors tenen la propietat de què poden utilitzar-se en posició prefixa o en posició postfixa. El resultat de l'expressió pot ser distint, depenent del context. Si els operadors ++ i -- estan en posició prefixa, l'operació d'increment o decrement s'efectua abans que l'operació d'assignació; si els operadors ++ i -- estan en posició postfixa, l'assignació s'efectua en primer lloc i la incrementació o decrementació a continuació. Les sentències ++n; n++; tenen el mateix efecte; així com --n; n--; Així però, quan s'utilitzen en expressions com ara n = 5; m = ++n; /* incrementa n en 1, 6, i l'assigna a m */ n = 10; printf("n= %d", n--); /* decrementa n en 1, 9, i el passa a printf() */ el resultat és distint que si s'utilitzen en posició prefixa. n = 5; m = n++; /* assigna n (5) a m, després incrementa n en 1 (6) */ n = 10; printf("n= %d", n--); /* passa n (10) a printf(), després decrementa n (9) */ Per a evitar problemes, convé utilitzar els operadors d'incrementació i decrementació sols, sense mesclar-los en altres expressions. 4.4. Operadors relacionals Els operadors relacionals permeten realitzar comparacions entre valors. El seu resultat és cert o fals. C no té tipus de dades lògics per representar els valors cert i fals. En el seu lloc s'utilitza el tipus int, amb el valor enter 0 que representa a fals i distint de zero a cert. fals cert zero distint de zero Els operadors relacionals s'utilitzen en expressions de la forma expressió operador_relacional expressió 12 DAI 1 B, Crèdit 5: Programació estructurada i modular Curs 2002-2003 Els operadors relacionals s'usen normalment en sentències de selecció o d'iteració per a comprovar el valor d'una condició. Operador == != > < >= <= Significat Igual a No igual a Major que Menor que Major o igual que Menor o igual que Exemple a==b a!=b a>b a<b a>=b a<=b Un error típic, fins i tot entre programadors experimentats, és confondre l'operador d'assignació (=) amb l'operador d'igualtat (==). Quan s'utilitzen els operadors en una expressió, l'operador relacional produeix un 0, o un 1, depenent del resultat de la condició, falsa o certa. Per exemple, si s'escriu c = 3 < 7; la variable c es posa a 1, donat que com 3 és menor que 7, aleshores l'operació < torna un valor d'1, que s'assigna a c. Exemple: Si x, a, b i c són de tipus float, nombre de tipus int, i inicial de tipus char, les següents expressions són vàlides: x < 5.75 b * b >= 5.0 *a * c nombre == 100 inicial != 'M' Els caràcters també es comparen utilitzant els codis numèrics del codi ASCII. 'A' < 'C' és 1, cert, ja que A és el codi 65 i és menor que el codi 67 de C. 'a' < 'c' és 1, cert: a codi 97, b codi 99. 'b' < 'B' és 0, fals: b codi 98, B codi 66. Els operadors relacionals tenen menor prioritat que els operadors aritmètics, i associativitat d'esquerra a dreta. m + 5 <= 2 * n equival a (m + 5) <= (2 * n). 4.5. Operadors lògics A més dels operadors matemàtics, C té també operadors lògics. Aquests operadors s'utilitzen amb expressions per tornar un valor cert (qualsevol enter distint de zero) o un valor fals (0). Els operadors lògics s'anomenen també operadors booleans, en honor de George Boole, creador de l'àlgebra de Boole. Operador ! && || Significat Negació I lògic O lògic 13 DAI 1 B, Crèdit 5: Programació estructurada i modular Curs 2002-2003 Les taules de veritat d'aquests operadors són les següents: a 0 0 1 1 b 0 1 0 1 a && b 0 0 0 1 a || b 0 1 1 1 a 0 1 !a 1 0 La prioritat i associativitat d'aquests operadors és la següent: Prioritat ! && || Associativitat esquerra – dreta esquerra – dreta esquerra – dreta 4.6. Conversions de tipus implícites Els tipus de dades bàsics poden ser mesclats lliurement en assignacions i expressions. Aleshores es produeixen conversions de tipus automàtiques: els operants de tipus més baix es converteixen en els de tipus més alt. int i = 12; double x = 4; x = x + i; /* el valor de i es converteix a double abans de la suma */ x = i/5; /* primer fa una divisió entera i/5==2, 2 es converteix a tipus double: 2.0 i s'assigna a x */ x = 4.0; x = x/5; /* converteix 5 a tipus double, fa una divisió real: 0.8 i s'assigna a x */ i = x; /* converteix 0.8 a tipus enter, 0, i s'assigna a i */ 4.7. Prioritat i associativitat La prioritat o precedència d'operadors determina l'ordre en què s'apliquen els operadors a un valor. Prioritat 1 2 3 4 5 6 7 8 9 Operadors ( ) ++ -- ! - + * / % + < <= > >= == != && || = Associativitat E-D D-E E-D E-D E-D E-D E-D E-D D-E Si dos operadors s'apliquen al mateix operant, l'operador amb major prioritat s'aplica primer. 14 DAI 1 B, Crèdit 5: Programació estructurada i modular Curs 2002-2003 Tots el operadors del mateix grup tenen igual prioritat i associativitat. L'associativitat esquerra-dreta significa aplicar l'operador més a l'esquerra primer, i en l'associativitat dreta-esquerra s'aplica primer l'operador més a la dreta. Els parèntesis tenen la màxima prioritat. 15 DAI 1 B, Crèdit 5: Programació estructurada i modular Curs 2002-2003 Apèndix: Biblioteca de problemes Estructura general d'un programa 1. Escriviu i executeu un programa que imprimeixi el vostre nom i adreça. 2. Depureu el programa següent: include <stdio.h> void main() { printf("El llenguatge de programació C") Elements bàsics del llenguatge 3. Quins dels següents identificadors són vàlids? a) b) c) d) e) f) n ProblemaMeu JocMeu Joc Meu write m&m g) h) i) j) k) l) _m_m registre A B 85 Nombre AAAAAAAAAA Nom_Cognoms m) n) o) p) q) r) Saldo_Actual 92 Universitat Autònoma Set 15 * 143Edat 4. Indiqueu les definicions de variables errònies i especifiqueu l'error. a) b) c) d) e) f) g) char char = 'A'; char A = 65; char par = "B"; char pin = '7'; int ancho = 2.5; float mol = 1.5E-7; int long = 745; 5. Quin tipus de dades bàsic s'ha d'utilitzar per a definir variables que continguin els següents valors: a) b) c) d) e) El nombre d'habitants de Reus La nota mitjana dels alumnes d'una classe La lletra més freqüent a l'obra Tirant lo Blanc La distància en metres de València a Barcelona L'edat en anys d'una persona 6. Identifiqueu el tipus i el significat de les següents constants: a) b) c) d) '\n' 27 99.44 -2.5E30 7. Indiqueu quines de les següents dades numèriques són constants vàlides en C, especificant el tipus de dades al que pertanyen. Així mateix, especifiqueu també la base en què està escrita cada constant entera vàlida. a.- 0.34 e.- 27,822 i.- 0515 b.- 34.2e-12 f.- 87654321 j.- 0x25353 c.- 10101010 g.- O.SE 8 k.- 0XBATA d.- 0.8E+0.8 h.- -12.8e22 l.- 0x2dab3 16 DAI 1 B, Crèdit 5: Programació estructurada i modular Curs 2002-2003 Entrades i sortides 8. Un programa en C conté les següents declaracions de variables: char a='A', b='9' , c='$'; Mostreu la sortida resultant de cadascuna de les següents sentències, incloent espais i salts de línia. printf("%c %c%% %c\n", a, b, c); printf("%c%c\t\"%c\"\n", a, b, c); printf ("%4c %5c %6c\n", a, b, c) ; printf ("=%c; b=%-12c, c=%10c\n",a,b,c) ; 9. Un programa en C conté les següents declaracions: float x= -2.5, y= 0.00003, z= 2500.5; Mostreu la sortida resultant de cadascuna de les següents sentències printf("%f %f %f\n", x,y,z); printf("%14f %14f %14f\n",x,y,z); printf ("%15.4f %15.4f %15.4f\n", x,y,z); printf ("%e %e %e\n",x,y,z); printf("%15e %12e %20e\n",x,y,z); printf("%g %g %g\n",x, y, z); printf ("%10.3e %10.3e %10.3e\n",x,y,z); printf("%+16f %-16f %016f\n", x, y,z); Operadors i expressions 10. Determineu el valor de les següents expressions aritmètiques: a) b) c) d) 15 / 12 24 / 12 123 / 100 200 / 100 e) f) g) h) 15 % 12 24 % 12 123 % 100 200 % 100 11. Quin és el valor de cadascuna de les següents expressions? a) b) c) d) e) f) g) h) 15 * 14 – 3 * 7 –4 * 5 * 2 (24 + 2 * 6) / 4 3 / 3 / 3 * 4 3 + 4 * (8 * (4 – (9 + 3) / 6)) 4 * 3 * 5 + 8 * 4 * 2 – 5 4 - 40 / 5 (-5) % (-2) 12. Escriviu les següents expressions com expressions de computadora. La potència pot fer-se amb la funció pow(), per exemple (x+y)2==pow(x+y,2). a) x +1 y d) b c+d b) x+ y x− y e) ( a + b) f) ((a + b) 2 ) 2 c) y x+ z y x+ z g) xy 1 − 4x c d 17 DAI 1 B, Crèdit 5: Programació estructurada i modular h) xy mn Curs 2002-2003 i) ( x + y ) 2 ⋅ ( a − b) 13. Escriviu el resultat de les següents expressions: a) b) c) d) e) f) 24 % 5 7 / 2 + 2.5 10.8 / 2 + 2 16 / 3 * 2 - 4 * 5 / 2 (4 + 6 ) * 3 + 2 * ( 5.5 - 1 ) 22 / 3 + 5.5 * 2 - ( 7 % 2 + ( 6 * 2 ) ) + 7.5 / 2 14. Escriviu el resultat de les següents expressions: a) b) c) d) e) f) 7 >= 5 && 27 == 8 45 <= 7 || ! ( 5 >= 7 ) 8 > 8 || 7 == 7 && ! ( 5 < 5 ) 4 + 2 < 8 && 24 + 1 == 25 || 0 ( 2 * 7 > 5 || 7 / 2 == 3 ) && ( 7 > 25 || ! 1 ) && 27 (8 == 3 + 2) && !(24 > 5) && (7 != 4) || (28 * 5) 15. Escriviu una expressió que indiqui la condició de què un nombre enter n sigui múltiple de 10 però distint de 500 i que sigui major o igual que 150. 16. Donades les variables enteres a, b, c, d, expresseu amb llenguatge C: • Els valors de a i b son ambdós menors que 17. • Els valors de a, b i c són idèntics i distints de d. • Els valors de b i d estan compresos estrictament entre els valors de a i c, sabent que a és inferior a c. • Entre els valors de a, b, i c hi ha almenys dos idèntics. • Entre els valors de a, b i c hi ha dos valors i només dos idèntics. • Entre els valors de a, b, i c hi ha com a màxim dos valors idèntics. • a és inferior al producte de b per c i agafa un valor pertanyent al conjunt següent: {3, 4, 5, 6, 7, 8, 9, 10, 11, 22, 23, 24, 25, 26, 27, 28, 29, 34} • a és un nombre par i està comprés entre dues vegades b i quatre vegades la diferència c menys d. • el quocient enter de c entre a és un nombre divisible per tres vegades d. 17. Donades les variables enteres europeu, casat, muller i edat i la variable de tipus float saldo expresseu amb llenguatge C: • europeu és igual a 1 i casat és igual a zero. • europeu és distint de zero, casat és igual a 1 i edat està compresa entre 20 i 30. • saldo és superior a 100.000 o europeu és igual a zero i edat divisible por quatre. • europeu i casat són iguals a 1 i edat és menor que 30 o europeu és igual a zero i saldo no és inferior a 250.000. • muller és igual a 1, europeu és igual a zero i saldo està comprés entre 50.000 i 250.000 o muller és igual a zero, europeu és igual a 1 i edat és superior a 25 i saldo és no negatiu. 18. Escriviu una sentència lògica que digui si un enter x és negatiu o positiu major que 100. 18 DAI 1 B, Crèdit 5: Programació estructurada i modular Curs 2002-2003 Programes 19. Escriviu un programa que llegeixi un enter, el multipliqui per 2 i a continuació escrigui el resultat per pantalla. 20. Escriviu un programa que llegeixi dos enters dintre de dues variables, intercanviï els valors de les dues variables mitjançant sentències d'assignació, i a continuació mostri el resultat. 21. Escriviu un programa que llegeixi dos enters en les variables x i y, i a continuació obtingui els valors de x / y i de x % y. Executeu el programa vàries vegades amb diferents parells d'enters com a entrada. 22. Escriviu un programa que sol·liciti a l'usuari la longitud i amplària d'una habitació i a continuació visualitzi la seva superfície amb quatre decimals. 23. Escriviu un programa que converteixi un nombre donat de segons en l'equivalent de minuts i segons. 24. Quins són els resultats visualitzats pel següent programa, si les dades proporcionades són 5 i 8? #include <stdio.h> #define M 6 void main() { int a, b, c; printf("Introdueix el valor d'a i de b"); scanf("%d %d", &a, &b); fflush(stdin); c= 2*a - b; c= c – M; b = a + c – M; a = b * M; printf("\n a = %d\n", a); b= -1; printf(" %6d %6d", b, c); } 25. Escriviu un programa per calcular la longitud de la circumferència i l'àrea del cercle per a un radi introduït per teclat. 26. Escriviu un programa que llegeixi dos enters i calculi i escrigui el seu producte, quocient i residu de dividir el primer pel segon. 27. Una temperatura Celsius (graus centígrads) pot ser convertida a una temperatura equivalent Farenheit d'acord a la següent fórmula: f=(9.0/5)*c*32. Escriviu un programa que llegeixi la temperatura en graus Celsius i l'escrigui en Farenheit. 28. Escriviu un programa que dibuixi el rectangle següent: ********* * * * * * * ********* 19 DAI 1 B, Crèdit 5: Programació estructurada i modular Curs 2002-2003 29. Modifiqueu el programa anterior, de manera que es llegeixi una lletra i la imprimeixi al centre del rectangle. 30. Calculeu l'àrea d'un triangle mitjançant la fórmula: Àrea= (p(p-a)(p-b)(p-c))1/2 on p és el semiperímetre, p= (a+b+c)/2, sent a, b, c els tres costats del triangle. 31. Construïu un programa que calculi i escrigui el producte, quocient enter i residu de dos nombres. 32. Escriviu un programa que desglossi certa quantitat de segons introduïda per teclat en el seu equivalent en setmanes, dies, hores, minuts i segons. 33. Escriviu un programa que expressi certa quantitat de pessetes en la mínima quantitat de bitllets i monedes de curs legal fins l'any 2001. Escriu un altre programa que expressi certa quantitat d'euros en la mínima quantitat de bitllets i monedes de curs legal en l'actualitat. 34. Escriviu un programa que digui si un any és bixest. Per a saber si un any és bixest s'utilitza la següent regla: Un any és bixest si és divisible per 400, o bé si és divisible per 4 però no per 100. 35. Feu un programa que calculi l'àrea del cercle una vegada introduït per teclat el valor del radi i sabent que el valor constant de PI es 3.1416, (podeu utilitzar la constant M_PI inclosa a la llibreria math.h). 36. Feu un programa que calculi l'àrea d'un polígon regular una vegada introduït per teclat el valor del perímetre (P) i l'apotegma (ap). Area = (P * ap) / 2 37. Feu un programa que calculi l'àrea d'un trapezi, introduint per teclat els valors de les bases i la seva altura. A = (B + b) * h / 2 38. Escriviu un programa que llegeixi el valor corresponent a una distància en milles marines i l'escrigui expressada en metres (1 milla, equival a 1852 metros). 39. Escriviu un programa que calculi la velocitat d'una pilota de tennis en Km/hora, coneixent la distància recorreguda en metres i el temps emprat en segons per a recórrer la distancia. 40. Dissenyeu un programa que calculi i escrigui el percentatge descomptat en una compra, introduint el preu real de l'article i el preu pagat. 41. Un corredor de marató (distància=42.195 km.) ha recorregut la carrera en 2 hores i 25 minuts. Es desitja un programa que calculi i escrigui el temps mitjà en minuts per kilómetro. 20