Você está na página 1de 71

Renato Cardoso Mesquita Departamento de Eng. Eltrica da UFMG renato@cpdee.ufmg.

br

Linguagens C e C++

1. As linguagens C e C++: uma introduo sintaxe . . . . . . .

1.1 Histrico, e estrutura dos programas

C nasceu na dcada de 70. Seu inventor, Dennis Ritchie, implementou-o pela primeira vez usando um DEC PDP-11 rodando o sistema operacional UNIX. O C derivado de uma outra linguagem: o B, criado por Ken Thompson. O B, por sua vez, veio da linguagem BCPL, inventada por Martin Richards. O C personalizava duas caractersticas fundamentais na programao profissional: o maior poder de programao dado ao programador e a portabilidade dos sistemas (padronizao e existncia de vrios compiladores para diferentes plataformas). Na primeira metade da dcada de 80, Bjarne Stroustrup, nos laboratrios AT&T desenvolvia o C++ com o objetivo de integrar os poderes da Programao Orientada a Objetos ao C. A linguagem C++ foi recentemente padronizada pela ANSI.

Linguagens C e C++: Uma introduo sintaxe Pg. 2 O clssico Hello World:

#include <stdio.h> void main () /* Um Primeiro Programa */ { printf ("Alo Mundo \n"); } #include <stdio.h> Comentrios em C e C++ /* Um Primeiro Programa */. // Um Primeiro Programa /* OBS: C++ aceita ambos estilos! */ Comandos do C terminam com ; Um segundo programa: #include <stdio.h> void main () { int Dias; /* Declaracao de Variaveis */ float Anos; printf ("Entre com o nmero de dias: "); /* Entrada de Dados */ scanf ("%d",&Dias); Anos=Dias/365.25; /* Conversao Dias->Anos */ printf ("\n\n%d dias equivalem a %f anos.\n", Dias , Anos); } Exerccio: O que faz o seguinte programa? #include <stdio.h> void main() { int x; scanf("%d", &x); printf("%d", x); }

Linguagens C e C++: Uma introduo sintaxe Pg. 3 1.2. Introduo s Funes Uma funo um bloco de cdigo de programa que pode ser usado diversas vezes em sua execuo. O uso de funes permite que o programa fique mais legvel, mais bem estruturado. Um programa em C consiste, no fundo, de vrias funes e chamadas a estas funes. #include <stdio.h> void mensagem () { printf ("Ola! "); } void main () { mensagem(); printf ("Eu estou vivo!\n"); } Argumentos Argumentos so as entradas que a funo recebe. atravs dos argumentos que passamos parmetros para a funo. Exemplo1: printf() e scanf() so funes que tm argumentos.

#include <stdio.h> void square (int x) { printf ("O quadrado e %d",(x*x)); } void main () { int num; printf ("Entre com um numero: "); scanf ("%d", &num);

Linguagens C e C++: Uma introduo sintaxe Pg. 4 printf ("\n\n"); square(num); } Passagem de parmetro por valor cpia de argumentos; Funes com mltiplos argumentos: exemplo #include <stdio.h> void mult (float a, float b, float c) { printf ("%f", a*b*c); } void main () { float x, y; x=23.5; y=12.9; mult (x, y, 3.87); } Retornando valores As funes que vimos at agora no retornam nenhum valor (void); O retorno default de uma funo um inteiro. Porm, no se deve utilizar o valor de retorno default. Deve-se sempre especificar o tipo de retorno da funo, mesmo que seja um retorno vazio (void); Para retornar um valor, usamos a palavra reservada return. #include <stdio.h> int prod (int x, int y) { return (x*y); } void main () { int saida;

Linguagens C e C++: Uma introduo sintaxe Pg. 5 saida = prod (12,7); printf ("A saida e: %d\n", saida); } O mesmo exemplo para multiplicao de floats: #include <stdio.h> float prod (float x, float y) { return (x*y); } void main () { float saida; saida = prod (45.2,0.0067); printf ("A saida e: %f\n",saida); } Forma geral das funes tipo_de_retorno nome_funo (lista_de_argumentos) { cdigo_da_funo } Exerccio: Escreva uma funo que some dois inteiros e retorne o valor da soma.

1.3. Introduo aos tipos de dados e s entradas e sadas

Os caracteres so um tipo de dado: o char. O C trata os caracteres como sendo variveis de um byte (8 bits). Podemos usar um char para armazenar tanto valores numricos inteiros de 0 a 255 quanto um caractere de texto

Linguagens C e C++: Uma introduo sintaxe Pg. 6 Os inteiros(ints) tm tem um nmero maior de bytes. Dependendo da implementao do compilador, eles podem ter 2 bytes (16 bits) ou 4 bytes (32 bits).

#include <stdio.h> void main () { char Ch; Ch='D'; printf ("%c",Ch); } Para entrada de caracteres, podemos usar as funes getch() e getche() (se o nosso compilador tiver a biblioteca conio) ou o scanf(): #include <stdio.h> #include <conio.h> void main () { char Ch; Ch=getch(); printf ("Voce pressionou a tecla %c",Ch); } #include <stdio.h> void main () { char Ch; scanf("%c", &Ch); printf ("Voce pressionou a tecla %c",Ch); } No C uma string um vetor de caracteres terminado com um caractere nulo. O caracter nulo um caractere com valor igual a zero. O terminador nulo pode ser escrito usando a conveno de barra invertida do C como sendo '\0'. Declarao de strings:

Linguagens C e C++: Uma introduo sintaxe Pg. 7 char nome_da_string[tamanho_da_string]; Como temos que reservar um caractere para ser o terminador nulo, temos que declarar o comprimento da string como sendo, no mnimo, um caractere maior que a maior string que pretendemos armazenar. Declarao e inicializao de strings: char nome[] = Renato; R e n a t o \0

Para ler uma string fornecida pelo usurio podemos usar a funo gets(). A funo gets() coloca o terminador nulo na string, quando voc aperta a tecla "Enter". #include <stdio.h> main () { char string[100]; printf ("Digite uma string: "); gets (string); printf ("\n\nVoce digitou %s",string); } As strings so vetores de caracteres. Para se acessar um determinado caracter de uma string, basta "indexarmos a string. Deve-se notar que os vetores no C tem seus ndices comeando em 0! #include <stdio.h> main() { char str[ ] = "Joao"; printf("\n\nString: %s", str); printf("\nSegunda letra: %c", str[1]); str[1] = 'U'; printf("\nAgora a segunda letra eh: %c", str[1]); printf("\n\nString resultante: %s", str); } O float um tipo para armazenar variveis em ponto flutuante. O double o tipo ponto flutuante duplo e pode ser visto como um float com muito mais preciso

Linguagens C e C++: Uma introduo sintaxe Pg. 8 Para cada um dos tipos de variveis (char, int, float, double) existem os modificadores de tipo: signed, unsigned, long e short. Ao float no se pode aplicar nenhum e ao double pode-se aplicar apenas o long. Os quatro podem ser aplicados a inteiros. A inteno que short e long devam prover tamanhos diferentes de inteiros onde isto for prtico. int normalmente ter o tamanho natural para uma determinada mquina. Assim, numa mquina de 16 bits, int provavelmente ter 16 bits. Numa mquina de 32, int dever ter 32 bits. Na verdade, cada compilador livre para escolher tamanhos adequados para o seu prprio hardware, com a nica restrio de que shorts e ints devem ocupar pelo menos 16 bits, longs pelo menos 32 bits, e short no pode ser maior que int, que no pode ser maior que long. Para um compilador tpico de 16 bits, teramos: Intervalo Num de bits Inicio Fim char 8 -128 127 unsigned char 8 0 255 signed char 8 -128 127 int 16 -32.768 32.767 unsigned int 16 0 65.535 signed int 16 -32.768 32.767 short int 16 -32.768 32.767 unsigned short int 16 0 65.535 signed short int 16 -32.768 32.767 long int 32 -2.147.483.648 2.147.483.647 signed long int 32 -2.147.483.648 2.147.483.647 unsigned long int 32 0 4.294.967.295 float 32 3,4E-38 3.4E+38 double 64 1,7E-308 1,7E+308 long double 80 3,4E-4932 3,4E+4932 O tipo long double o tipo de ponto flutuante com maior preciso. importante observar que os intervalos de ponto flutuante, na tabela acima, esto indicados em faixa de expoente, mas os nmeros podem assumir valores tanto positivos quanto negativos. Tipo

Linguagens C e C++: Uma introduo sintaxe Pg. 9 A funo printf printf (string_de_controle, lista_de_argumentos); Cdigo Significado %d %i %f %e %E %g %G %o %s %u %x %X %p %c %% Inteiro (decimal) O mesmo que %d Ponto flutuante decimal Nmero em notao cientfica com o "e" minsculo Nmero em notao cientfica com o "e" maisculo Escolhe automaticamente o melhor entre %f e %e Escolhe automaticamente o melhor entre %f e %E Nmero octal String Inteiro "unsigned" (sem sinal) Hexadecimal com letras minsculas Hexadecimal com letras maisculas Ponteiro Caractere Coloca na tela um %

Exemplos: printf ("Teste %% %%"); -> Teste % % printf ("%f",40.345); -> 40.345 printf ("Um caractere %c e um inteiro %d",'D',120); -> Um caractere D e um inteiro 120 printf ("%s e um exemplo","Este"); -> Este e um exemplo printf ("%s%d%%","Juros de ",10) -> Juros de 10%

Linguagens C e C++: Uma introduo sintaxe Pg. 10 printf ("%X %f %e",107,49.67,49.67); -> 6B 49.67 4.967e1 printf ("%d %o",10,10); -> 10 12 char x = 65 printf(X como inteiro = %d \n X como caracter = %c, x, x) X como inteiro = 65 X como caracter = A possvel tambm indicar o tamanho do campo, justificao e o nmero de casas decimais. Para isto usa-se cdigos colocados entre o % e a letra que indica o tipo de formato. Exemplos: %5d o campo ter cinco caracteres de comprimento no mnimo. Se o inteiro precisar de mais de cinco caracteres para ser exibido ento o campo ter o comprimento necessrio para exibi-lo. Se o comprimento do inteiro for menor que cinco ento o campo ter cinco de comprimento e ser preenchido com espaos em branco. Se se quiser um preenchimento com zeros pode-se colocar um zero antes do nmero. %05d reservar cinco casas para o nmero e se este for menor ento se far o preenchimento com zeros. O alinhamento padro direita. Para se alinhar um nmero esquerda usa-se um sinal - antes do nmero de casas. Ento %-5d ser o nosso inteiro com o nmero mnimo de cinco casas, s que justificado a esquerda. Ponto flutuante: %10.4f indica um ponto flutuante de comprimento mnimo de dez casas (incluindo o ponto decimal) e com 4 casas decimais. Entretanto, esta mesma notao, quando aplicada a tipos como inteiros e strings indica o nmero mnimo e mximo de casas. Ento %5.8d um inteiro com comprimento mnimo de cinco e mximo de oito.

