_SirO_ Posted May 3, 2006 at 02:29 PM Report #25448 Posted May 3, 2006 at 02:29 PM Boas! estou com um problema numa funçao, obtenho o erro de compilaçao "invalid use of array with unspecified bounds", o que eu pretendia na funçao era inicializar uma matriz com um espaço em cada posiçao.... int main(void) { char jogo[3][3]; int N=0; inicializa_jogo(jogo); while(N!=9) { escreve_tabuleiro(jogo); jogada_pess(jogo,&N); jogada_pc(jogo,&N); } return 0; } void inicializa_jogo(char jogo[][]) { int i,j; for(i=0;i<=2;i++) for(j=0;j<=2;j++) jogo[i][j]=' '; } EDIT: Usa a ferramenta GeSHi, assim o código fica mais legível
Destineo Posted May 3, 2006 at 03:36 PM Report #25468 Posted May 3, 2006 at 03:36 PM Boas tardes, O teu problema é que não podes definir um função como definiste, ou seja, com char jogo[][] como parametro. Como noutros posts, já não me lembro muito de C, mas sugiro o seguinte : void inicializa_jogo (char * jogo) { memset (jogo, ' ', 3*3*sizeof(char)); } Isto irá limpar o array e colocar o espaço em todas as posições. A chamada a esta função é exactamente a mesma como tens inicializa_jogo(jogo). Um array do estilo char xpto[9][10] faz com que a variavel xpto seja um ponteiro para o inicio do array que declaraste. Ou seja, no limite, se quisesses fazer as coisas à mão, podias navegar pelo array da seguinte forma; for (int i = 0; i < 9; i+=3*sizeof(char)) { char* elemento = xpto + i; .... } e em cada iteração, estarias a aceder à posição 0, 1 e 2 do array de chars que criaste. Expliquem-me como deve de ser ? Se não, digam qualquer coisa que tento melhor. - Destineo
_SirO_ Posted May 3, 2006 at 04:06 PM Author Report #25476 Posted May 3, 2006 at 04:06 PM obrigado por essa funçao memset, nao conhecia, mas esta funçao void inicializa_jogo (char * jogo) { memset (jogo, ' ', 3*3*sizeof(char)); } também nao pode ser definida assim.... penso eu, é que sendo o array bidimensional, penso que nao podemos aceder aos endereços de memoria assim tao facilmente.... quer dizer, imaginando que pretendo a posiçao [1][2], como é que faço, em aritmetica de ponteiros? Btw, ja descobri porque e que nao compilava, o erro estava onde disseste, tinha que indicar tambem as dimensoes do array. void inicializa_jogo(char jogo[3][3])
Destineo Posted May 3, 2006 at 04:18 PM Report #25483 Posted May 3, 2006 at 04:18 PM Podes aceder da forma que disse, porque quando tu crias o array bidimensional, ele aloca-te o espaço em memória consecutivamente. Se quiseres, nunca fiz isto, mas se olhares para o assembler que é gerado para aceder a uma posição, por exemplo [1][2] do array, vais ver que ele irá fazer a aritmética simples, de 1*tamanho do array(neste caso 3) + 2. O C alloca-te a memória consecutiva, senão tinha que manter uma tabela de endereço para saber onde estava cada elemento do array, o que é contra-produtivo, lento e ocupa mais espaço que o array em si. - Destineo
untouchables Posted May 3, 2006 at 06:05 PM Report #25506 Posted May 3, 2006 at 06:05 PM mais fácil ainda... no topo do programa, defines algo do tipo: typedef int MATRIZ[3][3]; no teu código,ficaria: int main(void) { MATRIZ m; int N=0; inicializa_jogo(m); while(N!=9) { escreve_tabuleiro(m); jogada_pess(m,&N); jogada_pc(m,&N); } return 0; } void inicializa_jogo(MATRIZ m) { int i,j; for(i=0;i<=2;i++) for(j=0;j<=2;j++) m[i][j]=' '; } ps: fiz isto à pressa, apenas alterei o óbvio. utilizando assim a matriz, funciona. experimenta 😄
_SirO_ Posted May 3, 2006 at 06:07 PM Author Report #25508 Posted May 3, 2006 at 06:07 PM Ok, obrigado pelo esclarecimento, isto de compreender bem, ponteiros/etc, é uma grande ajuda. Já acabei um programa, o jogo do galo, está porreiro por acaso, mas agora tenho um problema, nunca consigo ganhar.... :S Bem, acho que é sinal que está bem feito....
_SirO_ Posted May 3, 2006 at 06:09 PM Author Report #25510 Posted May 3, 2006 at 06:09 PM @ untouchables Por acaso também me ocorreu fazer uma coisa dessas.... mas só sabia fazer em Pascal, em C ainda sou muito tenrinho.... 😄
untouchables Posted May 3, 2006 at 06:15 PM Report #25516 Posted May 3, 2006 at 06:15 PM lol não consegues ganhar? então está muito bem feito 😄 não tens executável, para o pessoal ver como ficou?
_SirO_ Posted May 3, 2006 at 06:48 PM Author Report #25517 Posted May 3, 2006 at 06:48 PM claro que tenho! http://www.leirifotec.com/galo.exe (19KB) e o código também http://www.leirifotec.com/galo.c
untouchables Posted May 3, 2006 at 07:00 PM Report #25519 Posted May 3, 2006 at 07:00 PM bem, não consegui ganhar, mas também não perdi nenhuma vez 😄 está engraçado, parabéns!
deathseeker25 Posted May 3, 2006 at 07:57 PM Report #25539 Posted May 3, 2006 at 07:57 PM Acho que devias acrescentar a opção de jogar novamente ao código-fonte. Tambem joguei três vezes, não ganhei mas tambem não perdi. 😄
brink@ero Posted May 3, 2006 at 08:06 PM Report #25545 Posted May 3, 2006 at 08:06 PM Bem vindo ao forum _SirO_ Só agora ví o tópico. Vou te dar uns conselhos. Não é boa política usar variáveis globais (eu sou alérgico a isso 🙂 ). Deve-se sempre evitar, só em situações extremas é que se deve usar. O teu problema podia ser resolvido de duas maneiras. Pegando no teu código, como passar uma variável Matriz[N][M]? Bem, para quem não sabe isto é um array de N vectores de dimensão M. E vectores são apontadores para uma memória pré-reservada. Quando tens arrays de arrays, isto quer dizer que tens apontadores de apontadores. Neste momento vocês devem ter ficado confusos ou não. Isto é complicado de explicar para quem não percebe que um array/vector é um apontador. Mas quando acedes a Matriz[2][3] o que acontece é isto: 1.º - Vais à variável Matriz buscar o valor do endereço para onde está a apontar {por exemplo a posição 2451 (n.º fictício)} 2.º - Incrementas 2 unidades para chegares à posição Martiz[2] { neste momento estás apontar para a posição 2453} 3.º - Nessa posição está outro endereço de memória (o 2.º apontador) { por exemplo 6215} 4.º - Incrementas 3 unidades e tens o endereço de memória da Matriz[2][3] Confuso? Tanto trabalho que o compilador tem de fazer só para termos isto Matriz[N][M]! Pois é, como o meu professor disse: A memória é linear, não existe matrizes de memórias! Por isso é que nenhum programador com um determinado grau ou qualificação faz isso do Matriz[N][M]. Depois do sermão fica o modo de resolução. Como Matriz[N][M] é um apontador de apontadores, então fica do seguinte modo: void teste(char **Matriz) { /* ... */ } void main(void) { char Matriz[3][3]; /* ... */ teste(Matriz); } Na boa política é fazeres isto assim: char Matriz[3*3]; Depois para acederes à linha X e coluna Y, fazes assim: Matriz[Y + X * numero de colunas] Depois vou verificar o IA do teu programa e comento. 😄
brink@ero Posted May 3, 2006 at 09:20 PM Report #25566 Posted May 3, 2006 at 09:20 PM O programa tem um bug!! LOL Estava eu preste a ganhar logo à primeira jogada quando ele substituiu o meu X por um O. LOL Assim não vale, isso é batota! Deixo aqui a sequência das minhas jogadas: eu: 1,3 PC: 2,2 eu: 3,3 PC: 1,3 eu: 3,1 PC: 2,1 eu: 3,2 (sepostamente a jogada da vitória) PC: 3,3 ? ?????? Nota: Conheço todos os segredos do jogo do Galo (são poucos), porque já fiz um programa de IA do jogo do galo, onde estudei todas as jogadas!
untouchables Posted May 3, 2006 at 09:28 PM Report #25567 Posted May 3, 2006 at 09:28 PM brink@ero essas combinações não funcionam comigo... o PC não chega a substituir o caracter. reparei num "defeito"... o pc está mais preocupado com o facto de eu nao ganhar do que ele ganhar. exemplo: 1,1 1,3 (neste momento ele ja tem 2 elementos seuigos, mas nao vou fazer com que ele nao ganhe) 3,1(neste momento, ele podia ter ganho, mas tapou a minha jogada) só nofim disto é que ele irá ganhar, não aproveita a situação à primeira... edit: no fim destas 3 jogadas, se ainda fizer "3,2", ele ainda não vai acabar o jogo
_SirO_ Posted May 3, 2006 at 10:40 PM Author Report #25581 Posted May 3, 2006 at 10:40 PM lol isto esta feito um bocado à pedreiro, tens razao, tenho que alterar a IA para o gajo dar prioridade a ganhar, em vez de dar prioridade a nao deixar ganhar. Quanto á questao de ponteiro de ponteiro, eu sabia isso, apenas nao tenho pratica e portanto fiz como sabia 🙂 No que diz respeito a variavel global, ela nao e bem global ou é? quer dizer, ela esta declarada em cada cabeçalho de cada funçao, apenas resolvi manter o nome, mas podia ter alterado para outro..... O que sugeres? que cada funçao retorne um valor que por sua vez vai ser usado em vez de ter tantas funçoes void? EDIT: fazendo a modificação de void escreve_tabuleiro(char jogo[3][3]); para void escreve_tabuleiro(char **jogo); compila, com avisos, "incompatible pointer tipe" e assim que tento correr dá erro.... 😄 EDIT 2: AI revista. está mais lixado 😄
_SirO_ Posted May 3, 2006 at 11:59 PM Author Report #25599 Posted May 3, 2006 at 11:59 PM Mais um "grande" update.... http://www.leirifotec.com/galo.exe http://www.leirifotec.com/galo.c Um dia destes comercializo isto.... Qual ânsia pelo Windows Vista qual quê, o pessoal está é todo à espera da ultima versao do meu jogo do galo.... ?
brink@ero Posted May 4, 2006 at 08:20 AM Report #25610 Posted May 4, 2006 at 08:20 AM lol isto esta feito um bocado à pedreiro, tens razao, tenho que alterar a IA para o gajo dar prioridade a ganhar, em vez de dar prioridade a nao deixar ganhar. Quanto á questao de ponteiro de ponteiro, eu sabia isso, apenas nao tenho pratica e portanto fiz como sabia 😄 No que diz respeito a variavel global, ela nao e bem global ou é? quer dizer, ela esta declarada em cada cabeçalho de cada funçao, apenas resolvi manter o nome, mas podia ter alterado para outro..... O que sugeres? que cada funçao retorne um valor que por sua vez vai ser usado em vez de ter tantas funçoes void? EDIT: fazendo a modificação de void escreve_tabuleiro(char jogo[3][3]); para void escreve_tabuleiro(char **jogo); compila, com avisos, "incompatible pointer tipe" e assim que tento correr dá erro.... 😄 EDIT 2: AI revista. está mais lixado 😛 Não, eu comentei aquilo antes de ver o código. Não tens nenhuma variável global. Sobre o erro, não sei. Foi compilar o teu código no VC++. Deu-me um erro: error C2065: 'memset' : undeclared identifier Fui a net e ví isto: #include <string.h> void *memset(void *s, int c, size_t n); fonte: http://www.opengroup.org/onlinepubs/007908799/xsh/memset.html Depois compilou sem nenhum erro. Sobre o: void escreve_tabuleiro(char jogo[3][3]); para void escreve_tabuleiro(char **jogo); O VC++ não aceita isto, à tarde tento isso no linux. Mas tenho quase a certeza que dava assim. Agora estou confuso 🙂😄 Sobre a nova versão, já corrigiste o erro 😁 Mas mesmo assim consigo vencer 😛 :P 😛 :P
brink@ero Posted May 5, 2006 at 08:29 AM Report #25730 Posted May 5, 2006 at 08:29 AM Já experimentei no linux ? Erro meu, afinal ele não aceita char **matriz, para uma inicialização matriz[3][3]. Confundi com outra inicialização em que construia matrizes com memória dinâmica. Nessa situação fazia isto: char ** matriz na inicialização, depois é que reservava o espaço. Erro meu
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now