====== Exercícios Resolvidos ====== Esta página irá conter exercícios de entrada e saída, estruturas condicionais, estruturas de repetição, funções e vetores e matrizes. As respostas serão colocadas em forma de algoritmo (nomenclatura do VisualAlg) e sempre com o código C correspondente. Programas que utilizam as bibliotecas matemáticas devem ser compiladas com a opção **-lm**. Exemplo: **''gcc lista_002.c -olista_002 -lm''** Este comando compila o programa **lista_002.c** e cria o executável **lista_002**. ===== Entrada e Saída ===== Dado um número inteiro de segundos, mostrar a quantas horas, minutos e segundos ele corresponde. /* lista_es001.c */ #include int main(void) { int iQtdSegundos, iHoras, iMinutos, iSegundos; printf("\nEntre com o valor em segundos:"); scanf("%d", &iQtdSegundos); /* divisao de inteiros */ iHoras = iQtdSegundos / 3600; iMinutos = (iQtdSegundos - (iHoras*3600)) / 60; iSegundos = (iQtdSegundos - (iHoras/3600)) % 60; printf("\nHora convertida %02d:%02d:%02d", iHoras, iMinutos, iSegundos); return 0; } O governo acaba de liberar 10 milhões de dólares para a construção de casas populares, a qual contratou a Construtora Pica-Pau S/A. Cada casa custa o equivalente a 150 salários mínimos. Faça um algoritmo que leia o valor do salário mínimo, o valor do dólar e calcule a quantidade de casas possíveis de se construir. /* lista_es002.c */ #include #include int main(void) { float fTotal, fDolar, fSalario, fCustoCasa, fCasas, fSobras; printf("\nEntre com o valor do dolar:"); scanf("%f", &fDolar); printf("\nEntre com o valor do salario:"); scanf("%f", &fSalario); fTotal = 10000000 * fDolar; /* Total em reais */ fCustoCasa = (fSalario*150); fCasas = truncf(fTotal/fCustoCasa); fSobras = fTotal - (fCasas*fCustoCasa); printf("\nForam construidos %.0f casas e sobrou %.2f reais.", fCasas, fSobras); printf("\nCada casa custou %.2f reais.", fCustoCasa); return 0; } ===== Estruturas Condicionais ===== Receber 3 valores numéricos: **X**, **Y** e **Z**, e verificar se esses valores podem corresponder aos lados de um triângulo. Em caso afirmativo, informar ao usuário se o triângulo é equilátero, isóscelos ou escaleno. /* lista_condicional001.c */ #include #include int main(void) { float fX, fY, fZ; printf("\nEntre com os valores dos 3 lados:"); scanf("%f%f%f", &fX, &fY, &fZ); /* condição de existência de um triângulo */ if( (fabsf(fY-fZ) < fX) && (fX < (fY+fZ)) ) { if( (fX == fY) && (fX == fZ) ) { printf("\nTriangulo equilatero!"); } else { if( (fX != fY) && (fX != fZ) ) { printf("\nTriangulo escaleno!"); } else { printf("\nTriangulo isosceles!"); } } } else { printf("\nAs medidas nao formam um triangulo!"); } return 0; } Faça um programa que lê a operação (+,-,/,*) e dois números e exibe o resultado. /* lista_condicional002.c */ #include int main(void) { float fValor_a, fValor_b, fResultado; char cOperacao; printf("\nEntre com a operacao:"); scanf("%c", &cOperacao); printf("\nEntre com o primeiro valor:"); scanf("%f", &fValor_a); printf("\nEntre com o segundo valor:"); scanf("%f", &fValor_b); switch(cOperacao) { case '+': fResultado = fValor_a + fValor_b; break; case '-': fResultado = fValor_a - fValor_b; break; case '/': fResultado = fValor_a / fValor_b; break; case '*': fResultado = fValor_a * fValor_b; break; } printf("\n %f %c %f = %f", fValor_a, cOperacao, fValor_b, fResultado); return 0; } ===== Estruturas de Repetição ===== Um método para cálculo de raizes quadradas de um número **N** já era conhecido pelos babilônios em... bom, há muito tempo atrás. Este método também é conhecido como método de Heron, um matemático grego que o descreveu 20 séculos depois, perto do ano 50 DC. Começando de um valor inicial **k** (geralmente valendo um) os babilônios geravam um novo valor de **k** de acordo com a regra **k=(k+N/k)/2**. À medida que o processo é repetido, os novos valores de **k** se aproximam cada vez mais da raiz de **N**. Escreva um programa que recebe o valor de **N** e imprime os primeiros doze valores obtidos com esta fórmula, testando-os para ver se eles realmente se aproximam. algoritmo "heron" var K, N: real I: inteiro inicio escreva("Entre com N:") leia(N) K <- 1 para I de 1 ate 12 faca K <- (K + (N/K) )/2 escreval("I = ", I, " e K = ", K) fimpara fimalgoritmo /* lista_repeticao001.c */ #include int main(void) { float fK, fN; int iI; printf("Entre com o valor de N:"); scanf("%f", &fN); fK = 1; for( iI = 1; iI <= 12; iI++) { fK = (fK + (fN/fK))/2; printf("\nI = %d e K = %f", iI, fK); } return 0; } Calcular o valor aproximado de **p**. Dada a fórmula **p = 4 * (1 - 1/3 + 1/5 - 1/7 + 1/9 ......)**, repetir até que o erro seja menor que **0.000001** (**p = 3,141592654**) /* lista_repeticao002.c */ #include #include int main(void) { double dP, dS, dErro; char cSinal; int iContador; dP = 0; dS = 0; iContador = 1; cSinal = '+'; dErro = 1; while( dErro > 0.000001 ) { if( cSinal == '+' ) { dS = dS + (double)(1.0/iContador); cSinal = '-'; } else { dS = dS - (double)(1.0/iContador); cSinal = '+'; } dP = 4.0 * dS; dErro = fabs(3.141592654-dP); iContador+=2; } printf("\nP = %f", dP); printf("\tErro = %f", dErro); printf("\tContador = %d", iContador); printf("\tS = %f", dS); printf("\tSinal = %c", cSinal); return 0; } Desenvolva um programa que apresente os 100 primeiros números primos. /* lista_repeticao003.c */ #include int main(void) { int iQtdPrimos, iPrimo, i, iNatural; iQtdPrimos = 0; iNatural = 1; while(iQtdPrimos <= 100) { iPrimo = 1; for( i = 2; i < iNatural; i++) { if( iNatural % i == 0 ) /* divisao exata */ { iPrimo = 0; } } if( iPrimo ) { printf("\n%d eh primo!", iNatural); iQtdPrimos++; } iNatural++; } return 0; } Faça um programa que leia um número e apresente todos os divisores (resto da divisão igual a 0) desse número. /* lista_repeticao004.c */ #include int main(void) { int iValor, iDivisor; printf("\nEntre com um numero:"); scanf("%d", &iValor); for( iDivisor = 1; iDivisor <= iValor/2; iDivisor++) { if( iValor % iDivisor == 0) { printf("\n%d e divisor de %d", iDivisor, iValor); } } return 0; } ===== Funções ===== Crie uma função que retorne o próximo termo da sequência de Fibonacci. /* lista_funcao_001.c */ #include int fibonacci(void) { static int iP1 = -1; // contém o 1o. termo static int iP2 = 1; // contém o 2o. termo int iP3; iP3 = iP1 + iP2; // calcula o próximo termo iP1=iP2; // armazena os termos anteriores iP2=iP3; // para a próxima chamada return(iP3); } int main(void) { int i; for(i=0;i<20;i++) { printf("\n%d Termo = %d", i+1, fibonacci()); } return 0; } ===== Vetores e Matrizes ===== Dadas duas matrizes numéricas A e B de dimensão 4x3, fazer um algoritmo que gere uma matriz lógica C, tal que o elemento C[i][j] seja verdadeiro se os elementos nas posições respectivas das matrizes A e B forem iguais, e falso caso contrário. Exibir as matrizes A, B e C. EXEMPLO: ^ Vetor A ^ Vetor B ^ Vetor C ^ | 2 4 6 | 2 5 8 | verdadeiro falso falso | | 1 5 9 | 1 9 7 | verdadeiro falso falso | | 3 7 2 | 3 7 1 | verdadeiro verdadeiro falso | | 4 6 8 | 4 5 8 | verdadeiro falso verdadeiro | /* lista_mat001.c */ #include #include #define QTD_L 4 #define QTD_C 3 int main(void) { int mA[QTD_L][QTD_C], mB[QTD_L][QTD_C], mC[QTD_L][QTD_C]; int iL, iC; for( iL = 0; iL < QTD_L; iL++ ) { for( iC = 0; iC < QTD_C; iC++) { printf("Entre com o valor para A[%1d][%1d]:", iL, iC); scanf("%d",&mA[iL][iC]); } } for( iL = 0; iL < QTD_L; iL++ ) { for( iC = 0; iC < QTD_C; iC++) { printf("Entre com o valor para B[%1d][%1d]:", iL, iC); scanf("%d",&mB[iL][iC]); } } for( iL = 0; iL < QTD_L; iL++ ) { for( iC = 0; iC < QTD_C; iC++) { mC[iL][iC] = (mA[iL][iC] == mB[iL][iC]); } } printf("\nMatriz A\tMatriz B\tMatriz C"); for( iL = 0; iL < QTD_L; iL++ ) { for( iC = 0; iC < QTD_C; iC++) { printf("\n[%1d][%1d]=%d", iL, iC, mA[iL][iC]); printf("\t[%1d][%1d]=%d", iL, iC, mB[iL][iC]); printf("\t[%1d][%1d]=%d", iL, iC, mC[iL][iC]); } } return 0; } Criar um jogo da velha para 2 jogadores. O jogo deve informar quando houver jogadas inválidas, considerar 3x3 o tamanho do tabuleiro. /* lista_mat002.c */ #include #define _X_ 'X' #define _O_ 'O' #define D_VALIDACAO void desenha( char as_velha[3][3] ); int main(void) { int i,j; int ijogada; char as_velha[3][3]; /* matriz que conterá o jogo da velha */ char ss_nome_jogador_01[40]; char ss_nome_jogador_02[40]; printf("\nEntre com o nome do jogador 01->"); scanf("%s", &ss_nome_jogador_01); printf("\nEntre com o nome do jogador 02->"); scanf("%s", &ss_nome_jogador_02); printf("\n%s, voce vai jogar com o simbolo X", ss_nome_jogador_01); printf("\n%s, voce vai jogar com o simbolo O", ss_nome_jogador_02); for( i=0;i<3;i++) { for( j=0;j<3;j++) { as_velha[i][j]=' '; } } desenha(as_velha); ijogada = _X_; while(1) { #ifdef D_VALIDACAO do { #endif if( ijogada == _X_ ) { printf("\nE a vez do %s", ss_nome_jogador_01); } else { printf("\nE a vez do %s", ss_nome_jogador_02); } printf("\nInforme as coordenadas"); printf("\nCoordenada i ->"); scanf("%d", &i); printf("\nCoordenada j ->"); scanf("%d", &j); #ifdef D_VALIDACAO if( as_velha[i][j] != ' ' ) { printf("\nVoce e um estupido !!! Estas coordenadas ja estao ocupadas..." ); } } while( as_velha[i][j] != ' ' ); #endif as_velha[i][j]=ijogada; desenha(as_velha); /* inverte jogadores */ if( ijogada == _X_ ) { ijogada = _O_; } else { ijogada = _X_; } } return 0; } void desenha( char as_velha[3][3] ) { printf("\n %c |", as_velha[0][0] ); printf(" %c |", as_velha[0][1] ); printf(" %c ", as_velha[0][2] ); printf("\n---|---|---"); printf("\n %c |", as_velha[1][0] ); printf(" %c |", as_velha[1][1] ); printf(" %c ", as_velha[1][2] ); printf("\n---|---|---"); printf("\n %c |", as_velha[2][0] ); printf(" %c |", as_velha[2][1] ); printf(" %c ", as_velha[2][2] ); return; } Criar um jogo da velha que aceite n-dimensões. /* lista_mat003.c */ #include #define _X_ 'X' #define _O_ 'O' #define D_VALIDACAO #define D_DIMENSAO 7 void desenha( char as_velha[D_DIMENSAO][D_DIMENSAO] ); int verifica( char as_velha[D_DIMENSAO][D_DIMENSAO], char cSimbol ); int main(void) { int i,j; int ijogada; char as_velha[D_DIMENSAO][D_DIMENSAO]; /* matriz que conterá o jogo da velha */ char ss_nome_jogador_01[40]; char ss_nome_jogador_02[40]; printf("\nEntre com o nome do jogador 01->"); scanf("%s", &ss_nome_jogador_01); printf("\nEntre com o nome do jogador 02->"); scanf("%s", &ss_nome_jogador_02); printf("\n%s, voce vai jogar com o simbolo X", ss_nome_jogador_01); printf("\n%s, voce vai jogar com o simbolo O", ss_nome_jogador_02); for( i=0;i"); scanf("%d", &i); printf("\nCoordenada j ->"); scanf("%d", &j); #ifdef D_VALIDACAO if( as_velha[i][j] != ' ' ) printf("\nVoce e um estupido !!! Estas coordenadas ja estao ocupadas..." ); } while( as_velha[i][j] != ' ' ); #endif as_velha[i][j]=ijogada; desenha(as_velha); if( verifica(as_velha, ijogada )) { printf("\nParabens"); break; } if( ijogada == _X_ ) { ijogada = _O_; } else { ijogada = _X_; } } } void desenha( char as_velha[D_DIMENSAO][D_DIMENSAO] ) { int i,j; for( i=0; i ===== Ponteiros ===== Desenvolva uma função que faça a troca dos valores de duas variáveis passadas como parâmetros. /* lista_ponteiros0001.c */ #include void troca(int * piValor_a, int * piValor_b) { int iAux; iAux = *piValor_a; *piValor_a = *piValor_b; *piValor_b = iAux; return; } int main(void) { int iValor_a, iValor_b; iValor_a = 10; iValor_b = 20; troca(&iValor_a, &iValor_b); printf("\nValor a = %d", iValor_a); printf("\nValor b = %d", iValor_b); return 0; } ===== Exercícios com strings ===== Faça um programa para verificar se uma palavra ou frase são palíndromas. /* lista_string001.c */ #include #include int palindrome( char * sFrase ) { int iInicio, iFim; iInicio = 0; iFim = strlen(sFrase)-1; while( iInicio < iFim ) { if( sFrase[iFim] != sFrase[iInicio] ) { return 0; } iFim--; iInicio++; } return 1; } int main(void) { char sFrase[50]; strcpy(sFrase, "mussum"); printf("\n%s = %d", sFrase, palindrome(sFrase)); strcpy(sFrase, "socorrammesubinoonibusemmarrocos"); printf("\n%s = %d", sFrase, palindrome(sFrase)); return 0; } Faça um programa para verificar se uma palavra ou frase são palíndromas, ignorando espaços e variação de caixa. /* lista_string002.c */ #include #include int palindrome( char * sFrase ) { int iInicio, iFim; iInicio = 0; iFim = strlen(sFrase)-1; while( iInicio < iFim ) { while( sFrase[iFim] == ' ' ) iFim--; while( sFrase[iInicio] == ' ' ) iInicio++; if( tolower(sFrase[iFim]) != tolower(sFrase[iInicio]) ) { return 0; } iFim--; iInicio++; } return 1; } int main(void) { char sFrase[50]; strcpy(sFrase, "mussum"); printf("\n%s = %d", sFrase, palindrome(sFrase)); strcpy(sFrase, "Socorram me subi no onibus em marrocos"); printf("\n%s = %d", sFrase, palindrome(sFrase)); strcpy(sFrase, "Isto nao eh um palindrome"); printf("\n%s = %d", sFrase, palindrome(sFrase)); return 0; } ===== Exercícios com Sockets de rede ===== * Criar 2 programas (um cliente e outro servidor). * Basicamente ocorrerá trocas de mensagens no formato COMANDO:MENSAGEM * O servidor precisa aceitar a conexão de apenas 1 cliente por vez. * O cliente recebe os comandos e/ou mensagens sempre via linha de comando. * O Cliente pode enviar mensagens para o servidor; retirar 1 mensagem do servidor; retirar várias mensagens do servidor. * Para colocar 1 mensagem no servidor, o cliente deve enviar o comando: ''ENVIA:xxxxxxx'' onde ''xxxxxxx'' é a mensagem colocada no servidor; * Para retirar 1 mensagem do servidor, o cliente deve enviar o comando: ''RETIRA''. O servidor pega a primeira mensagem da fila e envia ao cliente. * Para retirar várias mensagens do servidor, o cliente deve enviar o comando ''VARIAS:n'' onde ''n'' é o número das últimas mensagens postadas no servidor. Se ''n'' for 0 (zero), o servidor deverá enviar todas as mensagens guardadas para o cliente. Se o cliente pediu um valor superior de mensagens que o servidor não tenha, o servidor deve enviar a mensagem ''ERRO:número de mensagens solicitadas ultrapassa o número de mensagens armazenadas''. **Lado do servidor** /* lista_redess001.c */ #include #include #include #include #include #include #include #include #define MAX_LEN 50 /* estrutura para a fila */ struct queue { char itens[MAX_LEN][MAX_LEN]; int front,rear; }; /* funcoes retiradas do livro ESTRUTURA DE DADOS COM ALGORITMOS E C */ char * dequeue(struct queue * pq); char * front(struct queue * pq); int size(struct queue * pq); void enqueue(struct queue * pq, char * szMensagem ); int empty(struct queue * pq); void envia( int iSock, char * szMensagem ); int main(void) { int iSock; struct sockaddr_in my_addr; struct queue q; q.front = 0; q.rear = 0; iSock = socket(AF_INET, SOCK_STREAM, 0); if( iSock == -1) { perror("socket:"); exit(1); } my_addr.sin_family = AF_INET; my_addr.sin_port = htons(5724); my_addr.sin_addr.s_addr = INADDR_ANY; bzero(&(my_addr.sin_zero), 8); if( bind(iSock, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) { perror("bind:"); exit(1); } if( listen( iSock, 10 ) < 0) { perror("listen:"); exit(1); } while(1) { int iFd; ssize_t iBytes; struct sockaddr_in client_addr; socklen_t sin_size; char szMensagem[MAX_LEN]; fflush(stdout); sin_size = sizeof(struct sockaddr_in); if( (iFd = accept(iSock, (struct sockaddr *) &client_addr, &sin_size)) < 0) { perror("accept:"); exit(1); } memset(szMensagem, 0, MAX_LEN); if ((iBytes=recv(iFd, szMensagem, MAX_LEN, 0)) < 0 ) /* recebe dados do cliente */ { perror("recv"); exit(1); } szMensagem[iBytes] = '\0'; /* Acrescenta o \0 para garantir termino nulo para a string */ printf("\nRecebido: [%s]",szMensagem); /* colocar na fila */ if( strncmp( szMensagem, "ENVIA",5 ) == 0) { enqueue(&q,(char *)(szMensagem)+6); } /* retira da fila */ if( strncmp( szMensagem, "RETIRA", 6) == 0) { strcpy( szMensagem, dequeue(&q)); envia( iFd, szMensagem ); } if( strncmp( szMensagem, "VARIAS", 6) == 0) { char szNumero[MAX_LEN]; strcpy( szNumero, (char *)(szMensagem)+7); if( size(&q) < atoi(szNumero)) { envia(iFd,"ERRO:Numero de mensagens pedidas ultrapassa a quantidade armazenada"); } else { int i; for( i=0; ifront == pq->rear ) { return 1; } return 0; } void enqueue(struct queue * pq, char * szMensagem ) { /* se front estiver no inicio e foi alcancado o fim da fila */ if( pq->rear + 1 >= MAX_LEN && pq->front == 0 ) { printf("\nEstouro da capacidade da fila"); exit(1); } /* fila cheia, mas tem espaco no inicio */ if( pq->rear + 1 >= MAX_LEN ) { /* desloco de front para o inicio */ int i, element; element = pq->front; for( i=0; i < pq->rear; i++) { strcpy(pq->itens[i], pq->itens[element]); element++; } pq->rear = pq->rear - pq->front; /* ultimo elemento agora */ pq->front = 0; } strcpy(pq->itens[ pq->rear++ ], szMensagem); return; } int size(struct queue * pq) { return ( pq->rear - pq->front ); } char * front(struct queue * pq) { /* o primeiro elemento sempre esta no inicio do vetor */ return pq->itens[ pq->front ]; } char * dequeue(struct queue * pq) { if( empty(pq) ) { printf("\nFila vazia"); exit(1); } return (pq->itens[ (pq->front)++ ]); } **Lado do cliente** /* lista_redesc001.c */ #include #include #include #include #include #include #include #include #include #include #define MAX_LEN 50 void envia( int iSock, char * szMensagem ); void recebe( int iSock, char * szMensagem ); int main(int argc, char ** argv ) { int iSock; struct sockaddr_in dest_addr; char szMensagem[MAX_LEN]; iSock = socket(AF_INET, SOCK_STREAM, 0); if( iSock == -1) { perror("socket:"); exit(1); } dest_addr.sin_family = AF_INET; dest_addr.sin_port = htons(5724); dest_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); bzero(&(dest_addr.sin_zero), 8); if( connect(iSock, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr)) < 0) { perror("connect:"); exit(1); } memset(szMensagem, 0, MAX_LEN); if( strcmp(argv[1],"ENVIA") == 0) { sprintf( szMensagem, "ENVIA:%s", argv[2] ); envia(iSock,szMensagem); } if( strcmp(argv[1],"RETIRA") == 0) { sprintf( szMensagem, "RETIRA" ); envia(iSock,szMensagem); recebe(iSock,szMensagem); } if( strcmp(argv[1], "VARIAS") == 0) { sprintf( szMensagem, "VARIAS:%s", argv[2] ); envia(iSock,szMensagem); do { recebe(iSock,szMensagem); if( strncmp(szMensagem, "ERRO:", 5) == 0) { break; } }while( strncmp(szMensagem, "FIM", 3) != 0); } close(iSock); } void envia( int iSock, char * szMensagem ) { int iBytes; printf("\nEnviando [%s]\n", szMensagem); if ((iBytes=send(iSock, szMensagem, MAX_LEN, 0)) < 0 ) { perror("send"); exit(1); } return; } void recebe( int iSock, char * szMensagem ) { int iBytes; memset(szMensagem, 0, MAX_LEN); if ((iBytes=recv(iSock, szMensagem, MAX_LEN, 0)) < 0 ) { perror("recv"); exit(1); } szMensagem[iBytes] = '\0'; printf("\nRecebido [%s]\n", szMensagem); return; }