printf ("%5.2f",456.671); printf ("%5.2f",2.671);

|456.67| | 2.67|

A funo scanf

Linguagens C e C++: Uma introduo sintaxe Pg. 11 scanf (string-de-controle, lista-de-argumentos); Importante lembrarmos de colocar o & antes das variveis da lista de argumentos. impossvel justificar isto agora, mas veremos depois a razo para este procedimento Os caracteres de converso d, i, u e x podem ser precedidos por h para indicarem que um short ao invs de int aparece na lista de argumento, ou pela letra l (letra ele) para indicar que que um long aparece na lista de argumento. Semelhantemente, os caracteres de converso e, f e g podem ser precedidos por l para indicarem que um double ao invs de float est na lista de argumento. Exerccio: Escreva um programa que leia duas strings e as coloque na tela. Imprima tambm a segunda letra de cada string. 1.4. Introduo ao controle de fluxo if: O comando if representa uma tomada de deciso do tipo "SE isto ENTO aquilo". if (condio) declarao; A condio do comando if uma expresso que ser avaliada. Se o resultado for zero a declarao no ser executada. Se o resultado for qualquer coisa diferente de zero a declarao ser executada. A declarao pode ser um bloco de cdigo ou apenas um comando. #include <stdio.h void main () { int num; printf ("Digite um numero: "); scanf ("%d",&num); if (num > 10) printf ("\n\nO numero e maior que 10"); if (num == 10) { printf ("\n\nVoce acertou!\n"); printf ("O numero e igual a 10."); } if (num < 10) printf ("\n\nO numero e menor que 10");

Linguagens C e C++: Uma introduo sintaxe Pg. 12 } A expresso num > 10 avaliada e retorna um valor diferente de zero, se verdadeira, e zero, se falsa. Quando queremos testar igualdades usamos o operador == e no =. O operador = representa apenas uma atribuio. Se escrevssemos if (num=10) ... /* Isto esta errado */ o compilador iria atribuir o valor 10 varivel num e a expresso num=10 iria retornar 10, fazendo com que o nosso valor de num fosse adulterado e fazendo com que a declarao fosse executada sempre. Os operadores de comparao so: ==, >, >=, <, <=. for for usado para repetir um comando, ou bloco de comandos, diversas vezes, de maneira que se possa ter um bom controle sobre o loop. for (inicializao; condio; incremento) declarao; O loop for equivalente a se fazer o seguinte: inicializao; if (condio) { declarao; incremento; "Volte para o comando if" } Ele fica repetindo estas operaes at que a condio seja falsa. #include <stdio.h> void main () { int count; for (count=1; count<=100; count=count+1) printf ("%d ",count); } Exerccio: (a) Explique porque est errado fazer if (num=10); (b) Escreva um programa que coloque os nmeros de 1 a 100 na tela na ordem inversa (comeando em 100 e terminando em 1).

Linguagens C e C++: Uma introduo sintaxe Pg. 13

1.5. Variveis, Constantes, Operadores e Expresses 1.5.1. Variveis As variveis no C devem ser declaradas antes de serem usadas. A forma geral da declarao de variveis : tipo_da_varivel lista_de_variveis; As variveis no C podem ter qualquer nome se duas condies forem satisfeitas: o nome deve comear com uma letra ou sublinhado (_) e os caracteres subsequentes devem ser letras, nmeros ou sublinhado (_). Restries: o nome de uma varivel no pode ser igual a uma palavra reservada, nem igual ao nome de uma funo declarada pelo programador, ou pelas bibliotecas do C. O C "case sensitive" e portanto deve-se prestar ateno s maisculas e minsculas. Quando vamos declarar variveis int com algum dos modificadores de tipo, basta colocar o nome do modificador de tipo. Assim um long basta para declarar um long int. char ch, letra; long count; float pi; H trs lugares nos quais podemos declarar variveis em C: 1- Fora de todas as funes do programa: Estas variveis so chamadas variveis globais e podem ser usadas a partir de qualquer lugar no programa. 2- No incio de um bloco de cdigo. Estas variveis so chamadas locais e s tm validade dentro do bloco no qual so declaradas. 3- Na lista de parmetros de uma funo. Mais uma vez, apesar de estas variveis receberem valores externos, estas variveis so conhecidas apenas pela funo onde so declaradas.

Linguagens C e C++: Uma introduo sintaxe Pg. 14

As regras que regem onde uma varivel vlida chamam-se regras de escopo da varivel. Duas variveis globais no podem ter o mesmo nome. O mesmo vale para duas variveis locais de uma mesma funo. J duas variveis locais, de funes diferentes, podem ter o mesmo nome sem perigo algum de conflito. int contador; /* escopo: global */

void teste(int i, int j) { char condicao; /* escopo: funcao teste */ .... } void main ( ) { int x, i; /* escopo: main */ ... for (i = 0 ; i < 10; i = i +1 ) { int z; /* escopo: o bloco do for */ teste(z , i); ... } ... } Quando o C cria uma varivel ele no a inicializa. Porm, podemos inicializar variveis no momento de sua declarao: tipo_da_varivel nome_da_varivel = constante; char ch='D'; int count=0; float pi=3.141; INOVAO C++: No C++ pode-se declarar uma varivel em qualquer ponto de um programa, inclusive entre instrues, ou mesmo dentro delas. Exemplo:

Linguagens C e C++: Uma introduo sintaxe Pg. 15 int x; // Primeira declarao x = x+1; float f; // Declarao feita aps uma instruo for (int i = 0; i < 20; i = i + 1) { ...... } // Declarao de i dentro do for Exerccio: Estude o programa e indique o valor das variveis sempre que solicitado: #include <stdio.h> int num; int func(int a, int b) { a = (a+b)/2; /* Qual e o valor de a apos a atribuicao? */ num = num - a; return a; } void main() { int first = 0, sec = 50; num = 10; num = num + func(first, sec); /* Qual e o valor de num, first e sec antes e depois da chamada de func ? */ printf("\n\nConfira! num = %d\tfirst = %d\tsec = %d",num, first, sec); }

1.5.2. Constantes Constantes so valores que so mantidos fixos pelo compilador. So consideradas constantes, por exemplo, os nmeros e caracteres como 45.65 ou 'n', etc... Constantes dos tipos bsicos Tipo de Dado char int long int Exemplos de Constantes 'b' '\n' '\0' 2 32000 -130 100000 -467

Linguagens C e C++: Uma introduo sintaxe Pg. 16 short int unsigned int float double 100 -30 50000 35678 0.0 23.7 -12.3e-10 12546354334.0 -0.0000034236556

Constantes hexadecimais e octais As constantes hexadecimais comeam com 0x. As constantes octais comeam em 0. Constante Tipo 0xEF Hexadecimal 0x12A4 Hexadecimal 03212 Octal 034215432 Octal Nunca escreva portanto 013 achando que o C vai compilar isto como se fosse 13. Na linguagem C, 013 diferente de 13! Constantes strings Uma string "Joao" na realidade uma constante string. Isto implica, por exemplo, no fato de que 't' diferente de "t", pois 't' um char enquanto que "t" um vetor de dois chars onde o primeiro 't' e o segundo '\0'. Constantes de barra invertida Estes so caracteres que podem ser usados como qualquer outro, especialmente formatar a sada. A lista completa dos cdigos de barra invertida dada a seguir: Cdigo \b \f \n \r \t \" \' \0 \\ \v \a Significado Retrocesso ("back") Alimentao de formulrio ("form feed") Nova linha ("new line") Retorno de carro ("carriage return") Tabulao horizontal ("tab") Aspas Apstrofo Nulo (0 em decimal) Barra invertida Tabulao vertical Sinal sonoro ("beep")

Linguagens C e C++: Uma introduo sintaxe Pg. 17 \N \xN Constante octal (N o valor da constante) Constante hexadecimal (N o valor da constante)

Atravs de diretivas de pr-processamento, podem ser definidas constantes. #define PI 3.141519 .... ang_rad = (2*PI/360)*ang_graus; O #define uma instruo anterior compilao que solicita ao compilador a troca do texto PI no programa pela string 3.141519. INOVAO C++ const float PI = 3.1415; // OBS: esta inovao foi absorvida pelo ANSIC 1.5.2. Operadores Aritmticos e de Atribuio Operadores aritmticos Ao Operador + Soma (inteira e ponto flutuante) Subtrao ou Troca de sinal (inteira e ponto flutuante) * Multiplicao (inteira e ponto flutuante) / Diviso (inteira e ponto flutuante) % Resto de diviso (de inteiros) ++ Incremento (inteiro e ponto flutuante) -Decremento (inteiro e ponto flutuante) Operadores unrios agem sobre uma varivel apenas, modificando ou no o seu valor, e retornam o valor final da varivel. Operadores binrios usam duas variveis e retornam um terceiro valor, sem alterar as variveis originais. Os operadores de incremento e decremento so unrios que alteram a varivel sobre a qual esto aplicados. Estes operadores podem ser pr-fixados ou ps- fixados. A diferena que quando so prfixados eles incrementam e retornam o valor da varivel j incrementada. Quando so ps-fixados eles retornam o valor da varivel sem o incremento e depois incrementam a varivel.

Linguagens C e C++: Uma introduo sintaxe Pg. 18 x=23; y=x++; /* no final teremos y = 23 e x = 24 */ x=23; y=++x; /* no final, teremos y=24 e x=24 */ Curiosidade: Nome da linguagem de programao C++ ; O operador de atribuio do C o =. O que ele faz pegar o valor direita e atribuir varivel da esquerda. Alm disto ele retorna o valor que ele atribuiu. Assim, as seguintes expresses so vlidas: x = y = z = 1.5; if (k=w) /* A expresso ser verdadeira para w diferente de zero */ Exerccio: Diga o resultado das variveis x, y e z depois da seguinte sequncia de operaes: int x,y,z; x=y=10; z=++x; x=-x; y++; x=x+y-(z--); 1.5.3. Operadores Relacionais e Lgicos Operadores Relacionais Operador Ao > Maior do que >= Maior ou igual a < Menor do que <= Menor ou igual a == Igual a != Diferente de Os operadores relacionais retornam verdadeiro (1) ou falso (0). Para fazer operaes com valores lgicos (verdadeiro e falso) temos os operadores lgicos: Operador Ao && AND (E) || OR (OU)

