************************************* ********** LAB3 - Resumo C ********** ************************************* Data : 01/12/2002 Versão : 04/07/2007 Professor: Luís Alves Ferreira Autor : Leandro Salvador ( leandrosalvador.com.br ) * Ciclo de Desenvolvimento (analista) - determinar o objetivo do programa - determinar os metodos que serao usados para descreve-lo - criar o programa para solucionar o problema - executar o programa e avaliar seus resultados * Ciclo de Desenvolvimento (programador) - codigo fonte - compilar --> arquivo objeto - linkar --> arquivo executavel - executar - compilar --> gcc arquivo.c -o arquivo * Componentes do programa - #include - diretiva - acrescenta um arquivo de cabecalho ao programa durante a compilacao - prototipo de funcao - int teste(int x, int y); - variaveis - devem ser definidas antes de serem utilizadas - main(){} - funcoes * Variaveis - tipos de variaveis (arquitetura 32 bits) - char --> 1 byte - short --> 2 bytes - int --> 4 bytes - long --> 8 bytes - float --> 4 bytes - double --> 8 bytes - unsigned --> char, short, int, long - padrao ANSI (tamanho de variaveis) - char = 1 byte - short <= int - int <= long - unsigned = int - float <= double - typedef - cria um novo nome para um tipo de dados ja existente - cria um sinonimo - exemplo - typedef int integer - cria o sinonimo integer para o tipo de variavel int - extern - indica que a funcao usa uma variavel externa que e definida em outra parte do programa - exemplo - extern int x; - deve ser usado dentro de uma funcao, quando ja houver uma variavel externa int x - static x auto - por default, todas as variaveis sao automaticas (auto), ou seja, sao recriadas sempre que a funcao e chamada e destruidas quando a execucao do programa sai da funcao - se a funcao tiver que reter o valor de uma variavel local entre chamadas, deve-se defini-la como static - nao ha qualquer diferenca entre variaveis locais automaticas e estaticas dentro de main(), pois as variaveis definidas em main() sao criadas quando a execucao do programa e iniciada e duram ate o encerramento do programa - declaracao - static int x; - register - sugere ao compilador que uma variavel local automatica seja armazenada em um registrador do processador, nao na memoria convencional - so pode ser usada com variaveis numericas simples - nao pode ser usada com variaveis estaticas, variaveis externas, matrizes ou estruturas - nao se pode definir um ponteiro para uma variavel de registro - declaracao - register int x; - especificadores de conversão - %d --> número decimal inteiro sinalizado - %u --> número decimal inteiro não sinalizado - %f --> número decimal com ponto flutuante - %.2f --> numero decimal com ponto flutuante que deve ser impresso com dois algarismos a direita - %c --> um único caracter - %s --> string alfa numérico * Constantes - constantes numericas - decimal --> 1, -1 - octal --> 01, 07 - hexadecimal --> 0x01, 0xFF - constantes simbolicas - #define - diretiva de pre-processamento - exemplo - #define NOMECONST literal - #define PI 3.14159 - const - palavra-chave - exemplo - const char nomeconst = literal; - const float pi = 3.14159; * Instrucoes - if(){} - if(){} else{} - exp1 ? exp2 : exp3 - switch(){case 1: {... break;} default: {...}} - while(){} - do{} while(); - for( ; ; ){} - break; // interrompe o laco - continue; // reinicia o laco - exit(0); // interrompe o programa; - goto rotulo; - rotulo: ; * Funcao - antes dos metodos devem estar os prototipos das funcoes existentes no arquivo - parametro e um valor especificado no cabecalho da funcao - argumento e um valor transferido pelo programa de origem para a funcao - o argumento e acessado atraves da referencia ao nome do parametro correspondente - a unica limitacao de uma funcao e que nao pode-se definir uma funcao dentro de outra - prototipo da funcao - int teste(int x, int y); - definicao da funcao - int teste(int x, int y){} - deve retornar algum valor do tipo int - chamada da funcao por uma outra funcao - teste(x, y); - a funcao pode receber valores na forma de um ou mais argumentos e retornar um valor - existem 2 tipos de funcoes - com return - sem return - o tipo de retorno pode ser - void - char - int - long - float - double * Funcoes De Cabecalho - stdio.h - puts() - puts("Texto"); - exibe mensagem simples de texto - acrescenta automaticamente um caractere de mudanca de linha no seu final - printf() - printf("Texto %d", x); - exibe mensagem que inclua o valor de uma ou mais variaveis - scanf() - scanf("%d", &x); - scanf("%s", ponteiro); // le string - le dados do teclado e os atribui a uma ou mais variaveis - sizeof() - sizeof(tipo); - sizeof(int); - mostra o tamanho dos tipos de dados numericos - gets() - gets(ponteiro); - le dados do teclado e os atribui a um ponteiro - stdlib.h - exit() - exit(0); // programa terminou normalmente - exit(1); // programa terminou com algum tipo de erro - system() - system(comando); - system("dir"); // obtem o diretorio de um disco em DOS - char *comando = "dir"; system(comando); * Matriz - declaracao - tipo nome[tamanho]; - referencia - nome[indice]; - exemplo - int matriz1[10]; // matriz unidimensional - int matriz2[10, 10]; // matriz bidimensional - int matriz3[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // matriz unidimensional inicializada - area de armazenamento = numero de elementos * tamanho do tipo dos elementos - nao deve ser maior do que 64 kB de dados * Ponteiro - ponteiros sao variaveis que armazenam enderecos de memoria onde estao os dados - ponteiros armazenam enderecos de memoria - ponteiros apontados para enderecos invalidos sao chamados "dangling pointers" - ponteiros devem sempre ser inicializados (apontados para algo) antes de serem usados - declaracao - tipo *ponteiro; - ponteiro = &variavel; - acessar o conteudo de uma variavel usando seu nome e chamado de acesso direto - acessar o conteudo de uma variavel usando um ponteiro e chamado de acesso indireto, ou indirecao - exemplo (instrucoes equivalentes) - printf("%d", variavel); - printf("%d", *ponteiro); - se *ponteiro = variavel - *ponteiro e variavel referem-se ao conteudo de variavel - ponteiro e &variavel referem-se ao endereco de variavel - operacoes aritmeticas com ponteiros - um ponteiro aponta para o primeiro elemento de uma matriz - deve ser incrementado com um valor equivalente ao tamanho do tipo de dados utilizado pela matriz - o incremento dos ponteiros permite que o programa acesse eficientemente todos os elementos de uma matriz - um nome de matriz sem os colchetes e um ponteiro para o primeiro elemento dessa matriz - array[] --> matriz declarada - *array --> primeiro elemento dessa matriz - *(array + 1) --> segundo elemento dessa matriz - acesso de elementos de uma matriz - int array[10]; // declara uma matriz - int *ponteiro; // declara um ponteiro - ponteiro = array; // inicializa o ponteiro - for(cont = 0; cont < 10; cont++) printf("%d", *ponteiro++); // imprime os elementos da matriz (usando notacao de ponteiros) - for(cont = 0; cont < 10; cont++) printf("%d", array[cont]; // imprime os elementos da matriz (usando notacao de indices de matrizes) - subtracao de dois ponteiros (diferenciacao) - a partir de dois ponteiros para elementos diferentes de uma mesma matriz, e possivel fazer a subtracao de um pelo outro para se descobrir qual e a distancia entre esses elementos - passando matrizes para funcoes - a unica maneira de se fazer isso e usando um ponteiro - para passar toda uma matriz para uma funcao pode-se usar um ponteiro que aponte para essa matriz - o ponteiro em si e um valor numerico simples (o endereco do primeiro elemento da matriz) - ao se passar esse valor para uma funcao, ela recebera o endereco da matriz e podera acessar os elementos da matriz usando a notacao de ponteiros - para se descobrir o tamanho de uma matriz, passamos o proprio tamanho da matriz como um argumento para a funcao - int maior(int *matriz, int tamanho){} - int maior(int matriz[], int tamanho){} - tanto *matriz como matriz[] significam "ponteiro para int" - x[contagem] e igual a *(x + contagem) * Char - deve ser unsigned char para ASCII estendido, pois vai de 0 a 255; - declaracao - unsigned char c1 = 'a'; - unsigned char c2 = 90; - char string[10]; // pode conter uma string com nove caracteres ou menos - char string[10] = {'T', 'e', 's', 't', 'e', '\0'}; - char string[10] = "Teste"; - char string[] = "Teste"; // cria e inicializa uma matriz de 6 elementos - char *string = "Teste"; // armazena em algum ponto da memoria e o ponteiro mensagem sera inicializado para apontar para o seu primeiro caractere - alocar espaco de memoria em tempo de compilacao - char string[] = "Teste"; e igual a char *string = "Teste"; ambas significam "um ponteiro para" - alocar espaco de memoria em tempo de execucao (funcao malloc()) - aloca um bloco de memoria correspondente ao numero de bytes armazenado em tamanho - void *malloc(tamanho); - aloca um bloco de 35 bytes - char *ptr; - ptr = malloc(35 * sizeof(char)); - exibir texto na tela - char *mensagem = "Teste"; - puts(mensagem); - printf("%s", mensagem); - ler strings do teclado - char input[10]; - puts("Digite um texto, depois pressione Enter"); - gets(input); * Estruturas - uma estrutura e uma colecao de uma ou mais variaveis agrupadas sob um unico nome para facilitar sua manipulacao - as variaveis de uma estrutura, ao contrario das variaveis de uma matriz, podem ser de diferentes tipos de dados - uma estrutura pode conter quaisquer tipos de dados validos em C, inclusive matrizes e ate mesmo outras estruturas - cada variavel dentro de uma estrutura e chamada de membro da estrutura - declaracao - struct rotulo { membros da estrutura } instancia; - struct coord { // contem as duas coordenadas necessarias para referenciar um unico ponto na tela int x; int y; }; struct coord primeira, segunda; // declara duas estruturas que sao instancias do tipo coord - struct retangulo { // contem as quatro coordenadas necessarias para referenciar um retangulo na tela struct coord esqcima; struct coord dirbaixo; }; struct retangulo meuquadrado; // declara uma estrutura que e instancia do tipo retangulo - struct data { int x[4]; char y[10]; }; struct data registro; // declara uma estrutura que e instancia do tipo data - struct entrada { char nome[20]; char sobrenome[20]; char fone[10]; }; struct entrada lista[1000]; // declara uma matriz que contem 1000 elementos do tipo entrada - struct peca { int numero; char nome[10]; }; struct peca *p_peca // declara um ponteiro para o tipo peca struct peca traquitana; // declara uma estrutura que e instancia do tipo peca p_peca = &traquitana; // atribui o endereco de traquitana a p_peca - acessando os membros de uma estrutura - primeira.x = 50; primeira.y = 100; primeira = segunda; e equivalente a primeira.x = segunda.x; primeira.y = segunda.y; - meuquadrado.esqcima.x - refere-se ao membro x do membro esqcima da estrutura meuquadrado que e do tipo retangulo - registro.x[2] = 100; registro.y[1] = 'x'; registro.y; // ponteiro para o primeiro elemento da matriz y dentro da estrutura registro puts(registro.y); // imprime o conteudo de y[] - lista[1] = lista[5] - atribui a cada membro da estrutura lista[1] os valores contidos nos membros correspondentes de lista[5] strcpy(lista[1].fone, lista[5].fone); - copia o string armazenado em lista[5].fone para lista[1].fone lista[5].fone[1] = lista[1].fone; - move o segundo caractere do numero de telefone armazenado em lista[5] para a quarta posicao do numero de telefone armazenado em lista[1] - (*p_peca).numero = 100; e equivalente a p_peca -> numero; - pode-se acessar um membro de uma estrutura - estrutura.membro --> nome da estrutura - (*ponteiro_estrutura).membro --> ponteiro para a estrutura com o operador de indirecao (*) - ponteiro_estrutura -> membro --> ponteiro para a estrutura - typedef e estruturas - cria um sinonimo para um tipo de estrutura ou uniao - exemplo - typedef struct { int x; int y; } coord; coord esqcima, dirbaixo; * Unioes - as unioes sao definidas e declaradas exatamente como as estruturas - uma estrutura pode conter varios valores - uma uniao pode conter um valor de cada vez apenas - uma uniao e uma colecao de uma ou mais variaveis agrupadas sob um nome comum - todos os membros da uniao ocupam uma mesma area de memoria - declaracao - union rotulo { membros da uniao } instancia; - union comum { char c; int i; }; - acessando os membros de uma uniao - union comum variavel_generica = {'0'}; * Lista Encadeada - a estrutura inclui um ponteiro para o seu proprio tipo - numa lista encadeada cada estrutura aponta para a proxima estrutura da lista - qualquer lista deve ter um comeco e um fim - o comeco da lista e sinalizado pelo ponteiro de cabecalho, que aponta para a primeira estrutura da lista - o ponteiro de cabecalho nao e uma estrutura, mas simplesmente um ponteiro que aponta para o tipo de dados usado na lista - o final da lista e sinalizado por uma estrutura cujo ponteiro inteiro tem o valor NULL - como todas as demais estruturas da lista possuem ponteiros com valores diferentes de NULL, opis devem apontar para o proximo item da lista, o valor NULL em um ponteiro e um sinal inconfundivel de que a lista chegou ao seu final - as listas encadeadas facilitam enormemente a insercao e remocao de itens de dados em uma lista ordenada (alfabeticamente, por exemplo) - declaracao - struct dados { char nome[10]; float valor; struct dados *proxima; }; - alocar espaco na memoria (malloc()) - struct dados *ponteiro; ponteiro = malloc(sizeof(struct dados)); ponteiro -> valor = 1.025 * Streams - todas as operacoes de entrada/saida em C, seja qual for a origem ou destino dos dados, utilizam streams - entrada --> teclado, arquivos em disco - saida --> tela, impressora, arquivos em disco - stream --> sequencia de caracteres (bytes de dados) - stream de entrada --> sequencia de bytes fluindo na direcao do programa - stream de saida --> sequencia de bytes saindo do programa - streams oferece a vantagem de a programacao de entrada/saida ser independente de dispositivos - programa lida com os dados recebidos ou transmitidos como uma sequencia continua de bytes, independente do dispositivo de entrada ou saida - todos os streams em C estao associados a um arquivo - arquivo --> passo intermediario entre o stream com o qual o programa esta lidando e o dispositivo fisico real que esta sendo usado para a entrada ou saida de dados - stream de texto - somente caracteres - organizado em linhas - podem conter ate 255 caracteres - sempre terminam com um caractere de fim linha - stream binario - qualquer tipo de dados, inclusive dados de texto - bytes de dados contidos em um stream binario nao sao traduzidos ou interpretados de qualquer maneira especial - sao lidos ou escritos exatamente como estao - usados principalmente com arquivos em disco - arquivos padrao de entrada e saida - a linguagem C ANSI possui cinco streams pre-definidos - abertos automaticamente quando um programa comeca a ser executado - fechado quando a execucao termina - streams-padrao (texto) - stdin --> entrada-padrao --> teclado - stdout --> saida-padrao --> tela - stderr --> erro-padrao --> tela - stdprn --> impressora-padrao --> impressora (LPT1) - stdaux --> auxiliar-padrao --> porta-serial (COM1) - printf() e puts() usam stdout - scanf() e gets() usam stdin - streams-padrao sao abertos automaticamente - outros streams devem ser abertos explicitamente - como os utilizados para manipular informacoes armazenadas em disco - funcoes de entrada/saida de streams - printf() --> fprintf() --> saida de dados formatada - puts() --> fputs() --> saida de strings - putchar() --> fputc() --> saida de caracteres - scanf() --> fscanf() --> entrada de dados formatada - gets() --> fgets() --> entrada de strings - getchar() --> fgetc() --> entrada de caracteres - arquivos de cabecalho - stdio.h - stdlib.h - stdargs.h - conio.h - entrada de dados - funcoes de entrada de caracteres - recebem dados de um stream de entrada, um caractere por vez - retornam o proximo caractere do stream ou EOF (se atingiu o final do arquivo) - EOF --> constante simbolica definida em stdio.h como -1 - buffer --> sistema operacional armazena todos os caracteres em um espaco temporario ate que se aperte a tecla Enter e entao os envia para o stream stdin - eco --> repetem ("ecoam") os caracteres para stdout a medida em que sao recebidos, exibindo-os na tela - nao ecoa os caracteres --> envia os caracteres para stdin e nao para stdout - getchar() - obtem o proximo caractere do stream stdin - usa buffer - usa eco - pode ser usada para receber linhas inteiras de texto - getch() - le o proximo caractere do stream stdin - nao usa buffer - nao usa eco - getche() - le o proximo caractere do stream stdin - nao usa buffer - usa eco - receber teclas especiais (estendidas) - F1 a F12, setas, etc... - precisa-se saber como essas teclas especiais e combinacoes de teclas funcionam - codigos estendidos de teclado - enviam um par de valores para stdin, nao apenas um valor - primeiro valor --> caractere null com valor numerico 0 - segundo valor --> valor numerico que identifica a tecla pressionada - exemplo - F1 --> 0 seguido de 59 - Home --> 0 seguido de 71 - funcoes de entrada de linhas - recebem dados de um stream de entrada, todos os caracteres ate o proximo caractere de mudanca de linha - gets() - aceita como argumento um ponteiro para o tipo char - retorna um ponteiro para o tipo char - caracteres sao lidos de stdin ate que seja encontrado um caractere de nova linha (\n) ou final de arquivo (EOF) - caractere \n e substituido por um caractere null e o string e armazenado no endereco indicado pelo argumento - o valor de retorno e um ponteiro para o string - fgets() - opera de maneira semalhante a funcao gets() - permite que o programador especifique o nome de um stream de entrada que deve ser usado - permite que o programador especifique o numero maximo de caracteres que devem ser recebidos - permite ler texto a partir de arquivos em disco - para usar fgets() na leitura de dados a partir de stdin, deve-se especificar stdin como stream de entrada - prototipo - char *fgets(char *str, int n, FILE *fp); - FILE *fp --> usado para especificar o stream de entrada - funcoes de entrada formatada - interpreta (formata) os dados recebidos - permite atribuir uma sequencia de caracteres recebidos a variaveis numericas - scanf() - aceita um numero variavel de argumentos - exige no minimo dois argumentos - primeiro argumento --> string de formato que utiliza caracteres especiais para indicar a funcao como os dados recebidos devem ser interpretados - segundo argumento em diante --> enderecos da variavel ou variaveis as quais os dados recebidos devem ser atribuidas - exemplo - scanf("%d", &x); - %d --> string de formato que indica que o valor inteiro obtido deve ser sinalizado - &x --> operador de endereco de que indica que o valor recebido deve ser atribuido a variavel x - saida de dados para a tela --> PAREI EM aula14.pdf pag 18 ----------//----------