Post on 25-Feb-2021
Programacio en C
Albert Ruiz (a partir de notes de Yago Antolın i Lluıs Alseda)
Curs 2008–09
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Com es fa un programa? Algorismes Aritmetica binaria
Continguts primera part
1 Sessio 1Com es fa un programa?AlgorismesAritmetica binaria
2 Sessio 2Estructura d’un programaTipus de dades, operadors, precedencia.La Llibreria stdio.hFlux de dades I
3 Sessio 3Flux de dades IILa coercio de tipus de dadesEntrada/sortida - Formats d’impressio
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Com es fa un programa? Algorismes Aritmetica binaria
¿Que es un programa?
Un algorisme es una sequencia d’instruccions.
Un llenguatge de programacio es un llenguatge que es pot fer servir percontrolar un ordinador.
Un programa (en C) es un fitxer de text que conte un algorisme escritutilitzant el lleguatge de programacio C.
Compilant el programa obtenim un fitxer executable. L’executable conteinstruccions de processador, que s’executen quan el Sistema Operatiu leshi envia.
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Com es fa un programa? Algorismes Aritmetica binaria
El programa ’bondia.c’
Exemple
//programa bondia.c/* Aquesta lınea i l’anterior son comentaris*/
#include<stdio.h>
int main(){printf("Bon dia a tothom\n");return 0;
}
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Com es fa un programa? Algorismes Aritmetica binaria
Compilant bondia.c
bondia.c −→ gcc -Wall bondia.c -o bondia −→ Bondia
bondia.c: es el fitxer font. Es crea amb un editor. Per exemple elKate.
gcc -Wall bondia.c -o bondia: es la instruccio de compilacio
bondia: es el programa (executable). S’executa com qualsevol altracomanda: Passant el seu nom al Sistema Operatiu.
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Com es fa un programa? Algorismes Aritmetica binaria
Escrivint algorismes
Descrivim una sequencia finita d’instruccions.
Cal que hi consti l’inici i el final i a mes cal que estiguin definides lesvariables.
Cal que sigui concıs, detallat i precıs.
Usarem instruccions com ara Llegir del teclat, Escriure perpantalla, Si (Condicio)- Instruccions -FiSi, Repetir - Instruccions- Mentre (Condicio) ...
Nota
No hi ha una manera estandar per escriure algorismes.
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Com es fa un programa? Algorismes Aritmetica binaria
Un algorisme per calcular l’area d’un triangle
ALGORISME: Calcular l’area d’un triangle
INICIVARIABLES
Area Tipus realBase Tipus realAltura Tipus real
ALGORISMEEscriure "Introdueix la base del triangle"Llegir BaseEscriure "Introdueix l’alcada del triangle"Llegir AlturaArea = (Base * Altura)/2Escribir "L’area del triangle es", Area
FI
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Com es fa un programa? Algorismes Aritmetica binaria
El factorial de un nombre
n! = n(n − 1)(n − 2) . . . 3 · 2 · 1
Exemple
4! = 4 · 3 · 2 · 1 = 24.
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Com es fa un programa? Algorismes Aritmetica binaria
Un algorisme per calcular el factorial de un nombre
ALGORISME: Calcular el factorial de un numero
INICI
VARIABLES
numero Tipus enter
factorial Tipus enter
ALGORISME
Escriure "Introdueix un nombre enter"
Llegir numero
Si (numero >0)
factorial = 1
Repetir
factorial = factorial * numero
numero = numero -1
Mentre (numero > 0)
Escriure "El factorial es", factorial
FiSi
FI
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Com es fa un programa? Algorismes Aritmetica binaria
La memoria
La memoria de l’ordinador emmagatzema la informacio com a sequenciesde bits (zeros i uns).
La memoria s’organitza en bytes que son paraules de 8 bits. Quanl’ordinador realitza calculs:
Treballa amb nombres escrits amb un nombre fixat de bytes. Es adir, no es pot operar amb nombres arbitrariament grans.
Les operacions depenen de l’aritmetica binaria. Aixo teconsequencies, per exemple, als tipus d’arrodoniment.
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Com es fa un programa? Algorismes Aritmetica binaria
Passar de binari a decimal:
L’ordinador utilitza bits per representar signe (+ -) i punt “decimal”. Persimplificar, farem servir - per representar un numero negatiu i . pels“decimals”.
Exemple
Per exemple el numero 1101.1
Pos.: pos 3 pos 2 pos 1 pos 0 . pos -1Binari: 1 1 0 1 . 1Becimal: 1 · 23+ 1 · 22+ 0 · 21 + 1 · 20 + 1 · 2−1 = 13 + 2−1
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Com es fa un programa? Algorismes Aritmetica binaria
Aritmetica binaria
Les operacions seguexen les mateixes regles que en el cas decimal. Permultiplica nomes cal saber-se les taules del 0 i de l’1!!!!
Exemple
Suma, resta i producte binari.
Suma 2 + 3 Resta 5 - 3 Producto 5× 3
11 0
+ 1 11 0 1
1 0 1- 1 10 1 0
1 0 1× 1 11 0 1
1 0 11 1 1 1
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Com es fa un programa? Algorismes Aritmetica binaria
Exemple
Divisio
101110
11110
11010
0
|10101.1
10101110100
1110100
1110...
|1110.1010101. . .
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Estructura Dades, operadors, prec. La Llibreria stdio.h Flux de dades I
Sessio 2
1 Sessio 1Com es fa un programa?AlgorismesAritmetica binaria
2 Sessio 2Estructura d’un programaTipus de dades, operadors, precedencia.La Llibreria stdio.hFlux de dades I
3 Sessio 3Flux de dades IILa coercio de tipus de dadesEntrada/sortida - Formats d’impressio
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Estructura Dades, operadors, prec. La Llibreria stdio.h Flux de dades I
Un exemple que fa calculs: el programa area.c
El seguent programa calcula l’area d’un cercle de radi r . El radi es llegeixdel teclat.
Exemple
// Programa area.c
#include <stdio.h>
#define PI 3.141592653589793238462643383279502884197
int main ()
{
double r;
printf("Entra el radi del cercle: ");
scanf ("%lf", &r);
printf("\nL´area es: %14.6f\n\n", PI*r*r);
return 0;
}
Totes les instruccions de C s’han d’acabar en punt i coma ;
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Estructura Dades, operadors, prec. La Llibreria stdio.h Flux de dades I
Estructura d’un programa
/* Capcalera d´identificacio del programa i l´autor
Fitxer: nom.c
Contingut: Exemple d´estructura d´un programa en C
Autor: nom de l´autor
Revisio: preliminar; data de la darrera modificacio */
/* Comandes del preprocessador. Son de dos tipus */
/* Tipus 1: inclusions de fitxers de capcalera. Per exemple: */
#include <stdio.h>
/* Tipus 2: definicio de constants simboliques. Per exemple: */
#define PI 3.141592653589793238462643383279502884197
int main() /* Funcio principal. Hi poden haver parametres */
/* El programa es comenca a executar per aquı */
{
/* Declaracions. Per exemple: */
double r;
.
. /* cos de la funcio principal; instruccions del programa*/
.
} /* Fi del main */
/* FUNCIONS AUXILIARS */
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Estructura Dades, operadors, prec. La Llibreria stdio.h Flux de dades I
Tipus de dades
Especificacio bytes Rang Precisio
unsigned char 1 0 - 255(signed) char 1 -128 - 127
unsigned short (int) 2 0 - 65535(signed) short (int) 2 -32768 - 32767
unsigned (int) 4 0 - 4294967295(signed) int 4 -2147483648 - 2147483647
unsigned long (int) 4 0 - 4294967295(signed) long (int) 4 -2147483648 - 2147483647
float 4 3.4 x 10±38 7 dıgitsdouble 8 1.7 x 10±308 15 dıgits
long double 12 1.1 x 10±4932 18 dıgits
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Estructura Dades, operadors, prec. La Llibreria stdio.h Flux de dades I
Exemples de constants
Constants:
´A´ ´3´ ´\t´ char3 char short int long unsigned
-27 char short int long-100000 int long4294967200 unsigned int unsigned long3. 3.0 -3.0e-2 float double long double
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Estructura Dades, operadors, prec. La Llibreria stdio.h Flux de dades I
Declaracio de variables
Qualsevol declaracio de variable consistira en una especificacio de tipus:
char, int, float
precedida d’un modificador:
unsigned, signed, short, long
a menys que aquest ultim ja indiqui clarament el tipus de variable.
Exemple
unsigned short natural; /* La variable ´natural´ es declara */
/* com un enter positiu */
int i, j, k = 1; /* Les variables ´i´ ´j´ ´k´ */
/* seran enters (amb signe). */
Aquı s’han fet tres operacions diferents:
Declaracio de variables. Consisteix en la reserva de memoria queocupara la variable i l’etiquetatge del “calaix” de memoria queocupa.
Inicialitzacio de variables. La variable k pren el valor 1.
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Estructura Dades, operadors, prec. La Llibreria stdio.h Flux de dades I
El tipus char
El Sistema Operatiu utilitza una codificacio estandar d’alfabet llatı.Aquesta codificacio depen de la configuracio regional la qual esta basadaen la codificacio ASCII de 7 bits.
Comandes a executar:
$ man ascii, $ man iso_8859-15 o be $ man latin9
Les variables tipus char utilitzan 8 bits per emmagatzemar nombres. Enfuncio de la codificacio pel Sistema Operatiu, cada numero 0-255representa un caracter.
Exemple
char caracter=’a’; //La variable caracter val 97
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Estructura Dades, operadors, prec. La Llibreria stdio.h Flux de dades I
Els operadors
operadors aritmetics: % modul (nomes per enters)* / producte i divisio+ - suma i resta
operadors relacionals: < <= mes petit (o igual) que> >= mes gran (o igual) que== != igual i diferent
operadors logics: ! no(proposicio logica)&& i logic|| o logic
operador incrementals: ++ increment una unitat-- decreixment una unitat
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Estructura Dades, operadors, prec. La Llibreria stdio.h Flux de dades I
Exemple
5 % 3; // El resultat es 25 > 3; // El resultat es veritat5 <=3; // El resultat es fals
!(5 > 3); // El resultat es fals(5 > 3)||(3 < 5); // El resultat es veritat
num++; // Aquestas dues linea fan el mateixnum = num+1;
En el llenguatge C veritat=1 i fals=0.
Exemple
Compte!!:
real = 3/2; // El resultat es 1.0; NO 1.5real = 3.0 / 2; // En canvi, ara, el resultat sı que es 1.5
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Estructura Dades, operadors, prec. La Llibreria stdio.h Flux de dades I
Precedencia dels operadors en C
Operador Significat
( ) Crida a funcio[ ] Acces a component de vector.-> Acces a camp d’estructura! Negacio logica
++ -- Autoincrement i autodecrement+ - Indicacio i canvi de signe* & Indireccio i adreca
( tipus ) Coercio de tipussizeof() Numero de bytes% * / Modul, producte i divisio+ - Suma i resta
< <= > >= Comparacio de nombres== =! Igualtat i diferencia logica&& i logica|| o logica? : Expressio condicional= Assignacio
+= -= Assignacio amb operacio*= /= %= Assignacio amb operacio
, Concatenacio
A la taula es poden observarels operadors (ordenats demes a menys prioritat, amb elsgrups de prioritat separats perlınies horitzontals) i el seusignificat. Evidentment, elsparentesis es poden usar pertrencar la prioritat d’undeterminat conjuntd’operadors en una expressio.Es molt recomanable emprenarparentesis en els casos en quel’ordre d’avaluacio no quediclar sense consultar la taula deprecedencia d’operadors.
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Estructura Dades, operadors, prec. La Llibreria stdio.h Flux de dades I
Entrada/sortida: basics
La llibreria stdio.h (standart input/output) ens permet utilitzar lesfuncions:
printf per escriure a la pantallascanf per llegir del teclat
La inclourem a traver de la commanda de preprocesador
#include<stdio.h>
Exemple
int a; //creem una variable de tipus int
float real=3.2; //creem una variable de tipus float
//amb valor 3.2
printf("Escriu un nombre enter\n");
//escribim a la pantalla
scanf("%d",&a); //llegim un nombre del teclat i
//el guardem a la variable a
printf("Has escrit %d i real val %f\n",a, real);
/*imprimim el nombre que vam escriure i el valor que conte real*/Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Estructura Dades, operadors, prec. La Llibreria stdio.h Flux de dades I
Instruccions de control de flux: l’if
if (expressio ) instruccio ;else instruccio ;if (expressio ) {
instruccio ;..
instruccio ;}else{
instruccio ;..
instruccio ;}/* fi de l´if */
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Estructura Dades, operadors, prec. La Llibreria stdio.h Flux de dades I
Exemples
Exemple
Suposem que tenim ax2 + bx + c .
disc = b*b - 4*a*c;
if(disc < 0)
printf("Discriminant negatiu. No hi ha arrels reals.\n");
else {
disc = sqrt(disc); a = 2*a;
printf("Les arrels son: %f i %f\n", (-b+disc)/a,(-b-disc)/a);
}
Exemple
if(((a > 0) && (d*c <= a)) || (d > 0 && d < 4))
printf("Les variables a, d i c son correctes\n");
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Flux de dades II La coercio de tipus de dades Entr/sort - impressio
Sessio 3
1 Sessio 1Com es fa un programa?AlgorismesAritmetica binaria
2 Sessio 2Estructura d’un programaTipus de dades, operadors, precedencia.La Llibreria stdio.hFlux de dades I
3 Sessio 3Flux de dades IILa coercio de tipus de dadesEntrada/sortida - Formats d’impressio
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Flux de dades II La coercio de tipus de dades Entr/sort - impressio
Instruccions de control de flux: els llacos for i while
for (
inicialitzacio; /* Per ex.: i = 0 */
expressio; /* Per ex.: i < LIMIT */
continuaci ; /* Per ex.: i = i + 1 */
){
instruccions;...}/* fi del for */
while (expressio) {
instruccions;...}/* fi del while */
do {
instruccions ;...}while (expressio);
Exemple
for(i=0, pot=1 ; i<=n ; i++, pot*= 3) printf("3^%d = %d\n", i, pot);Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Flux de dades II La coercio de tipus de dades Entr/sort - impressio
Equivalencia entre el llac for el i el while
for( inicialitzacio ; inicialitzacio ;expressio ; while( expressio )continuacio ; {
){ ;instruccions ; instruccions ;
continuacio ;} /* fi del for*/ } /* fi del while */
Exemple
pot = 1; i=0; pot=1;
for (i = 0; i <= n; i++){ while(i <= n){
printf ("3^%d = %d\n",i,pot); printf ("3^%d = %d\n",i,pot);
pot = pot * 3; pot = pot * 3; i = i + 1;
} }
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Flux de dades II La coercio de tipus de dades Entr/sort - impressio
Control de flux dels llacos: break; i continue;
L’estructura de control d’un programa no reflecteix el que realment fa elprocessador (salts condicionals i incodicionals) en l’aspecte del control deflux d’un programa.
El llenguatge C, no obstant aixo, incorpora instruccions que ens acostenmes a la realitat de la maquina com la sortida forcada de bucle (break) ila de continuacio forcada del bucle (continue).
Nota
Tambe existeix la instruccio de salt incondicional goto, que, per aconservar la programacio estructurada, no s’ha d’utilitzar mai.
Problema d’exemple: Per n variant de 1 a 20 i a enter positiu calcularn/(n2 − a ∗ n + 375) sempre que el denominador sigui positiu.Variant 2: Fer el calcul nomes fins la primera vegada que el denominadorno es positiu.
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Flux de dades II La coercio de tipus de dades Entr/sort - impressio
El programa llacos.c
Exemple
// Programa llacos.c
#include <stdio.h>
void main ()
{
int a, n,denom;
printf("Entra el parametre a: "); scanf("%d",&a);
for (n = 1; n <= 20; n++){
denom = n*n -a*n + 375;
printf("n = %d:\n",n);
// Metode inicial
// if (denom > 0)
// Quan la resta del llac es molt gran pot ser mes clar:
// if (denom <= 0) continue;
// Variant 2:
// if (denom <= 0) break;
printf ("Formula = %lf\n",((double) n)/denom);
}
} Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Flux de dades II La coercio de tipus de dades Entr/sort - impressio
La coercio de tipus de dades
A l’exemple anterior noteu l’expressio ((double) n)/denom. Si posemsimplement n/denom el resultat es trunca a un enter (erroni!!). Perforcar que el resultat sigui float o double es pot fer la potineria:(n*1.0)/denom.
La manera de fer-ho pero es forcant el canvi de tipus. L’expressio((double) n) te com a resultat el nombre n pero en format double.En general, el canvi de tipus es pot forcar indicant el tipus d’un operandentre parentesis que el precedeixin. Es a dir:
( especificacio_tipus ) operand
Exemple contrari: Si a es un float o un double positiu, llavors
(int) a
torna la part entera de a.
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Flux de dades II La coercio de tipus de dades Entr/sort - impressio
Sortida
La instruccio base es:
printf( “format d’escriptura entre cometes”
,llista de variables a imprimir);
Exemple
printf("L´import de la factura numero %5d",NumFact);printf("del Sr. %s puja a %d Euros.\n",NomClient,Import);
El format pot contenir caracters especials i especificadors de camp. Sis’especifiquen mes camps a imprimir que variables a la llista d’objectesimprimir, els resultats son imprevisibles (en general, veurem caractersestranys a la pantalla).
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Flux de dades II La coercio de tipus de dades Entr/sort - impressio
Caracters especials
\n newline\f form feed\b backspace\t tab\nnn ASCII nnn (octal)\xnn ASCII nn (hexadecimal)\\ backslash%% el caracter del %
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Flux de dades II La coercio de tipus de dades Entr/sort - impressio
Especificadors de camps (I)
% [-][+][amplada[.precisio ]]tipus%d enter en base decimal%i enter amb signe (igual a d)%u enter no signat%o enter en base vuit (octal)%x enter en hexadecimal%c caracter%s cadena de caracters%f real en punt flotant%e real en format exponencial%g real en format e, f o d%lf real doble en punt flotant%% el caracter del %
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Flux de dades II La coercio de tipus de dades Entr/sort - impressio
Especificadors de camps (II)
El signe -indica que el camp s’alinea a la dreta, cosa comuna per ala impressio de nombres enters el signe del qual nomes s’escriu encas que siguin negatius a menys que no s’indiqui +.
L’amplada s’utilitza per delimitar el nombre de caracters mınim quees reservara per a la impressio del camp corresponent. En el cas delsnombres en punt flotant, es pot especifiar el nombre de nombresdecimals que es desitja imprimir amb precisio.Tots aquests camps son opcionals.
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Flux de dades II La coercio de tipus de dades Entr/sort - impressio
Exemple: fabriquem la taula ASCII. El programa fesascii
Exemple
// Programa fesascii.c#include <stdio.h>void main (){char codi;for(codi=33; codi<127 ;codi++){
printf("%3d <--> %c\n",codi,codi);}
}
Notem que cada enter entre 33 i 126 (els caracter visibles) l’imprimim dedues maneres diferents: com a enter %d (codi numeric) i com a caracter%c (que tradueix el codi numeric a caracter).
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Flux de dades II La coercio de tipus de dades Entr/sort - impressio
Entrada
La instruccio base es:
scanf( “format de lectura entre
cometes”,llista de variables a llegir amb &);
La funcio scanf( ) llegeix els caracters teclejats per convertir-los ennombres del tipus especificat pel format. Els nombres que s’obtinguind’aquesta operacio se situaran a l’adreca indicada al seu argument, es adir, a &variable.
Aquesta lectura de caracters del teclat s’atura quan el caracter llegit jano es correspon amb un possible caracter del format especificat. La restade caracters queden al bufer del teclat en espera d’alguna altra lectura.
Exemple
scanf("%d %f %c", &enter, &real, &caracter);3 2.4 ascanf("%d; %f, %c: %lf", &enter, &real, &caracter, &doble);3; 2.4, a: 0.37
Albert Ruiz Programacio en C
Sessio 1 Sessio 2 Sessio 3 Flux de dades II La coercio de tipus de dades Entr/sort - impressio
Funcions especıfiques d’entrada/sortida de caracters
putchar( character ): Mostra character per pantalla.Exemple: putchar( ´\n´ );
puts( string ): Mostra una cadena de caracters string perpantalla.Exemple: puts( "Hola a tothom!" );
getchar( ): Retorna un caracter llegit del teclat.Exemple: Opcio = getchar( );
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Funcions Variables Adreca i indireccio
Sessio 4
4 Sessio 4FuncionsVariables locals i globalsEls operadors d’adreca i indireccio
5 Sessio 5Vectors i matriusCadenes de caracters
6 Sessio 6Entrada/sortida: FitxersPreprocesador i macrosParametres del main
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Funcions Variables Adreca i indireccio
Utilitat
Eficiencia. Si cal fer el mateix procediment a diferents llocs diferentsdel programa, el codifiquem una unica vegada en una funcio il’utilitzem als llocs que calgui cridant la funcio.
Estructura-Modularitat. La creacio de funcions permet dividir lacomprensio fa mes facil la realitzacio del programa i el seu depuratd’errors.
Seguretat. Cada funcio es pot provar i consolidar per separat. Encas d’error podem descartar les funcions consolidades.
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Funcions Variables Adreca i indireccio
Estructura de les funcions
tipus nomfuncio ( llista-parametres ){// Declaracions de variables locals// Instruccions de la funcio
return (expressio);} /* Fi de la funcio */
Els tipus de la funcio es el tipus de dada que torni amb el return. Si notorna cap valor amb el return, la funcio es tipus void
Exemple
La funcio que calcula1
1 + x2:
double f( double x ){return 1.0/(1.0 + x*x);
} /* f */
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Funcions Variables Adreca i indireccio
Exemple d’us: El programa grafica.c
Exemple
// Programa grafica.c
#include <stdio.h>
/* Prototipus de la funcio f. Com als fitxers de capcalera.
Serveix perque el compilador pugui comprovar que utilitzem
be la funcio */
double f( double );
void main ()
{
double x;
for(x=0.0; x<= 10.0 ; x+= 0.01) printf("%f %f\n",x,f(x));
}
double f( double x )
{
return 1.0/(1.0 + x*x);
} /* f */
Comandes a executar:
$./grafica > funcio.dat
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Funcions Variables Adreca i indireccio
Les variables del C: variables locals i globals
En el programa anterior, el fet que la variable es digui x al programaprincipal i a la funcio no es important. En llenguatge C els parametres deles funcions es passen per valor. Aixo vol dir que, quan es crida lafuncio, el valor de la variable x del programa principal es copia alcontingut de la variable x de la funcio. En particular
1 La variable x del programa principal es diferent de la variable x de lafuncio.
2 Si modifiquem la variable x a dins de la funcio, la variable x alprograma principal no s’altera.
Les variables en llenguatge C son locals del modul on viuen!!
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Funcions Variables Adreca i indireccio
Exemple: El programa grafica2.c
// Programa grafica2.c#include <stdio.h>double f( double );double uno=1.0; // Aquesta variable es global a tot el programavoid main (){double x = 2.0;printf("Uno: %lf\n", uno); // Correcte: variable conegudaprintf("Dos: %lf\n", dos); /* Error de compilat.
La variable dos solament es coneix mes avall*/printf("Aux: %lf\n", aux); /* Error de compilat.
La variable aux solament es coneix dins del bloc seguent*/printf("z: %lf\n", z); /* Error de compilat.
La variable z solament es coneix dins de la funcio*/{ double aux=2*x;printf("Aux: %lf\n", aux); // Correcte: variable conegudaprintf("x abans = %f; Funcio = %f; x despres = %f\n",x,f(x),x);
}printf("Aux: %lf\n", aux); /* Error de compilat. La variable aux solament es
coneix dins del bloc anterior */}double dos=2.0; // Aquesta variable solament es coneguda a partir d´aquidouble f( double z ){z = dos/(uno + z*z); // Correcte aquı coneixem uno i dos. Redefinim la z.return z;
} /* f */
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Funcions Variables Adreca i indireccio
Els operadors * i &
El valor de cada variable esta emmagatzemat en un lloc determinat de lamemoria, caracterizat per una direccio.Un apuntador es una variable (tipus apuntador a tipusint, float, char...) que conte la direccio d’una altra variable (del
mateix tipus).L’operador direccio & retorna l’adreca de la variable a la qual s’aplica.L’operador indireccio * te dues aplicacions:
retorna la informacio continguda a la direccio que conte elapuntador.defineix un apuntador.
Exemple
int i,*p; //p es un apuntador a variable int
p=&i; //p conte la direccio d’i
*p=10; //a la direccio continguda en *p guardem el valor 10
printf("El valor emmagatzemat a la variable i = %d\n",i);
printf("La direccio de la variable i = %d\n",&i);
printf("El valor emmagat. a l’apuntador p = %d\n",p);
printf("El valor emmagat. a la direccio conting. en p = %d\n",*p);
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Funcions Variables Adreca i indireccio
Funcions que tornen mes d’un valor.
Recordem que una funcio nomes retorna un valor amb return.Si volem que una funcio torni mes d’un valor una possibilitat es fer-houtilitzant els apuntadors.
Definim al programa principal variables r1,r2,... que contindran elsvalors de retorn.
Copiem a la funcio la direccio les varibles r1,r2... anteriors dinsdels apuntadors.
Tornem els valors escrivint els valors desitjats en les posicionsd’r1,r2,...
Exemple
Estudiem i “juguem” amb el programa seguent. Donats dos nombres x iy volem calcular x + y , x − y , x · y i x/y .
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Funcions Variables Adreca i indireccio
Exemple: el programa calculs.c
// Programa calculs.c
#include <stdio.h>
// Prototipus
void calculs( double, double, double *, double *, double *, double *);
void main ()
{
double x,y;
double suma, resta, p, q;
printf("Entra x i y separats per una coma: ");
scanf("%lf,%lf", &x,&y);
calculs(x, y, &suma, &resta, &p, &q);
printf("La suma es: %f\n", suma);
printf("La resta es: %f\n", resta);
printf("El producte es: %f\n", p);
printf("El quocient es: %f\n", q);
}
void calculs( double x, double y, double *s, double *r, double *p, double *q)
{
*s = x+y;
*r = x-y;
*p = x*y; // No confongueu els dos *. Son diferents!!
*q = x/y; // Error. Pot donar problemes.
} /* Fi de calculs */
Comandes a executar:
$ ./calculs
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Vectors i matrius Cadenes de caracters
Sessio 5
4 Sessio 4FuncionsVariables locals i globalsEls operadors d’adreca i indireccio
5 Sessio 5Vectors i matriusCadenes de caracters
6 Sessio 6Entrada/sortida: FitxersPreprocesador i macrosParametres del main
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Vectors i matrius Cadenes de caracters
Vectors i Matrius
Son tires de variables que permeten emmagatzemar conjunts de dades ennombre variable.
Exemple
Els coeficients d’un polinomi, els resultats d’un experiment per fer-ne unaestadıstica,...
Nota
Les cadenes de caracters son vectors de tipus char amb el codi ASCII 0 alfinal com a marca de final de cadena (notem que no hi ha cap caracterque tingui el codi ASCII 0 - En particular el caracter 0 te el codi ASCII48).
Nota
Les matrius m × n es representen com a vectors de llargada m · n escritsper files.
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Vectors i matrius Cadenes de caracters
Inicicialitzacio-declaracio
Exemple
double vector[5] = { 1.0, 1.1, 1.2, 1.3, 1.4 };
int matriu[3][3] = { 00, 01, 02, 10, 11, 12, 20, 21, 22 };
int matriu[3][3] = { /* o be, mes recomanable ... */
{ 00, 01, 02 },
{ 10, 11, 12 },
{ 20, 21, 22 },
};
char cadena[21] = { ´H´, ´o´, ´l´, ´a´, 0 };
char cadena[21] = "Hola"; /* o be, mes comodament ... */
char missatge[] = "Hola a tothom";
int vector[30] = { 20, 21, 22, 23, 24, 25, 26 };
/* Inicialitzacio incompleta (permesa) */
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Vectors i matrius Cadenes de caracters
Observacions
Nota
En llenguatge C els vectors i matrius sempre comencen per l’ındex 0. Pertant, les components de vector[4] son vector[0], vector[1],vector[2] i vector[3].
Nota
Les cadenes inicialitzades amb un text entre cometes ja porten implıcit elcaracter ´\0´ d’acabament i no cal incloure’l a la cadena de caracters deltext constant.
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Vectors i matrius Cadenes de caracters
Us de vectors i matrius
Per fer referencia a un element d’un vector o matriu, nomes cal indicar elnom i la posicio de l’element en particular al qual volem accedir:
vector[i]matriu[i_0][i_1]...[i_n]
i i les ik han de ser variables, constants o expressions el resultat de lesquals siguin enters. Per exemple, llegir els elements de la matriu de 3× 3enters declarada anteriorment, es faria de la manera seguent:
Exemple
for( i = 0; i<3; i = i + 1 ) {for( j = 0; j<3; j = j + 1 ) {printf( "matriu[%d][%d] = ? ", i, j );scanf( "%d", &(matriu[i][j]) );
} /* for */} /* for */
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Vectors i matrius Cadenes de caracters
Avıs!!!
El llenguatge C no comprova que al referenciar un element d’un vector omatriu no ens passem del rang de dimensionament. Per exemple, lainstruccio
vector[27] = 1.e-8
es perfectament valida independentment de la dimensio de vector. El quefa es que copia la constant 1.e-8 27 posicions de memoria mes endavantdel principi del vector (que, de fet, es el principi devector[0] = &(vector[0])). El fet de posar un nombre en una posiciode memoria incontrolada, com a mınim, pot comprometre l’execucio delnostre programa i, probablement, el funcionament del sistema operatiu.
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Vectors i matrius Cadenes de caracters
Exemple: Entrar i escriure vectors i matrius (matrius.c).
Exemple
#include <stdio.h>
#define DIMENSIO 2
int main()
{
int a[DIMENSIO][DIMENSIO];
int i,j;
puts("Entrem la matriu");
for (i=0; i < DIMENSIO ; i++){
for (j=0; j < DIMENSIO ; j++){
printf("a(%d,%d)=?",i+1,j+1);
scanf("%d",&(a[i][j]));
}
}
puts("Ara imprimim la matriu:");
for (i=0; i < DIMENSIO ; i++){
for (j=0; j < DIMENSIO ; j++){
printf("%d ",a[i][j]);
}
printf("\n");
}
return 0;
}Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Vectors i matrius Cadenes de caracters
Exemple: Entrar i escriure vectors i matrius (matrius.c).
Exemple
Podem substituir la impressio de la matriu per aquestes dues altresmaneres:
// tambe es pot fer d’aquest manera:
for (i=0; i<DIMENSIO;i++){
for (j=0;j<DIMENSIO;j++) printf("%d ",*(*(a+i)+j));
printf("\n");
}
// i d’aquesta (que es la que tenia al cap a classe, com a vector)
int *b;
b=&(a[0][0]);
for (i=0;i<DIMENSIO*DIMENSIO;i++) printf("%d ",*(b+i));
printf("\n");
Explicacio: quan definim int a[2][2] la variable a conte l’adreca oncomencen dos vectors tipus int, per tant *a retorna una adreca. Encanvi *(*a) conte l’enter a[0][0].
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Vectors i matrius Cadenes de caracters
Mes elegant: la impressio la fa una funcio (vectorsf.c)
Exemple
#include <stdio.h>#define DIMENSIO 2void imprimeixvector (float *, int);int main(){
float v[DIMENSIO];int i;puts("Entrem el vector");for (i=0; i < DIMENSIO ; i++){
printf("v(%d)=?",i+1);scanf("%f",&(v[i]));
}puts("Ara l´imprimim:");imprimeixvector (v, DIMENSIO);return 0;
}
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Vectors i matrius Cadenes de caracters
La funcio imprimeixvector
Exemple (La funcio imprimeixvector)
void imprimeixvector (float *vect, int dim){
int i;for(i=0; i < dim ; i++) printf("%f ",vect[i]);printf("\n");
}
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Vectors i matrius Cadenes de caracters
Les matrius son especials perque son quadrades.
Exemple (El programa matriusf.c)
#include <stdio.h>
#define DIMENSIO 20
void imprimeixmatriu (float [][DIMENSIO], int);
int main()
{
float a[DIMENSIO][DIMENSIO];
int i,j, dim;
printf("Entra la dimensio <= %d\n",DIMENSIO);
scanf("%d", &dim);
if(dim > DIMENSIO) {
puts("Error: dimensio massa gran");
return 1;
}
puts("Entrem la matriu");
for (i=0; i < dim ; i++){
for (j=0; j < dim ; j++){
printf("a(%d,%d)=?",i+1,j+1);
scanf("%d",&(a[i][j]));
}
}
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Vectors i matrius Cadenes de caracters
Error a la transparencia anterior:
Nota
Hi ha un error quan demanem els coeficients de la matriu: es de floats ihi posa %d, per tant a la lınia 18 ha de posar
scanf("%f",&(a[i][j]));
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Vectors i matrius Cadenes de caracters
La funcio que imprimeix la matriu
Exemple (Final del programa matriusf.c )
puts("Ara imprimim la matriu com a matriu:");imprimeixmatriu (a, dim);return 0;
} /* Fi del main */
void imprimeixmatriu (float mat[][DIMENSIO], int dim){int i, j;for (i=0; i < dim ; i++){for (j=0; j < dim ; j++){
printf("%f ",mat[i][j]);}printf("\n");
}}
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Vectors i matrius Cadenes de caracters
Mes difıcil encara: les matrius, de fet, son vectors i esguarden per fileres (matriust.c).
#include <stdio.h>
#define DIMENSIO 2
void imprimeixvector (float *, int);
int main()
{
float a[DIMENSIO][DIMENSIO];
int i,j;
puts("Entrem la matriu");
for (i=0; i < DIMENSIO ; i++){
for (j=0; j < DIMENSIO ; j++){
printf("a(%d,%d)=?",i+1,j+1);
scanf("%f",&(a[i][j]));
}
}
puts("Ara imprimim la matriu com a vector");
imprimeixvector ((float *) a, DIMENSIO*DIMENSIO);
return 0;
}
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Vectors i matrius Cadenes de caracters
La “trampa”
Exemple (la funcio)
void imprimeixvector (float *vect, int dim){
int i;for(i=0; i < dim ; i++) printf("%f ",vect[i]);printf("\n");return;
}
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Vectors i matrius Cadenes de caracters
Un tipus especial de vectors: les cadenes de caracters
En C no es poden fer assignacions, comparacions ni cap altra operaciodirecta amb cadenes completes ja que son vectors. Solament es podenfer caracter a caracter. D’aquesta manera, una assignacio d’una cadena auna altra s’hauria de fer de la forma seguent:
Exemple
char cadena[MAXLEN]="Cadena font";char altra[MAXLEN];int i;.......for(i=0; i<MAXLEN; i = i + 1) { /* copia de cadenes */
altra[i]=cadena[i];} /* for */
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Vectors i matrius Cadenes de caracters
Funcions estandard per a cadenes de caracters
Com que l’us de cadenes de caracters es practicament obligat enqualsevol programa, afortunadament, per estalviar feina, existeix unabiblioteca de funcions estandard per fer les operacions mes habitualssobre cadenes. Els seus prototipus es carregen usant el fitxer de capalera:
#include <string.h>
Un llistat breu d’aquestes funcions es:
int strlen ( char *string );
char *strcpy ( char *destination, char *source );
char *strncpy ( char *destination, char *source, int num-de-chars );
char *strcat ( char *destination, char *source );
char *strncat ( char *destination, char *source, int num-de-chars );
char *strdup ( char *source );
int *strcmp ( char *string_1, char *string_2 );
int *strncmp ( char *string_1, char *string_2, int num-de-chars );
char *strchr ( char *string, char character );
char *strrchr ( char *string, char character );
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Vectors i matrius Cadenes de caracters
Comentaris
La longitud real d’una cadena de caracters kdna en un momentdeterminat es pot obtenir a traves de la funcio strlen( kdna ).
En cas que es vulgui copiar el contingut de la cadena de caracterskdna a kdna9, es pot usar la funcio strcpy( kdna9, kdna ) o, sila cadena font pot ser mes llarga que la capacitat de la cadenadestinacio, strncpy( kdna9, kdna, LONGKDNA9-1 ). En aquesultim cas, cal preveure la possibilitat que la cadena resultant noporti un 0 final. Per aixo, cal reservar l’ultim caracter de la copiaamb compteig per situar-hi un 0 de guarda. Si la nova cadena notingues espai reservat, caldria fer la reserva.
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Vectors i matrius Cadenes de caracters
Comentaris (II)
La comparacio de cadenes es fa caracter a caracter, comencant pelprimer caracter de les dues cadenes a comparar i passant alscaracters seguents mentre la diferencia dels codis ASCIIcorresponents sigui 0. La funcio strcmp( ) retorna el valor del’ultima diferencia. Es a dir, negatiu si la segona cadena esalfabeticament mes gran que la primera, positiu en el cas oposat, i 0si son iguals.
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Vectors i matrius Cadenes de caracters
Comentaris (II)
Per entendre-ho millor, tot seguit apareix el possible codi d’una funcio decomparacio de cadenes:
Exemple
int strcmp( char *cad1, char *cad2 ){int dif = 0;while((*cad1 != ´\0´) &&(*cad2 != 0) &&( ( dif = *cad1 - *cad2 ) != 0 )) {
cad1 = cad1 +1;cad2 = cad2 +1;
} /* while */return dif;
} /* strcmp */
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Vectors i matrius Cadenes de caracters
La funcio strncmp( ) fa el mateix que la seva germana strcmp( )amb els primersnum-de-caracters.
Finalment -tot i que n’hi ha mes-, comentarem les funcions de cercade caracters dins de cadenes: strchr( ) i strrchr( ). Aquestesfuncions retornen la cadena de caracters que comenca al caracterbuscat dins la cadena o NULL si no el troben. La primera funcioinspecciona la cadena des del primer caracter i la segona ho facomencant pel final. Aixı, la funcio strchr( ) seria,aproximadament, com la seguent:
Exemple
int strchr( char *cadena, char caracter ){while( (*cadena != ´0´) && (*cadena != caracter) ){ cadena = cadena +1; }return cadena;
} /* strchr */
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Vectors i matrius Cadenes de caracters
Entrada sortida a cadenes de caracters
Tot i que moltes operacions sobre cadenes de caracters es poden fer ambles funcions anteriors, pot resultar molt util treballar amb una cadena comsi fos una sortida o una entrada estandard de dades. Per aixo, existeixenles versions per a cadenes de les funcions printf( ) i scanf( ):
sprintf( cadena, format [, llista_variables ] );sscanf ( cadena, format [, llista_&variables ] );
En tots dos casos, cadena es refereix a la cadena de caracters sobre laqual es fara l’operacio, format es la cadena que conte el format en ques’ha d’escriure o llegir la cadena, i els claudators indiquen l’opcionalitatde la llista de variables subseguent.
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Entrada/sortida: Fitxers Preprocesador i macros Parametres del main
Sessio 6
4 Sessio 4FuncionsVariables locals i globalsEls operadors d’adreca i indireccio
5 Sessio 5Vectors i matriusCadenes de caracters
6 Sessio 6Entrada/sortida: FitxersPreprocesador i macrosParametres del main
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Entrada/sortida: Fitxers Preprocesador i macros Parametres del main
Mes entrada/sortida: Fitxers
La connexio del nostre programa amb fitxers es fa usant apuntadors afitxers:
FILE *apuntador_a_fitxer
La variable de tipus apuntador a fitxer que s’inicialitza a l’obrir el fitxer.Es el nom del nostre canal de comunicacio (dins del programa) amb elfitxer. Aquest tipus de dades es defineix al fitxer de capcalera stdio.h.
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Entrada/sortida: Fitxers Preprocesador i macros Parametres del main
Mes entrada/sortida: Fitxers (II)
Esquema base per a llegir/escriure un fitxer:
FILE *apuntador_a_fitxer;
...
apuntador_a_fitxer= fopen(......); // Inicialitzacio
if(apuntador_a_fitxer== NULL){
puts(... treure un missatge d´error ...);
return 1;
}// SEMPRE cal comprovar que s´ha pogut obrir el fitxer
...
while(1) { // Recorregut sequencial del fitxer
fscanf(apuntador_a_fitxer, ... ); // Lectura de cada lınia
if(feof(apuntador_a_fitxer)) break;
...
} /* Fi del while */
...
fclose( apuntador_a_fitxer ); // Tanquem el fitxer
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Entrada/sortida: Fitxers Preprocesador i macros Parametres del main
Obrir i tancar: les funcions fopen i fclose
La funcio base es la fopen: crea un canal de comunicacio entre el fitxer iel programa amb la finalitat especificada pel mode d’obertura.
FILE * fopen(const char *nom-del-fitxer,const char *mode-d-obertura);
mode-d-obertura = "r" (read) "t" (text - es el defecte)"w" (write) "b" (binary)"a" (append)
Si, s’aconsegueix crear el canal (el fitxer existeix i tenim permisos delectura o be tenim permisos per crear el fitxer i hi ha prou espai de disc)es “connecta” a la nostre apuntador a fitxer; que esdeve el nom logic delcanal de connexio amb el fitxer. Si el proces falla la nansa conte un NULL.Es important tacar el fitxer quan acabem.
int fclose( FILE *apuntador_a_fitxer );
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Entrada/sortida: Fitxers Preprocesador i macros Parametres del main
Hi ha tres apuntadors a fitxers que estan definides sempre:
variable significat dispositiustdin entrada estandard teclatstdout sortida de dades estandard pantallastderr sortida d’errors estandard pantalla
Nota
Aixı
printf(format [, vars]) = fprintf(stdout, format [, vars])
scanf (format [, &vars]) = fscanf (stdin, format [, &vars])
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Entrada/sortida: Fitxers Preprocesador i macros Parametres del main
Funcions d’entrada/sortida a fitxers
FILE * fopen( const char *nom-de-fitxer, const char *mode-d-obertura );
int fclose( FILE *stream );
void rewind( FILE *stream );
int feof( FILE *stream );
int fgetc( FILE *stream );
char * fgets( char *string, int maxchar, FILE *stream );
int fscanf( FILE *stream, const char *format_string, ... );
int fputc( int character, FILE *stream );
int fputs( const char *string, FILE *stream );
int fprintf( FILE *stream, const char *format_string, ... );
long ftell( FILE *stream );
int fseek( FILE *stream, long int offset, int direction );
direction = SEEK_SET forward from beginning of file
SEEK_CUR forward from current position
SEEK_END backward from end of file
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Entrada/sortida: Fitxers Preprocesador i macros Parametres del main
Un exemple: transposar un fitxer de dades
#include <stdio.h>#include <string.h>#include <stdlib.h> /* Per la funcio atoi */#define MAXLENNOM 251int main (int argc, char *argv[]){FILE *fin, *fout;int x, xx=0,col,n,ncols;char nomsortida[MAXLENNOM];if (argc != 3 || (ncols = atoi (argv[2])) <=0) {
fprintf(stderr, "\nUs: %s <nomfitxer> <nombre-de-columnnes>\n\n", argv[0]);return 1;
}if(strlen(argv[1])+4 >= MAXLENNOM) {
fprintf(stderr, "\nERROR: El nom del fitxer %s es massa llarg...\n\n", argv[1]);return 1;
}if ((fin = fopen (argv[1], "r")) == NULL) {
fprintf(stderr,"\nERROR: El fitxer ´%s´ no existeix o no es pot obrir...\n\n", argv[1]);return 1;
}strcpy(nomsortida,argv[1]); strcat(nomsortida,".trp");printf("Comprovacio: %s\n", nomsortida );if ((fout = fopen (nomsortida, "w")) == NULL) {
fprintf (stderr,"\nERROR: No es pot obrir el fitxer de sortida ´%s´...\n\n", nomsortida);return 1;
}// fout = stdout; // Trampa!! aixo fa que la sortida sigui per pantalla
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Entrada/sortida: Fitxers Preprocesador i macros Parametres del main
El nucli del programa
for(col=0;col<ncols; col++) /* Anem a escriure la columna col.{ Cal que llegim ncols vegades tot el fitxer */
while (1){
for(n=0;n<ncols;n++) // Cal llegir els ncols nombres de cada lınia{
fscanf (fin, "%d", &x); if(n == col) xx= x;} /* Fi del for n */if(feof(fin)) break ;fprintf(fout, "%d ", xx);
} /* Fi del while */fprintf(fout,"\n");rewind(fin);
} /* Fi del for col */fclose (fin);fclose(fout);return 0;}
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Entrada/sortida: Fitxers Preprocesador i macros Parametres del main
Preprocessador
Ja hem vist que el preprocessador permet d’incloure els fitxers decapcalera de les funcions i definir constants simboliques.
#include <fitxer-de-capcalera.h>#include "fitxer-de-capcalera-propi.h"#define sımbol expressio_constant
Exemple
Ja vistos:
#include <stdio.h>#define DIMENSIO 2#define PI 3.141592653589793238462643383279502884197#define TOL 1.0e-6
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Entrada/sortida: Fitxers Preprocesador i macros Parametres del main
Macros
A mes, el preprocessador permet algunes substitucions amb parametres(les ”macros”), en contraposicio a les substitucions literals de lesdefinicions constants vistes fins ara:
#define nom_de_macro(arguments) expressio_amb_arguments
L’us de les macros ajuda a aclarir petites parts de codi emprant una“especie de funcio” amb algun nom significatiu de manera que la lecturaen sigui mes facil i no impliqui una crida real a una funcio amb un cos decodi que no la justifiqui com a tal. En aquesta funcio es molt util laconstruccio (if aritmetic):
(condicio) ? valor-si-veritat : valor-si-falsxx = (x < 0 ? -x : x) ; // xx es el valor absolut d´x
Cal tenir en compte que el nom de la macro i el parentesi esquerre nopoden anar separats i que la continuacio d’una lınea es fa col.locant unabarra inversa just abans del caracter de salt de lıinia (en cas que lacomanda de preprocessador sigui massa llarga).
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Entrada/sortida: Fitxers Preprocesador i macros Parametres del main
Exemple
#define abs(x) (x < 0 ? -x : x)#define round(x) ((int) ((double) x + 0.5 ))#define trunc(x) ((int) (x))#define MAX(x,y) ((x<y) ? y : x)#define PI 3.141592653589793238462643383279502884197#define quadrat(x) x*x#define area_cercle(r) PI*quadrat(r)
Albert Ruiz Programacio en C
Sessio 4 Sessio 5 Sessio 6 Entrada/sortida: Fitxers Preprocesador i macros Parametres del main
Parametres del main
Estudiem i “juguem” amb el programa seguent:
Exemple
// Programa parametres.c
#include <stdio.h>
int main (int argc, char *argv[])
{
int n;
printf("---Informe del Programa Parametres---\n");
printf(" Numero de parametres: %d\n", argc);
if(argc == 1){
printf("Error: No hi ha parametres\n\n");
return 1;
}
for(n=0; n<argc; n++){
printf("Parametre %d: %s\n",n,argv[n]);
}
putchar(’\n’);
return 0;
}
Comandes a executar:
$./parametres, $./parametres 1 -2 -3 4 55
Albert Ruiz Programacio en C