Linguagens C e C++: Uma introduo sintaxe Pg. 19 ! NOT (NO)

A tabela-verdade destes operadores dada a seguir: p q p AND q p OR q falso falso falso falso falso verdadeiro falso verdadeiro verdadeiro falso falso verdadeiro verdadeiro verdadeiro verdadeiro verdadeiro Operadores Lgicos Bit a Bit C permite que se faa operaes lgicas "bit-a- bit" em nmeros. Esta caracterstica ajuda programadores que queiram trabalhar com o computador em "baixo nvel". As operaes lgicas s podem ser usadas nos tipos char, int e long int. Operador Ao & AND | OR ^ XOR (OU exclusivo) ~ NOT >> Deslocamento de bits a direita << Deslocamento de bits a esquerda A forma geral dos operadores de deslocamento : valor>>nmero_de_deslocamentos valor<<nmero_de_deslocamentos O nmero_de_deslocamentos indica o quanto cada bit ir ser deslocado. Exerccio: Diga se as seguintes expresses sero verdadeiras ou falsas: ((10 > 5) || (5 > 10)); (!(5==6) && (5 != 6) && ((2 > 1) || (5 <= 4))); 1.5.4. Expresses Expresses so combinaes de variveis, constantes e operadores. Anos=Dias/365.25; i = i+3; c= a*b + d/e; c= a*(b+d)/e;

Linguagens C e C++: Uma introduo sintaxe Pg. 20 Converso de tipos em expresses Quando o C avalia expresses onde temos variveis de tipos diferentes o compilador verifica se as converses so possveis. Se no so, ele no compilar o programa, dando uma mensagem de erro. Se as converses forem possveis ele as faz, seguindo as regras: 1. Todos os chars e short ints so convertidos para ints. Todos os floats so convertidos para doubles. 2. Para pares de operandos de tipos diferentes: se um deles long double o outro convertido para long double; se um deles double o outro convertido para double; se um long o outro convertido para long; se um unsigned o outro convertido para unsigned. Exemplo: float a=10., b; double c, d=30.; c = d*a; b = c+d+a; Expresses que Podem ser Abreviadas Expresso Original x = x+k; x = x-k; x = x*k; x = x/k; x = x>>k; x = x<<k; x = x&k; etc... Expresso Equivalente x += k; x -= k ; x *= k; x /= k; x >>= k; x <<= k; x &= k;

Encadeando expresses: o operador , O operador , determina uma lista de expresses que devem ser executadas sequencialmente. O valor retornado por uma expresso com o operador , sempre dado pela expresso mais direita. x=(a = 2 , a+3); /* a varivel x receber o valor 5 */

Linguagens C e C++: Uma introduo sintaxe Pg. 21 Pode-se encadear quantos operadores , forem necessrios.

Linguagens C e C++: Uma introduo sintaxe Pg. 22 Tabela de Precedncias do C Esta a tabela de precedncia dos operadores em C. Maior () [] -> ! ~ ++ -- . -(unrio) (cast) *(unrio) &(unrio) sizeof */% +<< >> <<= >>= == != & ^ | && || ? = += -= *= /= Menor ,

Modeladores (Casts) Um modelador fora uma expresso a ser de um tipo especificado. (tipo)expresso; #include <stdio.h> void main () { int num; float f; num=10; f=(float)num/7; printf ("%f",f); } Se no tivssemos usado o modelador no exemplo acima o C faria uma diviso inteira entre 10 e 7. Com o modelador temos o resultado correto.

Linguagens C e C++: Uma introduo sintaxe Pg. 23 1.6. Estruturas de Controle de Fluxo. 1.6.1. O Comando if if (condio) declarao; O else if (condio) declarao_1; else declarao_2; #include <stdio.h> void main () { int num; printf ("Digite um numero: "); scanf ("%d",&num); if (num==10) { printf ("\n\nVoce acertou!\n"); printf ("O numero e igual a 10.\n"); } else { printf ("\n\nVoce errou!\n"); printf ("O numero e diferente de 10.\n"); } } O if-else-if if (condio_1) declarao_1; else if (condio_2) declarao_2; else if (condio_3) declarao_3; . . . else if (condio_n) declarao_n; else declarao_default; O programa comea a testar as condies, comeando pela 1, e continua a testar at que ele ache uma expresso cujo resultado d

Linguagens C e C++: Uma introduo sintaxe Pg. 24 diferente de zero. Neste caso ele executa a declarao correspondente. S uma declarao ser executada, ou seja, s ser executada a declarao equivalente primeira condio que der diferente de zero. A ltima declarao (default) a que ser executada no caso de todas as condies darem zero e opcional. #include <stdio.h> void main () { int num; printf ("Digite um numero: "); scanf ("%d", &num); if (num > 10) printf ("\n\nO numero e maior que 10"); else if (num==10) { printf ("\n\nVoce acertou!\n"); printf ("O numero e igual a 10."); } else if (num<10) printf ("\n\nO numero e menor que 10"); } A expresso condicional Quando o compilador avalia uma condio, ele quer um valor de retorno para poder tomar a deciso. Mas esta expresso no necessita ser uma expresso no sentido convencional. Uma varivel sozinha pode ser uma "expresso" e esta retorna o seu prprio valor. Isto quer dizer que teremos as seguintes equivalncias: int num; if (num!=0) .... if (num==0) .... equivale a int num; if (num) .... if (!num) ....

Linguagens C e C++: Uma introduo sintaxe Pg. 25 ifs aninhados O if aninhado simplesmente um if dentro da declarao de um outro if externo. #include <stdio.h> void main () { int num; printf ("Digite um numero: "); scanf ("%d", &num); if (num==10) { printf ("\n\nVoce acertou!\n"); printf ("O numero e igual a 10.\n"); } else { if (num > 10) { printf ("O numero e maior que 10."); } else { printf ("O numero e menor que 10."); } } } O Operador ? De uma maneira geral expresses do tipo: if (condio) expresso_1; else expresso_2; podem ser substitudas por: condio ? expresso_1 : expresso_2; Uma expresso como: if (a>0)

Linguagens C e C++: Uma introduo sintaxe Pg. 26 b=-150; else b=150; pode ser simplificada para: b = a>0 ? 150 : 150; #include <stdio.h> void main() { int index = 0, contador; char letras[5] = "Joao"; for (contador=0 ; contador<1000 ; contador++) { printf("\n%c",letras[index]); index = (index == 4)? index=0: ++index; } } Exerccio: Altere o ltimo exemplo para que ele escreva cada letra 5 vezes seguidas. Para isto, use um 'if' para testar se o contador divisvel por cinco (utilize o operador %) e s ento realizar a atualizao em index.

1.6.2. O Comando switch O comando switch prprio para se testar uma varivel em relao a diversos valores pr-estabelecidos. switch (varivel) { case constante_1: declarao_1; break; case constante_2: declarao_2; break;

Linguagens C e C++: Uma introduo sintaxe Pg. 27 case constante_n: declarao_n; break; default: declarao_default; } A estrutura switch no aceita expresses. Aceita apenas constantes. O switch testa a varivel e executa a declarao cujo case corresponda ao valor atual da varivel. A declarao default opcional e ser executada apenas se a varivel, que est sendo testada, no for igual a nenhuma das constantes. O comando break, faz com que o switch seja interrompido assim que uma das declaraes seja executada. Mas ele no essencial ao comando switch. Se aps a execuo da declarao no houver um break, o switch continuar executando. #include <stdio.h> void main () { int num; printf ("Digite um numero: "); scanf ("%d", &num); switch (num) { case 9: printf ("\n\nO numero e igual a 9.\n"); break; case 10: printf ("\n\nO numero e igual a 10.\n"); break; case 11: printf ("\n\nO numero e igual a 11.\n"); break; default: printf ("\n\nO numero nao e nem 9 nem 10 nem 11.\n"); } } Exerccio: Escreva um programa utilizando o comando switch que leia uma string (use gets()) e substitua todos os espaos ( ) e tabulaes ('\t') na string por caracteres de nova linha (\n). O loop deve encerrar-se quando encontrar o caracter de final de string ('\0').

Linguagens C e C++: Uma introduo sintaxe Pg. 28 1.6.3. O Comando for for (inicializao ; condio ; incremento) declarao; Um ponto importante que podemos omitir qualquer um dos elementos do for, isto , se no quisermos uma inicializao poderemos omiti-la. #include <stdio.h> void main () { int count; for (count=1; count<=100; count++) printf ("%d ",count); } O loop infinito for (;;) declarao; Para interromper um loop como este usamos o comando break. O comando break vai quebrar o loop infinito e o programa continuar sua execuo normalmente. #include <stdio.h> void main () { int Count; for (Count=1 ; ; Count++) { printf("\nCount: %i\n", Count); if (Count > 500) break; } } O loop sem contedo Loop sem contedo aquele no qual se omite a declarao. Sua forma geral portanto (ateno ao ponto e vrgula!): for (inicializao ; condio ; incremento); Uma das aplicaes desta estrutura gerar tempos de espera. #include <stdio.h>

Linguagens C e C++: Uma introduo sintaxe Pg. 29 void main () { long int i; printf("\a"); /* Imprime o caracter de alerta (um beep) */ for (i=0; i<10000000; i++); /* Espera 10.000.000 de iteracoes */ printf("\a"); /* Imprime outro caracter de alerta */ } Exerccio: Faa um programa que inverta uma string armazenandoa em outra string. Use o comando for para varrer a string at o seu final. Para saber o tamanho da string, voc pode usar a funo strlen(str), que retorna o nmero de caracteres contidos na string str. Para usar a funo, voc deve usar o #include <string.h>. Lembre-se que a string sempre termina com o caracter '\0'. 1.6.4. O Comando while e o do while while (condio) declarao; Equivalente: if (condio) { declarao; "Volte para o comando if" } #include <conio.h> void main () { char Ch = '\0'; while (Ch!='q') { Ch = getche(); } } Exerccio: Refaa o programa do exerccio anterior. Use o comando while para fechar o loop. O comando do-while: do {

