Baixe o app para aproveitar ainda mais
Prévia do material em texto
Universidade Federal de Mato Grosso do Sul Campus de Três Lagoas Sistemas de Informação Algoritmos e Programação II Introdução à C SI-CPTL-UFMS Prof. Ms. Leandro Magalhães de Oliveira S is te m a s d e I n fo rm a ç ã o - C P T L 1 Hello World! S is te m a s d e I n fo rm a ç ã o - C P T L 2 MOLDE Molde de um programa em C: #include <stdio.h> /* Comentários sobre o que o seu programa faz */ int main(void) { /* seus comandos */ return 0; } 3 S is te m a s d e I n fo rm a ç ã o - C P T L Estrutura Condicional Simples Quando só existe um comando no bloco do if, o uso de { } é opcional if ( condição ) comando 1; S is te m a s d e I n fo rm a ç ã o - C P T L 4 Exemplo #include <stdio.h> int main(void) { int idade; printf("Quantos anos você tem? "); scanf("%d", &idade); if (idade < 30) printf("Você é bem jovem!\n"); printf("Até breve!\n"); return 0; } S is te m a s d e I n fo rm a ç ã o - C P T L 5 Estrutura Condicional Composta Uma estrutura condicional composta tem o seguinte formato if ( condição ) { comando 1; … comando n; } else { comando 1; … comando n; } S is te m a s d e I n fo rm a ç ã o - C P T L 6 Segundo Exemplo #include <stdio.h> int main(void) { int idade; printf("Quantos anos você tem? "); scanf("%d", &idade); if (idade < 30) printf("Você é bem jovem!\n"); else printf("Você não é tão jovem.\n"); printf("Até breve!\n"); return 0; } S is te m a s d e I n fo rm a ç ã o - C P T L 7 Mais sobre a função scanf() • Podemos ler mais de um inteiro utilizando scanf(): • scanf(“%d %d”, &a, &b); • scanf(“%d %d %d”, &x, &y, &z); • E assim por diante; 8 S is te m a s d e I n fo rm a ç ã o - C P T L Estrutura de repetição while . . . while(condição) { instrução 1; instrução 2; . . . instrução m; } 9 . . . . . . S is te m a s d e I n fo rm a ç ã o - C P T L Números com ponto flutuante • A linguagem C permite que variáveis sejam declaradas para armazenar números com ponto flutuante, com os tipos float e double. • Exemplo: float x, y; double media; • Declara duas variáveis x e y do tipo float e uma variável média do tipo double. • É idêntico à declaração de variáveis do tipo int, como sempre fizemos, trocando o tipo da variável... 10 S is te m a s d e I n fo rm a ç ã o - C P T L Números com ponto flutuante • A distinção entre os tipos float e double se dá pela quantidade de precisão necessária. • Quando a precisão não é crítica, o tipo float é adequado. • O tipo double fornece precisão maior. • float e double também representam números reais negativos... • O menor número double seria -1.79769 * 10^308 11 S is te m a s d e I n fo rm a ç ã o - C P T L Números com ponto flutuante • Dica: É recomendável utilizar o tipo double. Atualmente, o custo de memória adicional por usar double ao invés de float é desprezível e sua precisão é muito maior. Com double, o programador se preocupa menos com o intervalo e a precisão dos números reais que ele irá trabalhar... • Utilizando apenas float, você pode eventualmente ter algum problema com intervalo e/ou precisão. Se você sempre usar double, você praticamente não terá nenhum problema com intervalo ou precisão! 12 S is te m a s d e I n fo rm a ç ã o - C P T L Imprimindo float e double • Para imprimir variáveis float e double na tela, utilizando o printf(), devemos escrever a mesma instrução que sabemos para imprimir variáveis inteiras na tela. O que mudamos é simplesmente a sequência de formatação. • Exemplo: • Para imprimir um float que representa a média de três inteiros: printf(“A media de %d, %d e %d eh: %f”, n1, n2, n3, media); • Para imprimir um double que representa a média de três inteiros (a mesma coisa): printf(“A media de %d, %d e %d eh: %f”, n1, n2, n3, media); 13 S is te m a s d e I n fo rm a ç ã o - C P T L Imprimindo float e double • Ou seja, para imprimir variáveis inteiras utilizamos a sequência de formatação %d. • Para imprimir variáveis com ponto flutuante, utilizamos a sequência de formatação %f. 14 S is te m a s d e I n fo rm a ç ã o - C P T L Lendo float e double • Para ler variáveis float e double do teclado, utilizando o scanf(), devemos escrever a mesma instrução que sabemos para ler variáveis inteiras na tela. O que mudamos é simplesmente a sequência de formatação. • Exemplo: • Para ler um float que representa o lado de um quadrado: scanf(“%f”, &lado); • Para ler um double que representa o lado de um quadrado (note a diferença sutil): scanf(“%lf”, &lado); 15 S is te m a s d e I n fo rm a ç ã o - C P T L Lendo float e double • Ou seja, para ler variáveis inteiras utilizamos a sequência de formatação %d. • Para ler variáveis float, utilizamos a sequência de formatação %f. • Para ler variáveis double, utilizamos a sequência de formatação %lf. • Isso é apenas para o scanf()! Para o printf(), a sequência de formatação para ambos os tipo é apenas %f. 16 S is te m a s d e I n fo rm a ç ã o - C P T L Nota sobre float e double • Para escrever variáveis reais tanto no código fonte do seu programa, como na execução do programa, utilize o ponto (.) como símbolo separador da parte inteira da parte fracionária; • Este é o padrão americano. • 1.75; • No padrão brasileiro, o valor acima deveria ser escrito da seguinte forma: • 1,75; • Contudo, em programação, utilizamos o padrão americano. 17 S is te m a s d e I n fo rm a ç ã o - C P T L Operadores Aritméticos • Operador aritmético unário • Um operador que age sobre um único número inteiro e devolve um resultado. • Há dois operadores aritméticos unários na linguagem C • o operador - , que troca o sinal da expressão aritmética que o sucede; • operador +, que não faz nada além de enfatizar que uma constante numérica é positiva (geralmente não utilizamos este operador). 18 S is te m a s d e I n fo rm a ç ã o - C P T L Operadores Aritméticos • Operador aritmético binário • Realiza as operações básicas sobre dois números inteiros • Vimos 5 operadores aritméticos binários: • + (adição) • - (subtração) • * (multiplicação) • / (quociente de uma divisão inteira) • % (resto de uma divisão inteira) 19 S is te m a s d e I n fo rm a ç ã o - C P T L Precedência dos operadores aritméticos • Caso haja necessidade de modificar a prioridade de uma operação em uma expressão, parênteses devem ser utilizados. • Como na matemática... • 7 * 5 + 3 = 38 • 7 * (5+3) = 56 20 S is te m a s d e I n fo rm a ç ã o - C P T L Expressões Relacionais • Uma expressão relacional, ou simplesmente uma relação, é uma comparação entre dois valores. • Esses valores são representados na relaçãoatravés de constantes, variáveis ou expressões. • Os operadores relacionais da linguagem C são: 21 S is te m a s d e I n fo rm a ç ã o - C P T L Expressões Relacionais • O resultado da avaliação de uma expressão relacional é sempre um valor lógico, isto é, verdadeiro ou falso. • Os operadores aritméticos têm precedência sobre os relacionais. A tabela de precedência, com os operadores relacionais fica assim: 22 S is te m a s d e I n fo rm a ç ã o - C P T L Expressões Relacionais • O resultado da avaliação de uma expressão relacional é sempre um valor lógico, isto é, verdadeiro ou falso. • Exemplo: int a, b, c; a = 2; b = 3; c = 4; • Qual o valor destas expressões? • a == 2 • a > b + c • b + c <= 5 - a • b != 3 23 S is te m a s d e I n fo rm a ç ã o - C P T L Expressões Lógicas • Uma expressão lógica é formada por uma ou mais expressões relacionais, através dos operadores lógicos. • Os operadores lógicos da linguagem C, utilizados como conectivos nas expressões lógicas são apresentados a seguir. 24 S is te m a s d e I n fo rm a ç ã o - C P T L Expressões Lógicas • Duas expressões relacionais p e q podem ser combinadas pelo conectivo && para formar uma única expressão denominada conjunção das proposições originais; • p && q; • Leia-se “p e q”; • Exemplo: if (nota >= 5 && faltas <= 8) { printf(“Aluno aprovado!”); } 25 S is te m a s d e I n fo rm a ç ã o - C P T L Expressões Lógicas • O resultado da avaliação de uma conjunção é verdadeiro se ambos os lados têm valor verdadeiro, como mostra a tabela a seguir: 26 p q p && q V V V V F F F V F F F F S is te m a s d e I n fo rm a ç ã o - C P T L Expressões Lógicas • Exemplo: if (nota >= 5 && faltas <= 8) { printf(“Aluno aprovado!”); } else { printf(“Aluno reprovado!”); } Simule os seguintes casos: 27 Casos Resultado? Nota = 7 e faltas = 5 Nota = 10 e faltas = 10 Nota = 3 e faltas = 0 Nota = 4 e faltas = 9 S is te m a s d e I n fo rm a ç ã o - C P T L Expressões Lógicas • Podemos relacionar várias expressões utilizando && • Não apenas duas. • Exemplo: if (nota >= 5 && faltas <= 8 && x <= y && a==2 && t > 4) { printf(“Aluno aprovado!”); } 28 S is te m a s d e I n fo rm a ç ã o - C P T L Expressões Lógicas • Duas expressões relacionais p e q podem ser combinadas pelo conectivo || para formar uma única expressão denominada disjunção das proposições originais; • p || q; • Leia-se “p ou q”; • Exemplo: if (idade < 18 || idade >= 65) { printf(“Você não pode se alistar no exército.”); } 29 S is te m a s d e I n fo rm a ç ã o - C P T L Expressões Lógicas • O resultado da avaliação de uma disjunção é verdadeiro se pelo menos um dos lados é verdadeiro, como mostra a tabela a seguir: 30 p q p || q V V V V F V F V V F F F S is te m a s d e I n fo rm a ç ã o - C P T L Expressões Lógicas • Exemplo: if (idade < 18 || idade >= 65) { printf(“Você não pode se alistar no exército.”); } else { printf(“Você está aceito no exército!”); } Simule os seguintes casos: 31 Casos Resultado? Idade = 15 Idade = 18 Idade = 30 Idade = 65 S is te m a s d e I n fo rm a ç ã o - C P T L Expressões Lógicas • Dada uma expressão relacional p, podemos usar o conectivo ! para formar uma única expressão denominada negação de p; • !p; • Leia-se “não p”; • !p é o complemento de p. Se p é verdadeiro, !p é falso. Se p é falso, !p é verdadeiro. 32 p !p V F F V S is te m a s d e I n fo rm a ç ã o - C P T L Expressões Lógicas • Exemplo: if (nota >= 7) { printf(“Aluno aprovado.”); } else { printf(“Aluno reprovado”); } Simule os seguintes casos: 33 Casos Resultado? Nota = 8 Nota = 6 S is te m a s d e I n fo rm a ç ã o - C P T L Expressões Lógicas • Exemplo: if (!(nota >= 7)) { printf(“Aluno reprovado”); } else { printf(“Aluno aprovado.”); } Simule os seguintes casos: 34 Casos Resultado? Nota = 8 Nota = 6 S is te m a s d e I n fo rm a ç ã o - C P T L Precedência • A tabela abaixo ilustra a prioridade de todos os operadores aritméticos, relacionais e lógicos, unários e binários, vistos até aqui. 35 S is te m a s d e I n fo rm a ç ã o - C P T L For • Exemplo de um programa simples que imprime os 100 primeiros números inteiros utilizando while: 36 S is te m a s d e I n fo rm a ç ã o - C P T L For • Exemplo de um programa simples que imprime os 100 primeiros números inteiros utilizando while: 37 Inicialização Condição Incremento ou passo S is te m a s d e I n fo rm a ç ã o - C P T L For • O formato geral da estrutura de repetição for é dado a seguir: for(inicialização; condição; passo) { Instrução 1; Instrução 2; . . . Instrução n; } 38 S is te m a s d e I n fo rm a ç ã o - C P T L For • Exemplo de um programa simples que imprime os 100 primeiros números inteiros utilizando for: 39 S is te m a s d e I n fo rm a ç ã o - C P T L For • Exemplo de um programa simples que imprime os 100 primeiros números inteiros utilizando for: 40 Inicialização Condição Incremento ou passo S is te m a s d e I n fo rm a ç ã o - C P T L Definição • Cada vetor, assim como uma variável, também possui um nome. • Para declarar um vetor, utilize a seguinte instrução: • tipo nome[tamanho]; • Onde tipo é denota o tipo do vetor. Se seu vetor será um vetor de inteiros, então o tipo é int. Se seu vetor é um vetor de doubles, então o tipo é double. • Nome é simplesmente o nome do vetor. Assim como acontece com variáveis, vamos nos referir a um vetor pelo nome que damos à ele. • Tamanho é o tamanho do vetor que estamos declarando. 41 S is te m a s d e I n fo rm a ç ã o - C P T L Caracteres • Um caractere pode ser visto como uma variável int no intervalo [0, 255]. • Temos 256 caracteres diferentes na linguagem C; • Diferentemente de uma variável do tipo int, quando imprimos um caractere utilizando printf(), sua representação gráfica é impressa ao invés de seu valor; • Se temos um caractere com valor 97 e o imprimos na tela, a letra ‘a’ é impressa. Isso acontece porque o ‘a’ é a representação gráfica do caractere 97. • A linguagem C utiliza a tabela ASCII (American Standard Code for Information Interchange - Código Padrão Americano para Troca de Informações) para traduzir o valor das variáveis em uma representação gráfica. 42 S is te m a s d e I n fo rm a ç ã o - C P T L Caracteres • A linguagem C utiliza a tabela ASCII (American Standard Code for Information Interchange - Código Padrão Americano para Troca de Informações) para traduzir o valor dasvariáveis em uma representação gráfica. • Consulte a tabela ASCII em http://www.asciitable.com/; • A primeira coluna da tabela indica o valor do caractere em decimal e a última coluna indica a representação gráfica daquele caractere; • Note que esta tabela apresenta apenas 128 caracteres. Estes são os caracteres padrão da tabela ASCII e são aqueles com os quais iremos trabalhar. 43 S is te m a s d e I n fo rm a ç ã o - C P T L Caracteres • Observação: • Dos 128 caracteres padronizados da tabela ASCII e de seus símbolos gráficos correspondentes, 33 deles são não-imprimíveis (de 0 a 31 e o 127) e os restantes 95 são imprimíveis. Os caracteres não-imprimíveis são caracteres de controle, criados nos primórdios da computação, quando se usavam máquinas teletipo e fitas de papel perfurado, sendo que atualmente grande parte deles estão obsoletos. • Dos caracteres não-imprimíveis, o que usaremos será o caractere 0 (será usado em vetores) e o 10 (que é o \n). 44 S is te m a s d e I n fo rm a ç ã o - C P T L Caracteres • Uma variável do tipo caractere pode ser declarada na linguagem C utilizando a palavra-chave char. • A instrução abaixo declara uma variável do tipo caractere chamada c: char c; • Para imprimir uma variável char, utilizamos a função printf(), mas com o formato “%c”: printf(“%c”, c); • Neste caso, será impresso a representação gráfica do caractere. • Descubra o que será impresso no programa ex1.c. 45 S is te m a s d e I n fo rm a ç ã o - C P T L Caracteres • Existe uma forma muito mais comum e confortável de representar constantes do tipo char. • Esta é a forma que sempre será usada. • Simplesmente colocamos o caractere desejado entre aspas simples, ao invés do valor do caractere. char c = ‘x’; 46 S is te m a s d e I n fo rm a ç ã o - C P T L Expressões com Caracteres • Caracteres são implementados como números inteiros. • Expressões envolvendo variáveis int (aritmética, de comparação, etc) podem ser utilizando com variáveis char. • Para ler um caractere do teclado, simplesmente utilize scanf() com a sequência de formatação “%c”: scanf(“%c”, &c); 47 S is te m a s d e I n fo rm a ç ã o - C P T L Literais • Temos utilizado cadeias de caracteres desde o nosso primeiro programa. Por exemplo, na seguinte instrução: printf(“Ola.\n”); o único argumento passado para a função printf é a cadeia de caracteres (de formatação) “Ola.\n”. • As aspas duplas “ e ” são usadas para delimitar uma constante do tipo cadeia de caracteres. • Na linguagem C, uma constante do tipo cadeia de caracter é chamada de literal. 48 S is te m a s d e I n fo rm a ç ã o - C P T L Literais e constantes char • Constantes do tipo char podem ser representadas por aspas simples, conforme já foi visto: char sinal = ‘+’; • Note que aspas simples definem constantes do tipo char e aspas duplas definem constantes do tipo cadeia de caracteres. Logo, a seguinte instrução está incorreta: char sinal = “+”; • Porque a variável sinal é um char e não uma cadeia de caracteres. 49 S is te m a s d e I n fo rm a ç ã o - C P T L Literais • Usamos literais especialmente quando chamamos as funções printf e scanf em um programa, ou seja, quando descrevemos cadeias de caracteres de formatação. • Essencialmente, a linguagem C trata as literais como cadeias de caracteres. • Quando o compilador da linguagem C encontra uma literal com n caracteres em um programa, ele aloca um vetor de caracteres com n+1 posições para armazenar a cadeia de caracteres correspondente. • Este vetor conterá os caracteres da cadeia mais um caractere extra, o caractere nulo, que registra o final da cadeia. • O caractere nulo é o caractere ’\0’ . 50 S is te m a s d e I n fo rm a ç ã o - C P T L Literais • É importante destacar a diferença entre o caractere nulo e o caractere zero: o primeiro é um caractere não-imprimível, tem valor decimal igual a 0 e representa o caractere ’\0’ (nulo); o segundo é um caractere imprimível, tem valor decimal igual a 48, e representa o caractere ‘0’ (zero decimal); • A literal “Ola!" é armazenada como um vetor de cinco caracteres na memória 51O l a ! \0 S is te m a s d e I n fo rm a ç ã o - C P T L Cadeias de caracteres • Se queremos trabalhar com variáveis que comportam mais que um único caracter, temos de trabalhar com cadeias de caracteres. • Cadeias de caracteres • Um vetor de caracteres sempre terminado pelo caractere nulo (\0). • Vantagem dessa estratégia: • Não é necessário manter outra variável que armazena o comprimento da cadeia de caracteres. • Desvantagem: • O comprimento de uma cadeia de caracteres só pode ser determinada por uma varredura pelo vetor. 52 S is te m a s d e I n fo rm a ç ã o - C P T L Cadeias de caracteres • Suponha que necessitamos de uma variável capaz de armazenar uma cadeia de caracteres de até 100 caracteres. Por exemplo, suponha que em uma parte do seu programa você pede o nome completo de uma pessoa e você assume que o nome não excederá 100 letras. #define MAX 100 char nome[MAX+1]; • Como a cadeia de caracteres necessitará de um caractere nulo (\0) no final, então o vetor de caracteres tem de ser declarado com 101 posições. • Na declaração de uma variável que pode armazenar uma cadeia de caracteres, sempre devemos reservar um compartimento a mais para que o caractere nulo possa ser armazenado. 53 S is te m a s d e I n fo rm a ç ã o - C P T L Cadeias de caracteres • A declaração de um vetor de caracteres com dimensão MAX+1 não quer dizer que ele sempre conterá uma cadeia de caracteres com MAX caracteres. • O comprimento de uma cadeia de caracteres depende da posição do caractere nulo na cadeia, não do comprimento do vetor onde a cadeia está armazenada. 54 S is te m a s d e I n fo rm a ç ã o - C P T L Cadeias de caracteres • Existem várias maneiras de ler e escrever uma cadeia de caracteres na tela. Veremos as duas mais simples. • Para escrever uma cadeia de caracteres na tela, simplesmente utilize a função printf e o formatador “%s”. printf(“%s\n”, nome); • Para ler uma cadeia de caracteres da tela, utilizaremos uma função nova da biblioteca stdio.h: gets(nome); 55 S is te m a s d e I n fo rm a ç ã o - C P T L Função gets • Para ler uma cadeia de caracteres da tela, utilizaremos uma função nova da biblioteca stdio.h: gets(nome); • A função gets lê os caracteres que o usuário digita na tela até que ele pressione enter, e então grava estes caracteres no vetor passado como parâmetro (no exemplo, o vetor nome); • O enter (‘\n’) não é gravado no vetor; • Depois de gravar a frase lida no vetor, a função gets grava o caractere nulo (‘\0’) por fim; 56 S is te m a s d e I n fo rm a ç ã o - C P T L Função gets • A variável frase tem que armazenar até 100 caracteres. Por que ela tem 101 posições? • Suponha que a frase digitada é “Ola”. Na linha 10, a função gets armazena “Ola” na variável frase da seguinte forma: • Note que a variável frase tem espaço para armazenar 100 caracteres + o ‘\0’. Neste caso,ela só armazena 3 caracteres + o ‘\0’. 57 O l a \0 0 1 2 3 S is te m a s d e I n fo rm a ç ã o - C P T L Inicialização • Como em qualquer vetor, uma cadeia de caracteres também pode ser declarada e inicializada simultaneamente. Por exemplo, char cidade[13] = "Campo Grande"; faz com que o compilador insira sequencialmente os caracteres da cadeia de caracteres "Campo Grande" no vetor cidade e então adicione o caractere nulo ao final da cadeia. A vetor cidade fica assim: 58C a m 0 1 2 p o 3 4 5 G r a 6 7 8 n d e 9 10 11 \0 12 S is te m a s d e I n fo rm a ç ã o - C P T L Declaração • Na linguagem C, as matrizes são declaradas similar- mente aos vetores: tipo nome[dimensão1][dimensão2]; tipo nome[linhas][colunas]; • Onde tipo denota o tipo da matriz. Se sua matriz é uma matriz de inteiros, então o tipo é int. Se sua matriz é uma matriz de doubles, então o tipo é double. • Nome é simplesmente o nome da matriz. • Dimensão1 ou linhas denota a quantidade de linhas da sua matriz. • Dimensão2 ou colunas denota a quantidade de colunas da sua matriz. 59 S is te m a s d e I n fo rm a ç ã o - C P T L Declaração • Na linguagem C, as matrizes são declaradas similar-mente aos vetores: tipo nome[dimensão1][dimensão2]; tipo nome[linhas][colunas]; • Essa declaração é idêntica à declaração de vetores... Mas vetores possuem apenas 1 dimensão, enquanto matrizes apresentam 2 dimensões... 60 S is te m a s d e I n fo rm a ç ã o - C P T L Declaração • Exemplo: int A[3][8]; • Declara uma matriz 3x8, onde cada posição ou célula é capaz de armazenar um valor inteiro (tipo int). • Como acontece com vetores, todas as posições da matriz começam inicializadas com lixo. 61 ? ? ? ? ? ? ? ? 0 1 2 0 1 2 3 4 5 6 7 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? S is te m a s d e I n fo rm a ç ã o - C P T L Registro • Em um registro podemos armazenar tipos de dados diferentes em uma mesma entidade • Cada um dos valores armazenados em um compartimento do registro é denominado de campo do registro, ou simplesmente campo S is te m a s d e I n fo rm a ç ã o - C P T L 62 Declaração • Podemos declarar um registro com identificador produto da seguinte forma: struct { int codigo; int quant; float valor; } produto; S is te m a s d e I n fo rm a ç ã o - C P T L 63 Declaração •A figura mostra a disposição do registro produto e seus campos na memória do computador S is te m a s d e I n fo rm a ç ã o - C P T L 64 Declaração • A declaração de um registro sempre inicia com a palavra struct • Em seguida, um bloco de declarações é iniciado com o símbolo { • Os campos do registro são então declarados (podem ser de tipos diferentes) S is te m a s d e I n fo rm a ç ã o - C P T L 65 Declaração • As declarações dos campos são finalizadas com o símbolo } • Depois de }, realizamos de fato a declaração do registro, digitando seu identificador • O registro produto declarado tem três campos, onde codigo e quant são inteiros e valor é um número real S is te m a s d e I n fo rm a ç ã o - C P T L 66 Declaração • Campos do mesmo tipo podem ser declarados na mesma linha, por exemplo: struct { char sala, turma; int h_inicio, m_inicio, h_fim, m_fim; float dimensoes_sala; } aula; Sis te m a s d e I n fo rm a ç ã o - C P T L 67 Atribuição • A atribuição de um valor a um campo de uma variável do tipo registro é realizada através do acesso a esse campo, especificando o identificador do registro, um ponto e o identificador do campo. • Por exemplo, se quisermos atribuir os valores para 12, 5 e 34.5 aos campos codigo, quant e valor, respectivamente: S is te m a s d e I n fo rm a ç ã o - C P T L 68 Atribuição • Observe que não é permitido o uso de espaços entre o identificador do registro, o ponto e o identificador do campo produto.codigo = 12; produto.quant = 5; produto.valor = 34.5; S is te m a s d e I n fo rm a ç ã o - C P T L 69 Utilização • Expressões lógicas também podem utilizar o valor dos campos de um registro, por exemplo: if (produto.valor > 150.0) printf("Acima do preço de mercado!\n"); S is te m a s d e I n fo rm a ç ã o - C P T L 70 Declaração •Declarações de registros diferentes podem conter campos com mesmo identificador, por exemplo: struct { char tipo; int fatorRH; int idade; float altura; } coleta; struct { char codigo; int tipo; int idade; } certidao; S is te m a s d e I n fo rm a ç ã o - C P T L 71 Declaração •Dessa forma, as seguintes atribuições são válidas: coleta.tipo = 'O'; certidao.tipo = 0; coleta.idade = 29; certidao.idade = coleta.idade + 2; S is te m a s d e I n fo rm a ç ã o - C P T L 72 Inicialização simultânea •A regra de inicialização simultânea também é válida para registros, ou seja, podemos inicializar seus campos no momento da declaração do registro. Valem as mesmas regras usadas para vetores. Exemplo: struct { int codigo; int quant; float valor; } produto = {1, 5, 34.5}; S is te m a s d e I n fo rm a ç ã o - C P T L 73 Inicialização simultânea • O campo codigo foi iniciado com o valor 1; quant com 5 e valor com 34.5 • Se quisermos que todos campos iniciem com valor zero: struct { int codigo; int quant; float valor; } produto = {0}; S is te m a s d e I n fo rm a ç ã o - C P T L 74 Operações • Às vezes é necessário copiar os elementos de uma estrutura para outra • Se A e B são, por exemplo, vetores de mesmo tipo de dados e mesma dimensão, é errado tentar fazer uma atribuição como: O mesmo vale para matrizes.A = B; S is te m a s d e I n fo rm a ç ã o - C P T L 75 Operações • Se quisermos copiar o conteúdo de um vetor para outro, é necessário realizar a cópia elemento por elemento: for (i = 0; i < n; i++) A[i] = B[i]; S is te m a s d e I n fo rm a ç ã o - C P T L 76 Operações • Em registros, no entanto, podemos fazer uma atribuição direta e realizar a cópia de todos seus campos nessa atribuição. Por exemplo: S is te m a s d e I n fo rm a ç ã o - C P T L 77 Exemplo de atribuição de registro struct { char tipo; int codigo; int quant; float valor; } mercadoria1, mercadoria2; mercadoria1.tipo = 'A'; mercadoria1.codigo = 10029; mercadoria1.quant = 62; mercatoria1.valor = 10.32 * TAXA + 0.53; mercadoria2 = mercadoria1; S is te m a s d e I n fo rm a ç ã o - C P T L 78 Definição de tipo •Uma estrutura pode ser usada para criar um novo tipo de dados próprio #include <stdio.h> // declaração de um novo tipo TEMPO typedef struct { int horas, minutos, segundos; } TEMPO; int main(void) { // declarando duas variáveis do tipo TEMPO TEMPO t1, t2; //... S is te m a s d e I n fo rm a ç ã o - C P T L 79 Vetor de registro • Podemos declarar um vetor com identificador cronometro: struct { int horas; int minutos; int segundos; } cronometro[10]; S is te m a s d e I n fo rm a ç ã o - C P T L 80 Vetor de registro •A declaração do vetor cronometro tem um efeito na memória que pode ser ilustrado com a seguinte figura: S is te m a s d e I n fo rm a ç ã o - C P T L 81 Vetor de registro •Atribuições de valores do tipo inteiro aos campos do registro do primeiro compartimento deste vetor cronometro podem ser feitas da seguinte forma: cronometro[0].horas = 20; cronometro[0].minutos = 39; cronometro[0].segundos = 18; S is te m a s d e I n fo rm a ç ã o - C P T L 82 Vetor de registro •Ainda podemos fazer atribuição direta de registro para registro •Então as atribuições a seguir realizam a troca de conteúdo das posições i e j struct { int horas; int minutos; int segundos; } cronometro[10], aux; aux = cronometro[i]; cronometro[i] = cronometro[j]; cronometro[j] = aux; S is te m a s d e I n fo rm a ç ã o - C P T L 83 Vetor de registro •Fazer a seguinte atribuição: •É o mesmo que:cronometro[i] = cronometro[j]; cronometro[i].horas = cronometro[j].horas; cronometro[i].minutos = cronometro[j].minutos; cronometro[i].segundos = cronometro[j].segundos; Si s te m a s d e I n fo rm a ç ã o - C P T L 84 Registro contendo variáveis compostas • Podemos declarar registros que contêm variáveis compostas como campos • Um exemplo muito comum é a declaração de um vetor de caracteres, ou uma cadeia de caracteres, dentro de um registro: struct { int dias; char nome[3]; } mes; S is te m a s d e I n fo rm a ç ã o - C P T L 85 Registro contendo variáveis compostas • Podemos fazer a seguinte atribuição válida ao registro mes: mes.dias = 31; mes.nome[0] = 'J'; mes.nome[1] = 'a'; mes.nome[2] = 'n'; S is te m a s d e I n fo rm a ç ã o - C P T L 86 Função Passagem de parâmetro • Conceitualmente, existem 3 tipos de parâmetros: • de entrada, que permitem que valores sejam passados para a função; • de saída, que permite que um valor seja devolvido da função; • de entrada e saída, que permitem que valores sejam passados para a função e devolvidos da função. S is te m a s d e I n fo rm a ç ã o - C P T L 87 Passagem de parâmetro • Até o momento, entramos em contato com parâmetros de entrada e parâmetros de saída nos programas que já fizemos • Os valores dos parâmetros de entrada são passados para uma função através de um mecanismo denominado passagem por cópia ou passagem por valor S is te m a s d e I n fo rm a ç ã o - C P T L 88 Função com impressão #include <stdio.h> void funcao(int num) { printf("%d\n", num); return; } int main(void) { int x; scanf("%d", &x); funcao(x); // chamada da funcao return 0; } S is te m a s d e I n fo rm a ç ã o - C P T L 89 Função quadrado #include <stdio.h> int quadrado(int num) { return (num*num); } int main(void) { int x; scanf("%d", &x); quadrado(x); // chamada da funcao return 0; } S is te m a s d e I n fo rm a ç ã o - C P T L 90 Função quadrado • Uma função que retorna algum valor deve ter seu resultado atribuído a alguma variável ou utilizado na escrita • Caso contrário, o resultado será perdido S is te m a s d e I n fo rm a ç ã o - C P T L 91 Função quadrado #include <stdio.h> int quadrado(int num) { return (num*num); } int main(void) { int x, result; scanf("%d", &x); result = quadrado(x); printf("%d\n", result); return 0; } S is te m a s d e I n fo rm a ç ã o - C P T L 92 Função quadrado • Uma função que retorna algum valor deve ter seu resultado atribuído a alguma variável ou utilizado na escrita • Caso contrário, o resultado será perdido S is te m a s d e I n fo rm a ç ã o - C P T L 93 Função quadrado • Na expressão • x é um argumento da função quadrado e é atribuído ao parâmetro correspondente da função • A passagem desse valor é feita por cópia, ou seja, o valor é copiado no parâmetro correspondente da função quadrado result = quadrado(x); S is te m a s d e I n fo rm a ç ã o - C P T L 94 Função zera • E se quiséssemos uma função que zerasse um inteiro passado como parâmetro? #include <stdio.h> void zera(int a) { a = 0; } int main(void) { int a; scanf("%d", &a); printf("%d\n", a); // impressão do valor lido zera(a); // função sem retorno que deveria zerar a printf("%d\n", a); // impressão depois de "zerar" return 0; } S is te m a s d e I n fo rm a ç ã o - C P T L 95 Função zera • O exemplo anterior não funciona porque o parâmetro a é passado como cópia • Ou seja, a variável a atribuída dentro da função é uma variável diferente de a lida na main, mas com o mesmo valor S is te m a s d e I n fo rm a ç ã o - C P T L 96 Parâmetro por referência • Valores de parâmetros de entrada e saída são passados/devolvidos por um mecanismo chamado referência • Uma variável especificada na chamada da função e um parâmetro especificado na interface da função compartilham a mesma área de armazenamento na memória • E isso significa que qualquer alteração realizada no conteúdo do parâmetro dentro da função acarreta alteração no conteúdo da variável do argumento S is te m a s d e I n fo rm a ç ã o - C P T L 97 Parâmetro por referência #include <stdio.h> void decompoe(float x, int *p_int, float *p_frac); int main(void) { float num, b; int a; printf("Informe um número real: "); scanf("%f", &num); decompoe(num, &a, &b); printf("Parte inteira: %d\n", a); printf("Parte fracionária: %f\n", b); return 0; } S is te m a s d e I n fo rm a ç ã o - C P T L 98 Parâmetro por referência • Note que os parâmetros p_int e p_frac vêm precedidos do símbolo * • Essa é a forma que definimos parâmetros de entrada e saída na linguagem C void decompoe(float x, int *p_int, float *p_frac) { *p_int = (int) x; *p_frac = x - *p_int; return; } S is te m a s d e I n fo rm a ç ã o - C P T L 99 Parâmetro por referência • Os parâmetros de entrada e saída sempre devem vir precedidos pelo símbolo * no corpo de uma função • A chamada da função decompoe na função main é ligeiramente diferente, como destacado abaixo: decompoe(num, &a, &b); S is te m a s d e I n fo rm a ç ã o - C P T L 100
Compartilhar