apostila de c - simplificada

13

Click here to load reader

Upload: wallace-de-santa

Post on 23-Sep-2015

223 views

Category:

Documents


2 download

DESCRIPTION

Apostila de C smplifcda

TRANSCRIPT

  • APOSTILA I

    Programao modular em C Por programao modular, entende-se a tcnica de se dividir o cdigo de um determinado programa em partes, de forma a reutilizar suas funes e procedimentos. A linguagem C permite a modularizao por meio de funes. importante perceber que, dependendo da linguagem de programao, funo so chamadas tambm de procedimentos ou mtodos. Em C optou-se por preservar o nome funo, tanto para funes que retornam valores quanto para aquelas que no o fazem. Veja a seguir uma funo que recebe um arquivo do tipo texto e o escreve na tela: void escrever(char *texto){ printf(texto); } Uma chamada a esta funo pode ser feita da seguinte forma: escrever("Gosto muito de C"); Observe o uso da palavra-chave void para indicar que a funo no retorna nenhum valor. Veja o cdigo completo para fins de estudo: #include #include void escrever(char *texto){ printf(texto); } int main(int argc, char *argv[]) { escrever("Gosto muito de C"); printf("\n\n"); system("PAUSE"); return 0; } Vejamos agora uma funo que retorna um valor: int somar(int a, int b){ return (a + b); } Esta funo recebe dois argumentos e exibe sua soma. Uma chamada a ela pode ser feita da seguinte forma:

  • int res = somar(4, 6); Para fins de estudo, eis o cdigo completo: #include #include int somar(int a, int b){ return (a + b); } int main(int argc, char *argv[]) { int res = somar(4, 6); printf("%d", res); printf("\n\n"); system("PAUSE"); return 0; } Exerccios: 1) Escreva uma funo que retorna a quantidade de caracteres em uma string fornecida como argumento. Dica: Strings em C podem ser criadas da seguinte forma: char texto[] = "C e Java so linguagens muito teis"; ou: char texto[100] = "C e Java so linguagens muito teis"; ou: char *texto = "C e Java so linguagens muito teis"; 2) Escreva uma funo que recebe duas strings como argumento e retorne a concatenao destas: Dica: use a funo strcat() para concatenar as duas strings. 3) Escreva uma funo que receba dois inteiros e retorne o resultado do primeiro elevado potencia do segundo. Obs: Use laos. No permitido usar a funo pow() do header math.h.

  • 4) Escreva uma funo que retorne a quantidade de ocorrncias de um determinado caractere em uma string. Dica: Use o operador de ndice [] para acessar o caractere individual de uma string.

    Saiba mais sobre true e false em C e C++ Em praticamente todas as linguagens de programao ns encontramos expresses condicionais que definem o fluxo de execuo. Expresses condicionais so aquelas que, quando avaliadas, resultam em um valor true (verdadeiro) ou false (falso). Muitas linguagens de programao possuem um tipo booleano que armazena os valores true ou false. Enquanto o C++ possui o tipo bool, o C possui uma forma bem interessante de definir true ou false. Em C, um valor true qualquer valor diferente de 0, incluindo numeros negativos. Veja: #include #include int main(int argc, char *argv[]) { int pode = 1; // verdadeiro int nao_pode = 0; // falso if(pode) printf("Teste resultou verdadeiro\n\n"); if(!nao_pode) printf("Teste resultou verdadeiro\n\n"); system("PAUSE"); return 0; } Lembre-se ento. False em C o valor zero. Qualquer outro valor true. Embora C++ j possua o tipo bool, possvel usar a abordagem do zero para false e qualquer outro valor para true em C++ tambm. Voc ver muito cdigo legado usando este artifcio. Quer ver algo interessante agora? Execute o seguinte cdigo C++: #include #include using namespace std; int main(int argc, char *argv[]){ bool pode = true; bool nao_pode = false;

  • cout
  • printf("\n\n"); system("PAUSE"); return 0; } Neste cdigo ns temos a declarao e definio de duas variveis: int valor = 10; int *p = &valor; A primeira varivel uma varivel do tipo int e a segunda um ponteiro para uma varivel do tipo int. Veja que devemos sempre usar "*" antes do nome de um ponteiro em sua declarao. O smbolo "&" serve para indicar que estamos acessando o endereo de uma varivel e no o seu contedo. O resultado destas duas linhas que agora temos um ponteiro que nos permite acessar e manipular a varivel valor. Observe a linha: printf("%d", *p); Aqui ns estamos acessando o valor da varivel apontada por p. Veja o uso do smbolo "*" para acessar o valor da varivel. Isso chamado de desreferenciamento de ponteiros. Pareceu complicado? Veja uma linha de cdigo que altera indiretamente o valor da varivel valor para 30: *p = 30; Ponteiros so ferramentas muito importantes na programao em C. No entanto, preciso ter muito cuidado ao lidar com eles. A primeira coisa a ter em mente que um ponteiro no est apontando para nenhum lugar at que atribuimos a ele o endereo de uma outra varivel. E a que mora o perigo. Um programa entra em colapso absoluto se tentarmos acessar um ponteiro que aponta para um local de memria que j foi liberado novamente ao sistema. No caso menos grave, estaremos tentando acessar locais de memria invlidos ou reservados a outros programas ou tarefas do sistema operacional. Isso nos lembra os velhos tempos da tela azul de morte.

    Obtendo o tamanho de um ponteiro em bytes em C Muitas vezes precisamos saber a quantidade de bytes que alocada quando declaramos uma varivel do tipo ponteiro. Veja como isso pode ser feito no trecho de cdigo a seguir: #include #include int main(int argc, char *argv[]) { // ponteiro para uma varivel do tipo float

  • float *p; // obtm o tamanho de p em bytes int tam = sizeof(p); // exibe o resultado printf("O tamanho do ponteiro e: %d bytes", tam); printf("\n\n"); system("PAUSE"); return 0; } No se esquea de que uma varivel do tipo ponteiro guarda o endereo de outra varivel. Desta forma, o valor armazenado em um ponteiro sempre do tipo int, que 2 bytes em sistemas de 16 bits, 4 bytes em sistemas de 32 bits e 8 bytes em sistemas de 64 bits. Exerccios: 1) Escreva um programa que permita obter o tamanho em bytes dos tipos de dados: int, long, float, double e char. 2) Escreva um programa que use um ponteiro do tipo int para acessar, alterar e exibir os valores de outras trs variveis tambm do tipo int. 3) Modifique o programa do item 2 para trabalhar com ponteiro e variveis do tipo float. 4) Crie um programa que permita usar um ponteiro para percorrer todos os elementos de uma matriz.

    Funes e a passagem por valor e por referncia A linguagem C permite que argumentos sejam passados s funes de duas formas distintas: por valor e por referncia. Na passagem por valor, alteraes no valor da varivel no corpo da funo no afetam a varivel original. Veja um exemplo: #include #include void alterar(int valor){ valor = 10; } int main(int argc, char *argv[]) { int valor = 5;

  • alterar(valor); printf("%d", valor); printf("\n\n"); system("PAUSE"); return 0; } Veja que ao imprimirmos o valor da varivel valor o resultado ser 5, e no 10, como poderamos pensar. Observe agora um exemplo de passagem de argumentos por referncia: #include #include void alterar(int *val){ *val = 10; } int main(int argc, char *argv[]) { int valor = 5; alterar(&valor); printf("%d", valor); printf("\n\n"); system("PAUSE"); return 0; } Agora o valor a ser impresso ser 10. Observe que, ao efetuar a chamada funo alterar, ns estamos usando o operador & para indicar a posio da varivel valor na memria. Isso permite que seu valor seja alterado como pretendamos.

    Alocando memria usando a funo malloc() A funo malloc() usada em C para alocarmos um bloco de memria. Esta funo recebe a quantidade de bytes a serem alocados e retorna um ponteiro do tipo void (genrico) para o incio do bloco de memria obtido. Veja sua assinatura: void *malloc(size_t size); Se a memria no puder se alocada, um ponteiro nulo (NULL) ser retornado. importante se lembrar de alguns conceitos antes de usar esta funo. Suponhamos que voc queira alocar memria para um inteiro. Voc poderia ter algo assim:

  • // aloca memria para um int ponteiro = malloc(4); Embora este cdigo esteja correto, no um boa idia assumir que um inteiro ter sempre 4 bytes. Desta forma, melhor usar o operador sizeof() para obter a quantidade de bytes em um inteiro em uma determinada arquitetura. Veja: // aloca memria para um int ponteiro = malloc(sizeof(int)); Eis o cdigo completo para um aplicativo C que mostra como alocar memria para um inteiro e depois atribuir e obter o valor armazenado no bloco de memria alocado: #include #include int main(int argc, char *argv[]) { // ponteiro para uma varivel do tipo inteiro int *ponteiro; // aloca memria para um int ponteiro = malloc(sizeof(int)); // testa se a memria foi alocada com sucesso if(ponteiro) printf("Memoria alocada com sucesso.\n"); else printf("Nao foi possivel alocar a memoria.\n"); // atribui valor memria alocada *ponteiro = 45; // obtm o valor atribudo printf("Valor: %d\n\n", *ponteiro); // libera a memria free(ponteiro); system("PAUSE"); return 0; } Uma aplicao interessante da funo malloc() quando precisamos construir uma matriz dinmica. Veja como isso feito no cdigo abaixo: #include #include int main(int argc, char *argv[])

  • { int i; // quantidade de elementos na matriz int quant = 10; // ponteiro para o bloco de memria int *ponteiro; // aloca memria para uma matriz de inteiros ponteiro = malloc(quant * sizeof(int)); // testa se a memria foi alocada com sucesso if(ponteiro) printf("Memoria alocada com sucesso.\n"); else{ printf("Nao foi possivel alocar a memoria.\n"); exit(1); } // atribui valores aos elementos do array for(i = 0; i < quant; i++){ ponteiro[i] = i * 2; } // exibe os valores for(i = 0; i < quant; i++){ printf("%d ", ponteiro[i]); } // libera a memria free(ponteiro); printf("\n\n"); system("PAUSE"); return 0; }

    Alocando memria dinmica usando a funo calloc() A funo calloc() bem parecida com a funo malloc() e tambm usada em C para alocarmos um bloco de memria. A diferena que calloc() recebe a quantidade de elementos e o nmero de bytes do elemento e retorna um ponteiro do tipo void (genrico) para o incio do bloco de memria obtido. Veja sua assinatura: void *calloc(size_t n, size_t size); Se a memria no puder se alocada, um ponteiro nulo (NULL) ser retornado. importante se lembrar de alguns conceitos antes de usar esta funo. Suponhamos que voc queira alocar memria para um nico inteiro. Voc poderia ter algo assim:

  • // aloca memria para um int ponteiro = calloc(1, 4); Embora este cdigo esteja correto, no um boa idia assumir que um inteiro ter sempre 4 bytes. Desta forma, melhor usar o operador sizeof() para obter a quantidade de bytes em um inteiro em uma determinada arquitetura. Veja: // aloca memria para um int ponteiro = calloc(1, sizeof(int)); Eis o cdigo completo para um aplicativo C que mostra como alocar memria para um inteiro e depois atribuir e obter o valor armazenado no bloco de memria alocado: #include #include int main(int argc, char *argv[]) { // ponteiro para uma varivel do tipo inteiro int *ponteiro; // aloca memria para um int ponteiro = calloc(1, sizeof(int)); // testa se a memria foi alocada com sucesso if(ponteiro) printf("Memoria alocada com sucesso.\n"); else printf("Nao foi possivel alocar a memoria.\n"); // atribui valor memria alocada *ponteiro = 45; // obtm o valor atribudo printf("Valor: %d\n\n", *ponteiro); // libera a memria free(ponteiro); system("PAUSE"); return 0; } Uma aplicao interessante da funo calloc() quando precisamos construir uma matriz dinmica. Veja como isso feito no cdigo abaixo: #include #include

  • int main(int argc, char *argv[]) { int i; // quantidade de elementos na matriz int quant = 10; // ponteiro para o bloco de memria int *ponteiro; // aloca memria para uma matriz de inteiros ponteiro = calloc(quant, sizeof(int)); // testa se a memria foi alocada com sucesso if(ponteiro) printf("Memoria alocada com sucesso.\n"); else{ printf("Nao foi possivel alocar a memoria.\n"); exit(1); } // atribui valores aos elementos do array for(i = 0; i < quant; i++){ ponteiro[i] = i * 2; } // exibe os valores for(i = 0; i < quant; i++){ printf("%d ", ponteiro[i]); } // libera a memria free(ponteiro); printf("\n\n"); system("PAUSE"); return 0; }

    Estruturas (struct) em C Matrizes (arrays) so muito importantes quando precisamos agrupar vrias variveis de um mesmo tipo de dados. Porm, h casos em que precisamos agrupar variveis de diferentes tipos. Para estes casos a linguagem C nos fornece as estruturas (struct). Veja como declar-las: // uma estrutura Pessoa struct Pessoa { char *nome;

  • int idade; }; Veja que esta estrutura possui dois tipos de dados diferentes: um ponteiro para uma cadeia de caracteres e uma varivel do tipo int. Para declarar variveis do tipo Pessoa voc tem duas opes. A primeira consiste em declarar as variveis juntamente com a declarao da estrutura. Veja: // uma estrutura Pessoa struct Pessoa { char *nome; int idade; }pessoa, cliente, chefe; A outra forma consiste em declarar a varivel no local no qual ela ser usada. Esta forma mais prtica. Veja um exemplo completo de como isso feito: #include #include // uma estrutura Pessoa struct Pessoa { char *nome; int idade; }; int main(int argc, char *argv[]) { // declara uma varivel do tipo struct struct Pessoa cliente; cliente.nome = "Osmar J. Silva"; cliente.idade = 36; // obtm os dados printf("O nome do cliente e: %s\n", cliente.nome); printf("A idade do cliente e: %d\n", cliente.idade); printf("\n\n"); system("PAUSE"); return 0; }

  • Exerccio: Faa um programa em C que troca 2 valores usando ponteiros.