Linguagens C e C++: Uma introduo sintaxe Pg. 30 declarao; } while (condio); equivalente a: declarao; if (condio) "Volta para a declarao"

O Comando continue comando continue pode ser visto como sendo o oposto do break. Ele s funciona dentro de um loop. Quando o comando continue encontrado, o loop pula para a prxima iterao. #include <stdio.h> void main() { int opcao = 0; do { printf("\n\n Escolha uma opcao entre 1 e 5: "); scanf("%d", &opcao); if ((opcao > 5)||(opcao < 1)) continue; /* Opcao invalida: vai ao fim do loop */ switch (opcao) { case 1: printf("\n -- Primeira opcao.."); break; case 2: printf("\n -- Segunda opcao.."); break; case 3: printf("\n -- Terceira opcao.."); break; case 4: printf("\n -- Quarta opcao.."); break; case 5: printf("\n -- Abandonando.."); break; } } while (opcao != 5);

Linguagens C e C++: Uma introduo sintaxe Pg. 31 }

1.7. Matrizes e strings Vetores Vetores nada mais so que matrizes unidimensionais. Para se declarar um vetor podemos utilizar a seguinte forma geral: tipo_da_varivel nome_da_varivel [tamanho]; float vet[20]; Na linguagem C a numerao dos vetores comea sempre em zero. Isto significa que, no exemplo acima, os dados sero indexados de 0 a 19. Para acess-los s escrever a posio correspondente: vet[5] = 3.; vet[0] = 8.; Ningum o impede de escrever: vet[30] = 40.; O C no verifica se o ndice que voc usou est dentro dos limites vlidos. Este um cuidado que voc deve tomar. Se o programador no tiver ateno com os limites de validade para os ndices ele corre o risco de escrever em regies reservadas para outras variveis ou de ver o computador travar. Bugs terrveis podem surgir. #include <stdio.h> void main () { int num[100]; /* Declara um vetor de inteiros de 100 posicoes */ int count=0; int totalnums; do { printf ("\nEntre com um numero (-999 p/ terminar): "); scanf ("%d",&num[count]); } while (num[count++]!=-999); totalnums=count-1; printf ("\n\n\n\t Os nmeros que voc digitou foram:\n\n"); for (count=0 ; count<totalnums ; count++) {

Linguagens C e C++: Uma introduo sintaxe Pg. 32 printf (" %d", num[count]); } } bom lembrar aqui que nenhuma restrio feita quanto a quantidade de nmeros digitados. Se o usurio digitar mais de 100 nmeros, o programa tentar ler normalmente, mas o programa os escrever em uma parte no alocada de memria, pois o espao alocado foi para somente 100 inteiros! Exerccio: Reescreva o exemplo acima, realizando a cada leitura um teste para ver se a dimenso do vetor nao foi ultrapassada. Caso o usurio entre com 100 nmeros, o programa dever abortar o loop de leitura automaticamente. O uso do Flag no deve ser retirado.

Strings Strings so vetores de chars; Devemos lembrar que o tamanho da string deve incluir o '\0' final. A biblioteca do C possui diversas funes que manipulam strings. Estas funes so teis pois no se pode, por exemplo, igualar duas strings: string1=string2; /* NAO faca isto */ Fazer isto um desastre. Quando estudarmos ponteiros entenderemos por que. #include <stdio.h> void main () { int count; char str1[100],str2[100]; .... /* Aqui o programa le str1 que sera copiada para str2 */ for (count=0 ; str1[count] ; count++) { str2[count]=str1[count]; } str2[count]='\0'; .... /* Aqui o programa continua */ }

Linguagens C e C++: Uma introduo sintaxe Pg. 33

Funes para manipulao de strings <string.h>: strcpy strcpy (string_destino,string_origem); #include <stdio.h> #include <string.h> void main () { char str1[100],str2[100],str3[100]; printf ("Entre com uma string: "); gets (str1); strcpy (str2,str1); strcpy (str3,"Voce digitou a string "); printf ("\n\n%s%s",str3,str2); } strcat A funo strcat() tem a seguinte forma geral: strcat (string_destino,string_origem); A string de origem permanecer inalterada e ser anexada ao fim da string de destino. #include <stdio.h> #include <string.h> void main () { char str1[100],str2[100]; printf ("Entre com uma string: "); gets (str1); strcpy (str2,"Voce digitou a string "); strcat (str2,str1); printf ("\n\n%s",str2); } strlen Sua forma geral : strlen (string);

Linguagens C e C++: Uma introduo sintaxe Pg. 34 A funo strlen() retorna o comprimento da string fornecida. O terminador nulo no contado. #include <stdio.h> #include <string.h> void main () { int size; char str[100]; printf ("Entre com uma string: "); gets (str); size=strlen (str); printf ("\n\nA string que voce digitou tem tamanho %d",size); } strcmp strcmp (string1,string2); A funo strcmp() compara a string 1 com a string 2. Se as duas forem idnticas a funo retorna zero. Se elas forem diferentes a funo retorna no-zero. #include <stdio.h> #include <string.h> void main () { char str1[100],str2[100]; printf ("Entre com uma string: "); gets (str1); printf ("\n\nEntre com outra string: "); gets (str2); if (strcmp(str1,str2)) printf ("\n\nAs duas strings so diferentes."); else printf ("\n\nAs duas strings so iguais."); } Exerccio: Faa um programa que leia vrias palavras pelo teclado, e armazene cada palavra em uma string. Depois, concatene todas as strings lidas numa nica string. Por fim apresente esta como resultado ao final do programa.

Linguagens C e C++: Uma introduo sintaxe Pg. 35 Matrizes bidimensionais A forma geral da declarao de uma matriz bidimensional muito parecida com a declarao de um vetor: tipo_da_varivel nome_da_varivel [linhas][colunas]; Quando vamos preencher ou ler uma matriz no C o ndice mais direita varia mais rapidamente que o ndice esquerda #include <stdio.h> void main () { int mtrx [20][10]; int i,j,count; count=1; for (i=0;i<20;i++) for (j=0;j<10;j++) { mtrx[i][j]=count; count++; } } Matrizes de strings Matrizes de strings so matrizes bidimensionais. Imagine uma string. Ela um vetor. Se fizermos um vetor de strings estaremos fazendo uma lista de vetores. Esta estrutura uma matriz bidimensional de chars. Podemos ver a forma geral de uma matriz de strings como sendo: char nome_da_varivel [num_de_strings][compr_das_strings]; Como acessar uma string individual? nome_da_varivel [ndice] #include <stdio.h main () { char strings [5][100]; int count; for (count=0;count<5;count++) { printf ("\n\nDigite uma string: "); gets (strings[count]); }

Linguagens C e C++: Uma introduo sintaxe Pg. 36 printf ("\n\n\nAs strings que voce digitou foram:\n\n"); for (count=0;count<5;count++) { printf ("%s\n",strings[count]); } } Matrizes multidimensionais tipo_da_varivel nome_da_varivel [tam1][tam2] ... [tamN]; Inicializao Podemos inicializar matrizes, assim como podemos inicializar variveis tipo_da_varivel nome_da_varivel [tam1][tam2] ... [tamN] = {lista_de_valores};

float vect [6] = { 1.3, 4.5, 2.7, 4.1, 0.0, 100.1 } int matrx [3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; char str [10] = { 'J', 'o', 'a', 'o', '\0' }; char str [10] = "Joao"; char str_vect [3][10] = { "Joao", "Maria", "Jose" }; Inicializao sem especificao de tamanho Podemos, em alguns casos, inicializar matrizes das quais no sabemos o tamanho a priori. O compilador C vai, neste caso verificar o tamanho do que voc declarou e considerar como sendo o tamanho da matriz char mens [] = "Linguagem C: flexibilidade e poder."; int matrx [][2] = { 1,2,2,4,3,6,4,8,5,10 }; 1.8. Ponteiros e alocao dinmica de memria O que so os Ponteiros? Ponteiros so variveis que guardam endereos de memria Um ponteiro tambm tem tipo. No C quando declaramos ponteiros ns informamos ao compilador para que tipo de varivel vamos

Linguagens C e C++: Uma introduo sintaxe Pg. 37 apont-lo. Um ponteiro int aponta para um inteiro, isto , guarda o endereo de um inteiro. Declarando e Utilizando Ponteiros Para declarar um ponteiro temos a seguinte forma geral: tipo_do_ponteiro *nome_da_varivel; o asterisco (*) que faz o compilador saber que aquela varivel no vai guardar um valor mas sim um endereo para aquele tipo especificado int *pt; char *temp,*pt2; Os ponteiros acima no foram inicializados. Isto significa que eles apontam para um lugar indefinido. O ponteiro deve ser inicializado (apontado para algum lugar conhecido) antes de ser usado! Isto de suma importncia! Para atribuir um valor a um ponteiro recm-criado poderamos igual-lo a um valor de memria. Operador &: int count=10; int *pt; pt=&count; pt contm o endereo da varivel inteira count. Operador * (operador de indireo ou deferenciao): *pt =5; printf(Conteudo do endereo apontado por pt %d, *pt); printf(Valor de count %d, count); *pt equivalente ao prprio count ! #include <stdio.h> void main () { int num,valor; int *p; num=55; p=&num; /* Pega o endereco de num */ valor=*p; /* Valor e igualado a num de uma maneira indireta */ printf ("\n\n%d\n",valor); printf ("Endereco para onde o ponteiro aponta: %p\n",p); printf ("Valor da variavel apontada: %d\n",*p);

Linguagens C e C++: Uma introduo sintaxe Pg. 38 } #include <stdio.h> void main () { int num,*p; num = 55; p = &num; /* Pega o endereco de num */ printf ("\nValor inicial: %d\n",num); *p=100; /* Muda o valor de num de uma maneira indireta */ printf ("\nValor final: %d\n",num); } Aritmtica de ponteiros: 1- Igualar dois ponteiros: Se temos dois ponteiros p1 e p2 podemos igual-los fazendo p1=p2. Repare que estamos fazendo com que p1 aponte para o mesmo lugar que p2. Se quisermos que a varivel apontada por p1 tenha o mesmo contedo da varivel apontada por p2 devemos fazer *p1=*p2. 2- Incremento e o decremento: p = p+1; /* p passa a apontar para o prximo endereo do mesmo tipo */ p++; Esta mais uma razo pela qual o compilador precisa saber o tipo de um ponteiro: se voc incrementa um ponteiro float ele anda 4 bytes na memria e se voc incrementa um ponteiro double ele anda 8 bytes na memria. Estamos falando de operaes com ponteiros e no de operaes com o contedo das variveis para as quais eles apontam. Para incrementar o contedo da varivel apontada pelo ponteiro p: (*p)++; p = p+15; /* p passa a apontar para 15 posies do tipo apontado adiante */ *(p+15); if( p1 == p2) { } if( p1 != p2) { } if(p1 < p2 ) { }

