paulo1205
(usa Ubuntu)
Enviado em 19/05/2023 - 22:27h
jonnycicuto escreveu:
Senhores professores, peço ajuda para verificar o erro que esta acontecendo com o meu código.
o meu codigo: potencia.c escrito no ambiente DEVc++ versão 9. Compila mas não executa, mostrando no comando "process terminated em 5 segundos retorna um valor 1".
Em anexo segue o codigo: potencia .c . Por favor podem me ajudar a identificar o erro.
Jonny Maia.
Comentário inicial: a arrumação do código, especialmente os recuos de blocos, está um tanto confusa. Eu nunca usei o Dev-C++, mas, pelo que costumava ouvir de comentários nesta comunidade e em outras comunidade de programação que já participei, seu recurso de recuos automáticos é meio quebrado. Muita gente sugere usar o Code::Blocks como seu substituto, por ter um aspecto parecido mas funcionamento (supostamente) muito superior.
Além disso, eu compilei — ou tentei compilar — o seu código com as opções de depuração que eu sugeri a você. Veja quantas mensagens de erro.
$ gcc -Wall -Wextra -Werror -pedantic-errors -std=c11 -O2 -c a.c
a.c:16:9: error: return type of ‘main’ is not ‘int’ [-Wmain]
16 | void main(void)
| ^~~~
a.c:25:5: error: parameter names (without types) in function declaration
25 | int table(p);
| ^~~
a.c:26:10: error: parameter names (without types) in function declaration
26 | int show(p);
| ^~~
a.c: In function ‘show’:
a.c:43:17: error: unknown conversion type character ‘ ’ in format [-Werror=format=]
43 | printf("%10 %10 %10 %10 \n","N","N^2","N^3", "N^4");
| ^
a.c:43:21: error: unknown conversion type character ‘ ’ in format [-Werror=format=]
43 | printf("%10 %10 %10 %10 \n","N","N^2","N^3", "N^4");
| ^
a.c:43:25: error: unknown conversion type character ‘ ’ in format [-Werror=format=]
43 | printf("%10 %10 %10 %10 \n","N","N^2","N^3", "N^4");
| ^
a.c:43:29: error: unknown conversion type character ‘ ’ in format [-Werror=format=]
43 | printf("%10 %10 %10 %10 \n","N","N^2","N^3", "N^4");
| ^
a.c:43:13: error: too many arguments for format [-Werror=format-extra-args]
43 | printf("%10 %10 %10 %10 \n","N","N^2","N^3", "N^4");
| ^~~~~~~~~~~~~~~~~~~~
a.c:46:28: error: too many arguments for format [-Werror=format-extra-args]
46 | printf("10d",p[i-1][j-1] );
| ^~~~~
a.c:45:19: error: this ‘for’ clause does not guard... [-Werror=misleading-indentation]
45 | for(i=1; i<5; i++)
| ^~~
a.c:47:21: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘for’
47 | printf("\n\n");
| ^~~~~~
a.c: In function ‘table’:
a.c:35:9: error: control reaches end of non-void function [-Werror=return-type]
35 | }
| ^
a.c: In function ‘show’:
a.c:52:1: error: control reaches end of non-void function [-Werror=return-type]
52 | }
| ^
cc1: all warnings being treated as errors
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// int p[4][10];
int pwr(int a, int b);
int pwr(int a, int b)
Não há necessidade de declarar uma função e logo em seguida defini-la. Se a definição da função ocorrer antes do seu uso, a própria definição funciona como declaração.
Hoje em dia não é recomendável usar
register . Em geral, os compiladores têm heurísticas melhores para identificar ganhos de desempenho com o uso de registradores para armazenar valores de certas variáveis, mesmo que você não peça.
for(; b; b--) t= t*a;
return t;
}
int table(int p[4][10]);
int show(int p[4][10]);
Aqui não tem erro propriamente, mas é interessante notar que o “
4 ” que aparece entre colchetes, nesses contextos de parâmetro de função, é meramente figurativo, não fazendo parte do tipo dos parâmetros. Isso se deve à forma como o C lida com
arrays referindo-se a eles quase sempre através de ponteiros para seus primeiros elementos. Não que eu ache que essa forma de trabalhar é correta (e até admito que ela causa certa confusão, inclusive para mim, no meu começo com a linguagem, e às vezes até hoje ainda provoca momentos em que tenho de parar para pensar), mas existe um artigo do falecido Dennis M. Ritchie, criador da linguagem, na qual ele explica como e por que motivo se decidiu fazer assim (
https://www.bell-labs.com/usr/dmr/www/chist.html — a explicação está na seçã com título “
Embryonic C ”, mas o artigo inteiro é muito interessante).
Na prática, o que isso implica é que as seguintes três declarações são absolutamente sinônimas: em todas elas, o tipo do parâmetro
p é “ponteiro para dado do tipo
array com 10 elementos do tipo
int ”.
int table(int p[4][10]); int table(int p[][10]); int table(int (*p)[10]);
O tipo de retorno de
main () tem de ser
int , não
void , conforme a §5.1.2.2.1 do padrão do C (
https://port70.net/~nsz/c/c11/n1570.pdf ).
{
int *p;
p = malloc(40*sizeof(int));
if(!p)
printf("falta solicitação de memoria.\n");
A rigor, a solicitação não faltou: faltou o recurso para atender a solicitação.
Veja como o uso inconsistente de recuos confunde: o corpo da definição de
main () acabou na linha acima, embora o sinal de fechamento de chaves esteja no mesmo nível do
if de três linhas acima. A chamada a
exit () também vai acontecer incondicionalmente, pois apesar de visualmente estar com dois níveis de recuo a mais que o
if , ela já aparece fora após o comando cuja execução é condicionalmente por ele controlado.
Esse descasamento me levou à confusão até durante esta análise que estou fazendo: eu cheguei a escrever, e depois tive de apagar, alguns comentários abaixo que fariam sentido se o código seguisse o aspecto visual. Contudo, olhando novamente para este bloco, vi que tinha sido induzido ao erro.
// aqui p e simplesmente um ponteiro
int table(p);
int show(p);
As duas linhas acima são declarações, contudo elas usam uma sintaxe obsoleta, na qual o tipo do parâmetro
p é indeterminado, ao contrário do que você diz no comentário que as antecede, o tipo não é um ponteiro (nem é
int , nem qualquer outro tipo). Além disso essas declarações são supérfluas, pois as mesmas duas funções já haviam sido declaradas algumas linhas acima (antes da definição de
main ()), e de modo mais adequado do que agora, já que as primeiras especificavam os tipos dos seus parâmetros (ainda que visualmente surpreendente, como já mostrei acima).
//constroi a tabela de potencias
// o compilador tem uma matriz para trabalhar
int table(int p[4][10])
{
register int i, j;
for(j=1; j<11; j++)
for(i=1; i<5; i++) p[i-1] [j-1]= pwr(j,i);
Aqui você chega ao final de uma função que tem tipo de retorno
int mas não retorna nenhum valor. Isso é errado (a única exceção aceita pela linguagem é a função
main (), para a qual existe a presunção de que nenhum valor retornado implica retornar zero; para qualquer outra função, é obrigatório devolver algum valor explicitamente).
}
///exibe a tabela de potencias inteiras
int show(int p[4][10])
//agora o compilador tem uma matriz para trabalhar
{
register int i, j;
printf("%10 %10 %10 %10 \n","N","N^2","N^3", "N^4");
for(j=1; j<11; j++){
for(i=1; i<5; i++)
printf("10d",p[i-1][j-1] );
Tanto aqui como na chamada anterior, as há erros na
string de formatação: no primeiro caso, faltou especificar o tipo de conversão dos dados a serem impressos (suponho que deveria ser cinco vezes "
%10s ”); no segundo, faltou o sinal de “
% ” para iniciar a conversão).
printf("\n\n");
}
free(p);
Não creio que caiba chamar
free () neste ponto, ainda mais numa função cujo nome não dá nenhuma pista de que vai acontecer uma desalocação.
Geralmente, alocações e desalocações acontecem no mesmo nível de código e dentro da mesma função. Assim, seria de se esperar que, como a alocação aconteceu no primeiro nível de recuo em
main (), a desalocação também acontecesse no primeiro nível de recuo dentro da mesma função
main ().
Além disso, também é comum que a função de desalocação opere em par com a função de desalocação. Por exemplo, a uma função de alocação simples, como
malloc (),
realloc () e
calloc (), corresponde uma função de desalocação simples, como
free (). Já a funções de alocação mais complexa e para tipos específicos, tais como
fopen (),
getaddrinfo () ou
regcomp (), correspondem funções de desalocação que saibam liberar esses objetos complexos (no caso, respectivamente,
fclose (),
freeaddrinfo () e
regfree ()).
//eleva um inteiro a uma potencia especifica
De novo, você chega ao final de uma função que tem tipo de retorno
int mas não retorna nenhum valor.
... Então Jesus afirmou de novo: “(...) eu vim para que tenham vida, e a tenham plenamente.” (João 10:7-10)