Lista 1 - Linguagem de Programação C
Obs.: Soluções alternativas para as correções dos problemas dos exercícios foram consideradas durante a correção.
9. Verificação da resposta do usuário (1,5)
É sempre recomendado verificar se o usuário fornece uma resposta válida frente a um conjunto de opções. Modifique o programa a seguir, utilizando a seqüência do-while, de modo a repetir o menu de opções sempre que esta for inválida. No programa a seguir, a execução é abortada se a opção for inválida.
/* prog9.c */
#include <stdio.h>
int main()
{
char x;
// O início do comando do-while deve estar antes da apresentação
do menu
// para que este seja repetido sempre que a opção for inválida
(de acordo
// com o pedido no enunciado do exercício).
//
do
{
printf("1. inclusao\n");
printf("2. alteracao\n");
printf("3. exclusao\n");
printf(" Digite sua opcao:");
x=getchar();
switch(x)
{
case '1':
/* sequencia de comandos para x == 1 */
break;
case '2':
/* sequencia de comandos para x == 2 */
break;
case '3':
/* sequencia de comandos para x == 3 */
break;
// A opção default do comando switch deve ser mantida para
que a
// mensagem "Opcao invalida" seja apresentada, se este for o caso.
//
// O comando exit(1) desta opção deve ser eliminado para
que o
// programa não mais termine sua execução caso a opção
seja inválida.
//
default:
printf("Opcao invalida\n");
// comando usado apenas para ler o caracter "\n" (referente
// a tecla "enter" que está no buffer, antes de ler a nova opção.
//
getchar();
}
} while (x != '1' && x != '2' && x != '3');
/* demais
comandos do programa */
}
10. Manipulação de strings (1,5)
Há várias funções para manipulação de strings, sendo importante destacar strcat(), strcmp(), strlen() e strcpy(). Estas funções estão definidas na biblioteca <string.h>. Escreva um programa que leia do teclado uma senha alfanumérica, utilize a função strcmp() para compará-la com uma senha definida internamente no programa e retorne ao usuário a validade ou não da senha fornecida por ele, em função do resultado da comparação.
/* prog10.c */
#include
<stdio.h>
#include
<string.h>
main()
{
// variável usada para armazenar a senha, a qual pode ser qualquer
arranjo de
// caracteres.
char *senha = "asdfgh"; //
poderia ser também: char senha[7] = "asdfgh";
// variável usada para armazenar a senha entrada pelo usuário.
char s[7];
printf ("Informe a senha: ");
gets(s);
// poderia ser também: scanf("%s",
s);
if (!(strcmp(s, senha))) //
poderia ser também: if (strcmp(s, senha) == 0)
printf("Senha Válida.\n");
else
printf("Senha Inválida.\n");
}
11. Passagem de parâmetros para função (2,0)
O programa abaixo toma dois dados inteiros recebidos pelo teclado e deveria imprimi-los em ordem crescente. Explique por que o programa não funciona corretamente e introduza as correções mínimas necessárias para torná-lo operante.
O programa não funciona corretamente porque a passagem de parâmetros para a função troca está sendo feita de forma errada. Ela está sendo feita por valor, assim a função troca manipula apenas valores de variáveis locais à função (ou seja, apenas cópias das variáveis dado1 e dado2, declaradas na função main). Para o programa funcionar corretamente, a passagem de parâmetros para a função troca deve ser feita por referência, assim a função manipularia os valores das próprias variáveis dado1 e dado2, declaradas na função main. A seguir, encontram-se as correções para que a passagem de parâmetros seja por referência:
/* prog11.c */
#include <stdio.h>
int main()
{
int dado1,
dado2;
void troca(int
*,
int *);
printf("Entre
com dois dados inteiros: ");
scanf("%d
%d",&dado1, &dado2);
troca(&dado1,
&dado2);
printf("Dados
em ordem crescente: %d \t %d \n", dado1, dado2);
return
0;
}
void troca(int *dado1,
int *dado2)
{
int temp;
if(*dado1
> *dado2)
{
temp = *dado1;
*dado1 = *dado2;
*dado2 = temp;
}
}
12. Linha de comando com argumentos (2,0)
É possível criar programas em C que aceitem argumentos na linha de comandos. A variável argc conterá o número de argumentos mais 1, e argv é um arranjo de ponteiros para strings, que irão apontar para posições de memória que recebem o nome do programa executável e a lista de argumentos.
Explique por que é necessário o uso da função atoi(), que converte um caractere para um inteiro.
Porque a variável (cont) usada no comando for e o segundo argumento (argv[1]) da linha de comandos são de tipos diferentes. Enquanto que a variável cont é do tipo inteiro, o argumento argv[1] é do tipo string (ponteiro para caracteres). Assim, para que a variável cont possa receber o conteúdo de argv[1], este conteúdo deve ser primeiramente convertido para inteiro.
Quantas são as opções de argumentos?
São três opções:
Levando em consideração que os argumentos passados são do tipo certo:
#include <stdio.h>
int main(int argc,char *argv[])
{
int disp,cont;
if(argc
< 2)
{
printf("Falta digitar o valor para contagem\n");
exit(1);
}
if ((argc
== 3) && (!strcmp(argv[2],"mostra")))
disp = 1;
else
disp = 0;
for(cont=atoi(argv[1]);cont;--cont)
if(disp)
printf("%d\n",cont);
printf("%c",7);
}
17. Strings: ponteiros, arranjos e alocação dinâmica (2,0)
O programa a seguir apresenta problemas de implementação. Discrimine os problemas e proponha uma alternativa para eliminá-los, garantindo a execução da operação desejada. As linhas de código em que está presente a seqüência de comentário em branco (/* */) devem ser mantidas inalteradas no código alternativo a ser gerado, podendo ser introduzido código adicional entre estas linhas.
Problemas:
Existe incompatibilidades entre a declaração e o uso de algumas variáveis:
1) mens1: é declarada como um arranjo de caracteres (string), mas a sua atribuição é feita de forma incorreta. As possíveis soluções para este problema são:
char *mens2;
mens2 = malloc(100); /* */
*mens2 = " aa lista de exercicios do curso EA877!\n";
Assim,
duas opções possíveis para que o programa não
apresente problemas de implementação, são:
/* prog17.c */
/* Este programa aceita o
primeiro nome digitado pelo usuario e compoe uma frase a ser apresentada
na tela */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *nome,mens1[100],*mens2;
mens2 = malloc(100); /* */
printf("Qual
e' seu nome? "); /* */
scanf("%s",nome);
/* */
strcpy(mens1, "Bem-vindo, ");
*mens2 = " aa lista de exercicios do curso EA877!\n";
printf("%s%s%s",mens1,nome,mens2);
/* */
return
0;
}
/* prog17.c */
/* Este programa aceita o
primeiro nome digitado pelo usuario e compoe uma frase a ser apresentada
na tela */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *nome,*mens1,*mens2;
mens1 = malloc(100);
mens2
= malloc(100); /* */
printf("Qual
e' seu nome? "); /* */
scanf("%s",nome);
/* */
*mens1 = "Bem-vindo, ";
*mens2 = " aa lista de exercicios do curso EA877!\n";
printf("%s%s%s",mens1,nome,mens2);
/* */
return
0;
}
Por que não é possível corrigir, ao menos em alguns compiladores C, o nome do curso atribuído a p na forma:
char *p="EA878";
p[4] = '7'; /* erro! */
Porque
está se tentando manipular o ponteiro p (isto é, acessar
a quinta posição do conteúdo apontado por p), como
se ele fosse uma string, ou seja, um arranjo de caracteres. Apesar de estas
duas formas (ponteiros e strings) estarem intimamente relacionas em C,
nem todos compiladores C aceitam essa forma direta de manipulação
de ponteiros. A forma correta para essa manipulação seria:
*(p + 4) = '7'.