Linguagens C e C++: Uma introduo sintaxe Pg. 39 Operaes que voc no pode efetuar num ponteiro: dividir ou multiplicar ponteiros, adicionar dois ponteiros, adicionar ou subtrair floats ou doubles de ponteiros. Exerccio: (a) Explique a diferena entre p++; (*p)++; *(p++); (b)O que quer dizer *(p+10);? (c) Explique o que voc entendeu da comparao entre ponteiros Matrizes como ponteiros tipo_da_varivel nome_da_varivel [tam1][tam2] ... [tamN]; O compilador aloca tam1 x tam2 x tam3 x ... x tamN x tamanho_do_tipo bytes em um espao livre de memria. O nome da varivel que voc declarou na verdade um ponteiro constante para o tipo da varivel da matriz. Tendo alocado na memria o espao para a matriz, ele toma o nome da varivel (que um ponteiro constante) e aponta para o primeiro elemento da matriz. nome_da_varivel[ndice] absolutamente equivalente a se fazer: *(nome_da_varivel+ndice) porque no C a indexao comea com zero... *nome_da_varivel equivalente a nome_da_varivel[0] void main () { float matrx [50][50]; int i , j; for (i=0;i<50;i++) for (j=0;j<50;j++) matrx[i][j]=0.0; } void main () { float matrx [50][50], *p; int count; p = matrx[0]; for (count=0;count<2500;count++) { *p=0.0; p++; } }

int vetor[10]; int *ponteiro, i; ponteiro = &i; /* as operacoes a seguir sao invalidas */

Linguagens C e C++: Uma introduo sintaxe Pg. 40 vetor = vetor + 2; /* ERRADO: vetor e' constante*/ vetor++; /* ERRADO: vetor e' constante */ vetor = ponteiro; /* ERRADO: vetor e' constante */ Teste as operaes acima no seu compilador. Ele dar uma mensagem de erro. Alguns compiladores diro que vetor no um Lvalue. Lvalue, significa "Left value", um smbolo que pode ser colocado do lado esquerdo de uma expresso de atribuio, isto , uma varivel. Outros diro que tem-se "incompatible types in assignment", tipos incompatveis em uma atribuio. /* as operacoes abaixo sao validas */ ponteiro = vetor; /* CERTO: ponteiro e' variavel */ ponteiro = vetor+2; /* CERTO: ponteiro e' variavel */

Ponteiros como matrizes #include <stdio.h> void main () { int matrx [10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int *p; p=matrx; printf ("O terceiro elemento da matriz e: %d",p[2]); } Podemos ver que p[2] equivale a *(p+2). Strings Seguindo o raciocnio acima, nomes de strings, so do tipo char*. Isto nos permite escever a nossa funo StrCpy(), que funcionar aproximadamente como a funo strcpy() da biblioteca: #include <stdio.h> #include <string.h> void StrCpy (char *destino,char *origem) { while (*origem) { *destino=*origem; origem++;

Linguagens C e C++: Uma introduo sintaxe Pg. 41 destino++; } *destino='\0'; } void main () { char str1[100],str2[100],str3[100]; printf ("Entre com uma string: "); gets (str1); StrCpy (str2,str1); StrCpy (str3,"Voce digitou a string "); printf ("\n\n%s%s",str3,str2); } Observe que podemos passar ponteiros como argumentos de funes. Na verdade assim que funes como gets() e strcpy() funcionam. Passando o ponteiro voc possibilita funo alterar o contedo das strings. Quando fazemos origem++ e destino++ poderia-se argumentar que estamos alterando o valor do ponteiro-base da string. Mas no C, so passados para as funes cpias dos argumentos. Desta maneira, quando alteramos o ponteiro origem na funo StrCpy() o ponteiro str2 permanece inalterado na funo main(). Endereos de elementos de matrizes &nome_da_varivel[ndice] vlido e retorna o endereo do ponto da matriz indexado por ndice Matrizes de ponteiros int *pmatrx [10]; No caso acima, pmatrx um vetor que armazena 10 ponteiros para inteiros Exerccio: Seja a[] um vetor qualquer, independente de tipo e tamanho, e pa um ponteiro para o mesmo tipo de a[]. Responda V ou F, justificando as que forem falsas:

Linguagens C e C++: Uma introduo sintaxe Pg. 42 ( ) Qualquer expresso de vetor e ndice equivalente a uma outra expresso escrita com um apontador e um deslocamento ( ) Aps a atribuio pa=&a[0]; pa e a possuem valores idnticos ( ) A atribuio pa=&a[0]; pode ser escrita como pa=a; ( ) Uma referencia a a[i] pode ser escrita como *(a+i) ( ) &a[i] e a+i so idnticos ( ) a+i e' o endereo do i-simo elemento aps a ( ) pa[i] e' idntico a *(pa+i) ( ) pa=a e' uma operao valida ( ) pa++ e' uma operao valida ( ) a=pa e' uma operao valida ( ) a++ e' uma operao valida Inicializando Ponteiros Podemos inicializar ponteiros. Exemplos: char *strp= "String constante."; Qual a diferena para char strv [ ] = "Vetor de caracteres."; ?? Podemos tambm inicializar vetores de ponteiros: char *nome-ms[ ] = { "Ms-ilegal", "Janeiro", "Fevereiro", "Maro", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"} ; OBS: "Matriz" de caracteres onde cada linha tem comprimento varivel! Para zerar ponteiros, usamos a palavra reservada NULL. int *pti; pti = NULL; Ponteiros para Ponteiros Podemos declarar um ponteiro para um ponteiro com a seguinte notao: tipo_da_varivel **nome_da_varivel;

Linguagens C e C++: Uma introduo sintaxe Pg. 43

**nome_da_varivel o contedo final da varivel apontada; *nome_da_varivel o contedodo ponteiro intermedirio. No C podemos declarar ponteiros para ponteiros para ponteiros, ou ento, ponteiros para ponteiros para ponteiros para ponteiros e assim por diante. Cuidados a Serem Tomados ao se Usar Ponteiros O principal cuidado ao se usar um ponteiro deve ser: saiba sempre para onde o ponteiro est apontando. Isto inclui: nunca use um ponteiro que no foi inicializado void main () /* Errado - Nao Execute */ { int x,*p; x=13; p=x; /* Qual o endereo apontado por p?????? */ } Este programa compilar e rodar. O que acontecer? Ningum sabe. Alocao Dinmica A alocao dinmica permite ao programador alocar memria para variveis quando o programa est sendo executado. O padro C ANSI define apenas 4 funes para o sistema de alocao dinmica, disponveis na biblioteca stdlib.h. Como se organiza a memria? Sistema Operacional Cdigo do programa Dados (Var. globais e estticas) Heap (memria alocada dinamicam.) (memria livre) Pilha (variveis automticas)

Linguagens C e C++: Uma introduo sintaxe Pg. 44

malloc A funo malloc() serve para alocar memria (na rea de heap) void *malloc (unsigned int num); A funao toma o nmero de bytes que queremos alocar (num), aloca na memria e retorna um ponteiro void * para o primeiro byte alocado. O ponteiro void * pode ser atribudo a qualquer tipo de ponteiro. Se no houver memria suficiente para alocar a memria requisitada a funo malloc() retorna um ponteiro nulo. #include <stdio.h> #include <stdlib.h> void main ( ) { int *p; int a; printf(" Quantos inteiros quer alocar?: "); scanf("%d", &a); p=(int *)malloc(a*sizeof(int)); if (!p) { printf ("** Erro: Memoria Insuficiente **"); exit; } ... } calloc A funo calloc() tambm serve para alocar memria void *calloc (unsigned int num, unsigned int size); #include <stdio.h> #include <stdlib.h> void main (void) { int *p; int a;

Linguagens C e C++: Uma introduo sintaxe Pg. 45 printf(" Quantos inteiros quer alocar?: "); scanf("%d", &a); p=(int *)calloc(a, sizeof(int)); if (!p) { printf ("** Erro: Memoria Insuficiente **"); exit; } return 0; } realloc A funo realloc() serve para realocar memria: void *realloc (void *ptr, unsigned int num); A funao modifica o tamanho da memria previamente alocada apontada por *ptr para aquele especificado por num. O valor de num pode ser maior ou menor que o original. Um ponteiro para o bloco devolvido porque realloc() pode precisar mover o bloco para aumentar seu tamanho. Se isso ocorrer, o contedo do bloco antigo copiado no novo bloco, e nenhuma informao perdida. Se ptr for nulo, aloca num bytes e devolve um ponteiro; se num zero, a memria apontada por ptr liberada. Se no houver memria suficiente para a alocao, um ponteiro nulo devolvido e o bloco original deixado inalterado. free Quando alocamos memria dinamicamente necessrio que ns a liberemos quando ela no for mais necessria. void free (void *p); #include <stdio.h> #include <stdlib.h> void main ( ) { int *p; int a; printf(" Quantos inteiros quer alocar?: "); scanf("%d", &a);

Linguagens C e C++: Uma introduo sintaxe Pg. 46 p=(int *)malloc(a*sizeof(int)); if (!p) { printf ("** Erro: Memoria Insuficiente **"); exit; } ... .free(p); ... } Alocao Dinmica de Matrizes A alocao dinmica de memria para matrizes realizada da mesma forma que para vetores, com a diferena que teremos um ponteiro apontando para outro ponteiro que aponta para o valor final, o que denominado indireo mltipla. A estrutura de dados utilizada neste exemplo composta por um vetor de ponteiros (correspondendo ao primeiro ndice da matriz), sendo que cada ponteiro aponta para o incio de uma linha da matriz. Em cada linha existe um vetor alocado dinamicamente compondo o segundo ndice da matriz. #include <stdio.h> #include <stdlib.h> float **Alocar_matriz_real (int m, int n) { float **v; /* ponteiro para a matriz */ int i; /* variavel auxiliar */ if (m < 1 || n < 1) { /* verifica parametros recebidos */ printf ("** Erro: Parametro invalido **\n"); return (NULL); } /* aloca as linhas da matriz */ v = (float **) calloc (m, sizeof(float *)); if (v == NULL) { printf ("** Erro: Memoria Insuficiente **"); return (NULL); } /* aloca as colunas da matriz */ for ( i = 0; i <= m-1; i++ ) { v[i] = (float*) calloc (n, sizeof(float));

Linguagens C e C++: Uma introduo sintaxe Pg. 47 if (v[i] == NULL) { printf ("** Erro: Memoria Insuficiente **"); return (NULL); } } return (v); /* retorna o ponteiro para a matriz */ } float **Liberar_matriz_real (int m, int n, float **v) { int i; /* variavel auxiliar */ if (v == NULL) return (NULL); if (m < 1 || n < 1) { /* verifica parametros recebidos */ printf ("** Erro: Parametro invalido **\n"); return (v); } for (i=0; i<m; i++) free (v[i]); /* libera as linhas da matriz */ free (v); /* libera a matriz */ return (NULL); /* retorna um ponteiro nulo */ } void main (void) { float **mat; /* matriz a ser alocada */ int l, c; /* numero de linhas e colunas da matriz */ ... /* outros comandos, inclusive inicializacao para l e c */ mat = Alocar_matriz_real (l, c); ... /* outros comandos utilizando mat[][] normalmente */ mat = Liberar_matriz_real (l, c, mat); ... } Ponteiros em C++ Ponteiros para void: void *a Em C++ pode-se acessar o contedo apontado por um ponteiro genrico somente aps ele ter sido formatado. Exemplo: * (* int) a . Ponteiros para const: const char * string = eu sou uma constante; Ponteiros const: char * const string= Meu ponteiro e uma constante;

Linguagens C e C++: Uma introduo sintaxe Pg. 48 Ponteiros const para const: const char * const string Todos somos consts. int i; // i is an int int * pi; // pi is a pointer to int (uninitialized) int *const cp= &i; // cp is a constant pointer to int const int ci = 7; // ci is a constant int const int * pci; // pci is a pointer to constant int const int * const cpc = &ci; // cpc is a constant pointer // to a constant int Operaes vlidas: i = ci; *cp = ci; // Assign const-int to int // Assign const-int to // object-pointed-at-by-a-const-pointer ++pci; // Increment a pointer-to-const pci = cpc; // Assign a const-pointer-to-a-const to a // pointer-to-const Operaes ilegais: ci = 0; // NO--cannot assign to a const-int ci--; // NO--cannot change a const-int *pci = 3; // NO--cannot assign to an object // pointed at by pointer-to-const cp = &ci; // NO--cannot assign to a const-pointer, // even if value would be unchanged cpc++; // NO--cannot change const-pointer pi = pci; // NO--if this assignment were allowed, // you would be able to assign to *pci // (a const value) by assigning to *pi. Alocao dinmica de memria em C++: Operador new: int * array = new int[100]; int * string = new char[11]; float * a = new float; ou new(float); float *pi = new float(3.1415); Deve-se tambm testar o resultado de new (NULL se for insucesso); Operador delete: desalocar a memria alocada pelo new: delete a; delete pi; delete [] array; delete [100] array; delete [ ] string; delete [11] string;

Linguagens C e C++: Uma introduo sintaxe Pg. 49 OBS: Sempre desalocar o espao de memria alocado para uma varivel, quando ela no for mais utilizada. Em programas C++ usar a dupla new <-> delete. Em C, malloc <-> free! Exemplo: float **matriz; int nrow, ncol, i; /* Aloca a matriz */ /* Aloca vetor de ponteiros, que apontaro para o inicio de cada linha */ matriz = new *float [nrow]; if(!matriz) { printf(" Memria insuficiente! ); exit(0); } else { /* Aloca as linhas */ for(i=0 ; i <nrow; i++) { matriz[i]= new float[ncol]; if(!matriz[i]) { printf(" Memria insuficiente! ); exit(0); } } } ... /* Desaloca a matriz */ /* Desaloca as linhas */ for (i=0; i < nrow ; i++) delete [] matriz[i]; /* Desaloca o vetor de ponteiros */ delete [] matriz;

Linguagens C e C++: Uma introduo sintaxe Pg. 50 1.9. Funes Uma funo no C tem a seguinte forma geral: tipo_de_retorno nome_da_funo (declarao_de_parmetros) { corpo_da_funo } A declarao de parmetros uma lista com a seguinte forma geral: tipo nome1,tipo nome2, ... ,tipo nomeN O Comando return O comando return tem a seguinte forma geral: return valor_de_retorno; ou return; Quando se chega a uma declarao return a funo encerrada imediatamente e, se o valor de retorno informado, a funo retorna este valor. Uma funo pode ter mais de uma declarao return. #include <stdio.h> int EPar (int a) { if (a%2) /* Verifica se a e divisivel por dois */ return 0; else return 1; } void main () { int num; printf ("Entre com numero: "); scanf ("%d",&num); if (EPar(num)) printf ("\n\nO numero e par.\n"); else printf ("\n\nO numero e impar.\n"); }

Linguagens C e C++: Uma introduo sintaxe Pg. 51 Como as funes retornam valores, podemos aproveit-los para fazer atribuies Porm se uma funo retorna um valor voc no precisa aproveitar este valor. Se voc no fizer nada com o valor de retorno de uma funo ele ser descartado. Por exemplo, a funo printf() retorna um inteiro que ns nunca usamos para nada. Ele descartado. Exerccio: Escreva a funo 'EDivisivel(int a, int b)' (tome como base EPar(int a)). A funo dever retornar 1 se o resto da diviso de a por b for zero. Caso contrrio, a funo dever retornar zero. Prottipos de Funes Como o compilador sabe se uma determinada funo existe e quais so os seus parmetros? At agora, escrevemos as funes antes de suas chamadas! Mas, na maior parte das vezes, isto no acontece ... Como manter a coerncia? A soluo so os prottipos de funes. Prottipos so nada mais, nada menos, que declaraes de funes. Isto , voc declara uma funo que ir usar. O compilador toma ento conhecimento do formato daquela funo antes de compil-la. O cdigo correto ser ento gerado. Formato: tipo_de_retorno nome_da_funo (declarao_de_parmetros); onde o tipo-de-retorno, o nome-da-funo e a declarao-de-parmetros so os mesmos que voc pretende usar quando realmente escrever a funo. Repare que os prottipos tm uma ntida semelhana com as declaraes de variveis. #include <stdio.h> float Square (float a); void main () { float num; printf ("Entre com um numero: "); scanf ("%f",&num); num=Square(num); printf ("\n\nO seu quadrado vale: %f\n",num); } float Square (float a)

Linguagens C e C++: Uma introduo sintaxe Pg. 52 { return (a*a); } Usando prottipos o compilador evita erros, no deixando que o programador use funes com os parmetros errados e com o tipo de retorno errado, o que uma grande ajuda Arquivos-Cabealhos Arquivos-cabealhos so aqueles que temos mandado o compilador incluir no incio de nossos exemplos e que sempre terminam em .h. Eles s contm prottipos de funes. Voc tambm pode gerar seus arquivos cabealho. Arquivo funcao.h int EPar(int a); Arquivo funcao.c int EPar (int a) { if (a%2) return 0; else return 1; } Arquivo princip.c #include <stdio.h> #include "funcao.h" void main () { int num; printf ("Entre com numero: "); scanf ("%d", &num); if (EPar(num)) printf ("\n\nO numero e par.\n"); else printf ("\n\nO numero e impar.\n"); }

/* Verifica se a e divisivel por dois */

Linguagens C e C++: Uma introduo sintaxe Pg. 53 Este programa poderia ser compilado usando a seguinte linha de comando para o gcc: gcc princip.c funcao.c -o saida.exe Passagem de parmetros por Valor e por Referncia O default da linguagem C a passagem de parmetros por valor #include <stdio.h> float sqr (float num); void main (void) { float num,sq; printf ("Entre com um numero: "); scanf ("%f",&num); sq=sqr(num); printf ("\n\nO numero original e: %f\n",num); printf ("O seu quadrado vale: %f\n",sq); } float sqr (float num) { num=num*num; return num; } num NO alterado no programa principal! E se quisermos alterar os valores dos parmetros para o programa principal? passagem de parmetros por referncia! Este nome vem do fato de que, neste tipo de chamada, no se passa para a funo os valores das variveis, mas sim suas referncias (a funo usa as referncias para alterar os valores das variveis fora da funo). Quando queremos alterar as variveis que so passadas para uma funo, ns podemos declarar seus parmetros formais como sendo ponteiros. Os ponteiros so a "referncia" que precisamos para poder alterar a varivel fora da funo. O nico inconveniente que, quando usarmos a funo, teremos de lembrar de colocar um & na frente das variveis que estivermos passando para a funo. #include <stdio.h> void Swap (int *a,int *b); void main ()

Linguagens C e C++: Uma introduo sintaxe Pg. 54 { int num1,num2; num1=100; num2=200; Swap (&num1,&num2); printf ("\n\nEles agora valem %d %d\n",num1,num2); } void Swap (int *a,int *b) { int temp; temp=*a; *a=*b; *b=temp; } ... Porque temos que usar um & antes dos parmetros de scanf()? Vetores como Argumentos de Funes int matrx [50]; /* Sera passada como argumento para func() */ Podemos declarar func() das trs maneiras seguintes: void func (int matrx[50]); void func (int matrx[]); void func (int *matrx); Os valores de matrx PODEM ser alterados dentro de func() ! Os Argumentos argc e argv A funo main() pode ter parmetros formais int main (int argc, char *argv[]); Os parmetros argc e argv do ao programador acesso linha de comando com a qual o programa foi chamado. O argc (argument count) um inteiro e possui o nmero de argumentos com os quais a funo main() foi chamada na linha de comando. Ele , no mnimo 1, pois o nome do programa contado como sendo o primeiro argumento.

Linguagens C e C++: Uma introduo sintaxe Pg. 55 O argv (argument values) um ponteiro para um vetor de strings. Cada string deste vetor um dos parmetros da linha de comando. O argv[0] sempre aponta para o nome do programa Exemplo: Escreva um programa que faa uso dos parmetros argc e argv. O programa dever receber a partir da linha de comando o dia, mes e ano correntes, e imprimir a data em formato apropriado. Soluo: #include <stdio.h> #include <stdlib.h> void main(int argc, char *argv[]) { int mes; char *nomemes [] = {"Janeiro", "Fevereiro", "Maro", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"}; mes = atoi(argv[2]); if (mes<1 || mes>12) printf("Erro!"); else printf("\n%s de %s de 19%s", argv[1], nomemes[mes-1], argv[3]); } Recursividade Na linguagem C uma funo pode chamar a si prpria. Uma funo assim chamada funo recursiva. #include <stdio.h> int fat(int n) { int ret; if (n) return n*fat(n-1) else return 1; } void main() { int n;

Linguagens C e C++: Uma introduo sintaxe Pg. 56 printf("\n\nDigite um valor para n: "); scanf("%d", &n); printf("\nO fatorial de %d e' %d", n, fat(n)); } H certos algoritmos que so mais eficientes quando feitos de maneira recursiva, mas a recursividade algo a ser evitado sempre que possvel, pois, se usada incorretamente, tende a consumir muita memria e ser lenta. Lembre-se que memria consumida cada vez que o computador faz uma chamada a uma funo. Com funes recursivas a memria do computador pode se esgotar rapidamente. Escopo de variveis: Em C, existem as variveis locais, locais de bloco, globais e globais de arquivo. Vimos tambm que uma varivel local de mesmo nome de uma varivel global "esconde" a varivel global no seu escopo.

#include <stdio.h> int j = 0; int main( ) { int j; j = 45; printf("O valor de j em main e: %d", j); /* Imprimir 45 */ { int j = 5; printf (" j dentro do bloco= %d", j); /* Imprimira 5 */ } } Em C, seria impossvel acessar o valor das variveis globais escondiadas por variveis locais de mesmo nome. Em C++ existe o operador de resoluo de escopo (::) Este operador, colocado na frente do nome da varivel, faz com que o programa possa acessar a varivel global. #include <stdio.h> int j = 0; int main( ) {

Linguagens C e C++: Uma introduo sintaxe Pg. 57 int j; j = 45; printf("O valor de j em main e: %d ", j); /* Imprimir 45 */ printf("O valor global de j e: %d ", ::j); /* Imprimira' 0 */ { int j = 5; printf (" j dentro do bloco= %d ", j); /* Imprimira 5 */ printf("O valor global de j e: %d ", ::j); /* Imprimira' 0 */ } } Especificadores de classe de armazenamento. auto O especificador de classe de armazenamento auto define variveis locais. Este especificador praticamente nunca usado pois todas as variveis do C so auto por definio, isto , ao se encerrar o processamento dentro da funo ou bloco em que foram declaradas, a memria ocupada por estas variveis liberada. extern O extern define variveis que sero usadas em um arquivo apesar de terem sido declaradas em outro. Digamos que para um programa grande tenhamos duas variveis globais: um inteiro count e um float sum. Estas variveis so declaradas normalmente em um dos mdulos do programa. int count; float sum; main (void) { ... return 0; } Num outro mdulo do programa temos uma rotina que deve usar as variveis globais acima. Digamos que a rotina que queremos se chama RetornaCount() e retorna o valor atual de count. O problema que este mdulo ser compilado em separado e no tomar conhecimento dos outros mdulos. O que fazer? Ser que funcionaria se fizermos assim: int count; /* errado */ float sum; int RetornaCount (void) {

Linguagens C e C++: Uma introduo sintaxe Pg. 58 return count; } No. O mdulo compilaria sem problema, mas, na hora que fizermos a linkagem (unio dos mdulos j compilados para gerar o executvel) vamos nos deparar com uma mensagem de erro dizendo que as variveis globais count e sum foram declaradas mais de uma vez. A maneira correta de se escrever o mdulo com a funo RetornaCount() : extern int count; /* certo */ extern float sum; int RetornaCount (void) { return count; } Assim, o compilador ir saber que count e sum esto sendo usados no bloco mas que foram declarados em outro. static O funcionamento das variveis declaradas como static depende se estas so globais ou locais. Variveis globais static funcionam como variveis globais dentro de um arquivo, ou seja, so variveis globais que no so (e nem podem ser) conhecidas em outros modulos. Isto util se quisermos isolar pedaos de um programa para evitar mudanas acidentais em variveis globais. Variveis locais static so variveis cujo valor mantido de uma chamada da funo para a outra: int count (void) { static int num=0; num++; return num; } A inicializao de num s vale para a primeira vez que a funo chamada pois num deve manter o seu valor de uma chamada para a outra. Declarar-se uma funo como static significa restringir sua visibilidade ao arquivo fonte onde ela se encontra Modificao C++

Linguagens C e C++: Uma introduo sintaxe Pg. 59 Uma modificao que o C++ trouxe refere-se declarao extern. Em C++ toda varivel global no static ser do tipo extern implicitamente. Ponteiros para Funes O C permite que acessemos variveis e funes atravs de ponteiros! Podemos ento fazer coisas como, por exemplo, passar uma funo como argumento para outra funo. Um ponteiro para uma funo tem a seguinte declarao: tipo_de_retorno (*nome_do_ponteiro)(); ou tipo_de_retorno (*nome_do_ponteiro)(declarao_de_parmetros); Veja que no obrigatrio se declarar os parmetros da funo #include <ctype.h> #include <stdio.h> #include <string.h> #include <stdlib.h> void check (char *a, char *b, int (*cmp)()); int numcmp(char *a, char *b); int main (void) { char s1[80], s2[80]; gets(s1); gets(s2); if(tolower(*s1) <= 'z' && tolower (*s1) >='a') check(s1,s2,strcmp); else check(s1,s2,numcmp); return 0; } void check (char *a, char *b, int (*cmp) () ) { printf ("verificando a igualdade \n");

Linguagens C e C++: Uma introduo sintaxe Pg. 60 if(!(*cmp)(a,b) ) printf ("iguais"); else printf("diferentes"); } int numcmp (char *a, char *b) { if(atoi(a) == atoi(b)) return 0; else return 1; } Funes em C++: 1- As funes C++ podem ter argumentos default (tambm conhecidos como argumentos padro ou assumidos). Isto significa que, caso a chamada da funo omita algum parmetro, a funo pode usar o default previamente definido. Para definir valores default eles devem ser explicitados na declarao (prottipo) da funo.
/************************************************* O programa calcula o valor das parcelas de uma compra a prazo, baseando-se em um plano simples de pagamentos e na formula do Valor Presente. O Calculo das prestacoes e' dado pela formula : A = (VP * i ) /(1 (1 + i ) n ) onde A = Valor de cada Pagamento VP= Valor a vista i = taxa de juros n = numero de pagamentos ****************************************************/

#include <stdio.h> #include <math.h> void condicoes (float valor, int pagamentos=0); const float juros = 0.05; int main() { float valor, entrada; char inbuf[30]; printf("Entre com o valor da compra: "); scanf("%f", &valor); condicoes(valor); // a vista condicoes(valor,1); // 1 pagamento daqui a 1 mes condicoes(valor,3); // 3 vezes

Linguagens C e C++: Uma introduo sintaxe Pg. 61 condicoes(valor,6); // 6 vezes return 0; } void condicoes (float valor, int pagamentos) { float prestacao; if (pagamentos) { prestacao = valor * juros; prestacao /= (1 - pow(1+juros,-pagamentos)); printf("\nou %d parcelas de Cr$%9.2f",pagamentos, prestacao ); } else printf("\nValor a vista e\' Cr$ %9.2f",valor); } No h como deixar de mencionar argumentos no meio de uma lista. Exemplo: float listagem(char = , int = 0, float = 1.5); Pode-se omitir: f = listagem(); f=listagem(b); f=listagem(c, 1); Mas no f=listagem(a, ,3.1)!!!!!!! 2- Funes inline: aperfeioamento do conceito de macros do C, retirando seus problemas. Ex: #define CUBO(x) x*x*x. CUBO(a+b) a+b*a+b*a+b = a + 2.ba + b !!!!! Alm disto, macros no permitem variveis locais, blocos, verificao de tipos inline int par num : num+1);} (int num) {return((num%2==0)?

inline float cubo (float x) {return x*x*x;} inline float dobro (float x) {return 2*x;} 3- Sobrecarga de funes: Funes com mesmo nome, mas com o nmero ou o tipo de parmetros diferentes podem existir. Exemplo: int escalar(int [], int [], int); float escalar(float [], float [], int);

Linguagens C e C++: Uma introduo sintaxe Pg. 62 Para poder haver sobrecarga necessrio que as listagens de parmetros sejam diferentes em pelo menos um argumento! Cuidado com parmetros default, para no confundir o compilador!!!! void impressao(int, float, char); e void impressao(int,float); podem ser sobrecarregadas, mas void impressao(int, float, char=a); no. Exemplo: Overload.cpp #include <stdio.h> #include <conio.h> int escalar(int [], int [], int); float escalar(float [], float [], int); int main () { int vet_i1[5] = {1,2,3,4,5}; int vet_i2[5] = {0,0,0,0,1}; float vet_f1[3] = {4.1,1.0,3.1}; float vet_f2[3] = {0,0,1}; printf ("\nEscalar dos inteiros = %d",escalar(vet_i1, vet_i2, 5)); printf ("\nEscalar dos floats = %f",escalar(vet_f1, vet_f2, 3)); return 0; } int escalar (int a[], int b[], int tam) { int res = 0; for (int i = 0; i < tam; i++) res += a[i] * b[i]; return res; } float escalar (float a[], float b[], int tam) { float res = 0; for (int i = 0; i < tam; i++) res += a[i] * b[i]; return res; } 4- Referncias: Uma referncia um apelido (alias) de uma varivel, ou seja, apesar de possurem nomes distintos, uma referncia e sua varivel

Linguagens C e C++: Uma introduo sintaxe Pg. 63 de inicializao ocupam o mesmo endereo de memria. A modificao de uma afeta a outra. Exemplo: int z = 10; int & y = z; Referncias devem ser inicializadas no instante de sua declarao (excees na pgina 123). Referncias so muito utilizadas na passagem de parmetros por referncia em C++. Exemplo: Em C: void zera(int *); int main() { int x; zera(&x); return 0; } void zera(int * valor){ *valor = 0; } Em C++: void zera (int &); int main() { int x; zera(x); return 0 } void zera (int & valor) { valor = 0; }

1.10. Estruturas e Enumeraes Uma estrutura agrupa vrias variveis numa s. Funciona como uma ficha pessoal que tenha nome, telefone e endereo. A ficha seria uma estrutura. Criando Estruturas Para se criar uma estrutura usa-se o comando struct. Sua forma geral :
struct nome_do_tipo_da_estrutura { tipo_1 nome_1; tipo_2 nome_2; ... tipo_n nome_n; } variveis_estrutura;

Exemplos:

Linguagens C e C++: Uma introduo sintaxe Pg. 64 #include <stdio.h> #include <string.h> struct tipo_endereco { char rua [50]; int numero; char bairro [20]; char cidade [30]; char sigla_estado [3]; long int CEP; }; struct ficha_pessoal { char nome [50]; long int telefone; struct tipo_endereco endereco; }; main (void) { struct ficha_pessoal ficha; strcpy (ficha.nome,"Luiz Osvaldo Silva"); ficha.telefone=4921234; strcpy (ficha.endereco.rua,"Rua das Flores"); ficha.endereco.numero=10; strcpy (ficha.endereco.bairro,"Cidade Nova"); strcpy (ficha.endereco.cidade,"Belo Horizonte"); strcpy (ficha.endereco.sigla_estado,"MG"); ficha.endereco.CEP=31340230; return 0; } Para no necessitarmos utilizar a palavra struct a cada declarao de varivel estruturada, devemos definir um tipo para a estrutura, ou seja, devemos usar o typedef. Por exemplo: , typedef struct { char rua [50]; int numero; char bairro [20];

Linguagens C e C++: Uma introduo sintaxe Pg. 65 char cidade [30]; char sigla_estado [3]; long int CEP; } Endereco; Agora a declarao de uma varivel seguir a seguinte sintaxe: Endereco minha_casa, meu_trabalho; Inovao C++: Em C++ no necessrio utilizar a palavra typedef para se definir uma estrutura. A prpria etiqueta especificando nome j define um tipo. Assim: struct Endereco { char rua [50]; int numero; char bairro [20]; char cidade [30]; char sigla_estado [3]; long int CEP; }; Permite declarar: Endereco minha_casa, meu_trabalho; Vetores de estruturas Um estrutura como qualquer outro tipo de dado no C. Podemos, portanto, fazer vetores e matrizes de estruturas: struct ficha_pessoal fichas [100]; Poderamos ento acessar a segunda letra da sigla de estado da dcima terceira ficha fazendo:
fichas[12].endereco.sigla_estado[1];

Atribuindo Podemos atribuir duas estruturas que sejam do mesmo tipo. O C ir, neste caso, copiar uma estrutura na outra. void main() {

Linguagens C e C++: Uma introduo sintaxe Pg. 66 struct ficha_pessoal primeira, segunda; Le_dados(&primeira); segunda = primeira; Imprime_dados(segunda); } Devemos tomar cuidado com a seguinte declarao: struct ficha_pessoal fichas [100]; pois neste caso fichas um ponteiro para a primeira ficha. Se quisermos a estrutura completa da n-sima ficha devemos usar fichas[n-1]. Passando para funes void PreencheFicha (struct ficha_pessoal ficha) { ... } Devemos observar que, como em qualquer outra funo no C, a passagem da estrutura feita por valor. Isto significa que alteraes na estrutura dentro da funo no tero efeito na varivel fora da funo. Mais uma vez podemos contornar este pormenor usando ponteiros e passando para a funo um ponteiro para a estrutura. Inovao C++: Referncias constantes Pode-se otimizar a performance de um programa utilizando referncias em casos de passagem de parmetros por valor, pois toda passagem por valor acarreta cpia em memria. Para estruturas grandes, isto ineficiente. Pode-se, ainda, usar uma referncia constante, eliminando cpia e garantindo que a varivel no ser modificada. #include <stdio.h> struct Pessoa { char nome[40]; char endereco[60]; }; void entrada(Pessoa & alguem); void saida(const Pessoa & alguem);

Linguagens C e C++: Uma introduo sintaxe Pg. 67 int main() { Pessoa usuario; entrada(usuario); saida(usuario); return 0; } void entrada(Pessoa & alguem) { printf("\nEntre com seu Nome : "); gets(alguem.nome); printf("Entre com seu Endereco : "); gets(alguem.endereco); } void saida(const Pessoa & alguem) { printf("\n\nDADOS DO USUARIO : "); printf("\tNome : %s\n",alguem.nome); printf("\tEndereco : %s",alguem.endereco); } Ponteiros para estruturas struct ficha_pessoal *p; Os ponteiros para uma estrutura funcionam como os ponteiros para qualquer outro tipo de dados no C. H, entretanto, um detalhe a ser considerado. Se apontarmos o ponteiro p declarado acima para uma estrutura qualquer e quisermos acessar um elemento da estrutura poderamos fazer: (*p).nome Este formato raramente usado. O que comum de se fazer acessar o elemento nome atravs do operador seta (->): p->nome A declarao acima muito mais fcil e concisa. Para acessarmos o elemento CEP dentro de endereco faramos: p->endereco.CEP

Linguagens C e C++: Uma introduo sintaxe Pg. 68 Exerccio: Escreva um programa fazendo o uso de structs. Voc dever criar um tipo chamado ponto, contendo apenas a posio x e y (inteiros) do ponto. Declare 2 pontos, leia a posio (coordenadas x e y) de cada um e calcule a distncia entre eles. Divida o programa atravs do uso de funes (por exemplo usando uma rotina para a leitura e uma rotina para o clculo de distncia). Apresente no final a distncia entre os dois pontos. Enumeraes Numa enumerao podemos dizer ao compilador quais os valores que uma determinada varivel pode assumir. enum nome_do_tipo_da_enumerao lista_de_variveis; Exemplo: #include <stdio.h> enum dias_da_semana {segunda, terca, quarta, quinta, sexta, sabado, domingo}; int main (void) { enum dias_da_semana d1,d2; d1=segunda; d2=sexta; if (d1==d2) { printf ("O dia e o mesmo.\n"); } else { printf ("So dias diferentes.\n"); } if(d2=sexta) printf ("Ta' chegando o fim de semana ... \n"); return 0; } Como a enumerao funciona? O compilador pega a lista de valores que voc fez e associa, a cada um, um nmero inteiro. Ento, ao primeiro da lista, associado o nmero zero, o segundo ao nmero 1 e assim por diante. As variveis declaradas so ento variveis int. {lista_de_valores}

Linguagens C e C++: Uma introduo sintaxe Pg. 69

1.11. Introduo s entradas e sadas em C++

1.11.1. Fluxos padronizados de entrada e sada: Os sistemas de entrada e sada do C e C++ podem trabalhar com uma grande variedade de dispositivos fsicos. Estes dispositivos so chamados de arquivos e podem ser arquivos em disco, terminais de vdeo, placas de rede, fitas, etc ... Para prover uma abstrao sobre estes dispositivos, estas linguagens trabalham com o conceito de fluxo, dispositivos lgicos. Todos os fluxos so similares no funcionamento. Tendo em vista que os fluxos so altamente independentes dos dispositivos, as mesmas funes que escrevem para um arquivo em disco podem tambm escrever para o console. A biblioteca stream (fluxo)do C++ implementada como uma coleo de classes que segue o paradigma da orientao a objetos. Nela esto trs objetos: cin, cout e cerr, destinados entrada e sada de dados via terminal ou via arquivos. Para utilizar, incluir o arquivo de caberio iostream.h. cin >> varivel; Exemplo: int x; float f, g; double dou; char ch; cin >> x; cin >> f >> g; cin >> dou >> ch; cout << Expresso; int x=2; float f=1, g=3; double dob = 3; char sex = f; cout << x = << x; cout << f << << g; cout << dob = << dob << \nsex= << sex; OBS: cin na entrada de Strings:

Linguagens C e C++: Uma introduo sintaxe Pg. 70 char nome[30]; cin >> nome; Ler o que o usurio digitar at ocorrer um espao ! Renato Cardoso ser entendido como Renato. Podem ser usadas as funes get (funes sobrecarregadas), pertencentes ao objeto cin: get(char *string, int tamanho, char terminador = \n); get(streambuf& buffer, char terminador = \n); get(char& ch); char c, string[20]; streambuf alg; cin.get( c); cin.get(string, 20); cin.get(alg, 'f'); OBS: Ver exemplo CIN_GET.CPP na pgina 140, para problemas e variaes no comportamento dos mtodos get de cin. Ver tambm as tabelas 9.3 e 9.4 (pginas 142 e 143) com as funes de manipulao de fluxo das classes istream e ostream. 1.11.2. Sadas formatadas em C++ A forma default pela qual os dados so impressos em C++ definida pelo estado de formato. A modificao do estado de formato pode ser efetivada pelos Manipuladores ou pelos Sinalizadores de formato. No caso dos Sinalizadores, o programador pode manipular o estado de formato (definindo base e preciso) atravs da utilizao das funes setf() e unsetf(), com os parmetros da tabela 9.5 (pg. 143/144). Exemplo: double a, b, c; cout.setf(ios::scientific); // Notacao cientifica cout << a; cout << b; cout.unset(ios::scientific); cout.setf(ios::fixed); // Notacao de ponto flutuante cout << b << c;

Linguagens C e C++: Uma introduo sintaxe Pg. 71 cout.width(n) : Ajusta o campo de sada para o tamanho n (o default zero, isto , utiliza todo o campo necessrio). Programa FORM_SIN.CPP exemplifica situaes de uso de sinalizadores (pginas 145/146); Outra forma de manipular campos em C++ pressupe a utilizao de Manipuladores. Para us-los deve-se incluir o header iomanip.h. A tabela 9.7 (pgs 146 e 147) apresenta vrios manipuladores e seus significados. Exemplo de uso de manipuladores para formatao da sada: #include <iostream.h> #include <iomanip.h> int main () { char *texto = Saidas; cout.setf(ios::left); cout << setw(20) << texto << 20 <<\n; // Usa o manipulador setw() cout << setw(20) << setfill(.) << texto << 20; // setw() e setfill return 0; } Saidas 20 Saidas..............20 Programa FOR_MAN.CPP exemplifica o uso de manipuladores em C++.

Você também pode gostar