Ir ao conteúdo
  • Cadastre-se

Duvida de C


joubet

Posts recomendados

Sou iniciante no estudo da linguagem, e gostaria de entender melhor o funcionamento do tipo VOID. Suponha:

1) Sei que se eu escrever uma função precedida de VOID, estou dizendo para que a mesma não retorne valor. Mas qual a diferença de se escrever:

Soma(void)

{

int num =0;

num = num + 30;

return (num);

}

OU

Soma()

{

int num =0;

num = num + 30;

return (num);

}

OU

void Soma(void)

{

int num =0;

num = num + 30;

return (num);

}

E

void Soma()

{

int num =0;

num = num + 30;

return (num);

}

2) Por que não posso adicionar ou subtrair ponteiros tipo float ou doble ? Qual a vantagem de fazer isso ?

3) Como inicializar ponteiros corretamente para evitar ponteiros nulos ?

4) As afirmativas abaixo estão corretas ?

main()

{

int dezena =10, *p;

p =&dezena;

printf (“%d”, p);

/* imprime o valor da variável “.dezena” */

printf (“%p”, p);

/* imprime o endereco da variável “.dezena” */

printf (“%p”, &p);

/* imprime o endereco da variável “p” */

:(

Link para o comentário
Compartilhar em outros sites

1) Primeiramente você deve explicitar qual o tipo de retorno de uma função sempre, mesmo que o compilador que você esteja trabalhando não te obrigue a fazer isso, mas faça isso como boa prática de programação. Logo esqueça declarações desse tipo:

Soma(void)
{
  int num =0;

  num = num + 30;
  return (num);

}

O void dentro dos parênteses só deixa explícito que a função não recebe parâmetros, não há nenhum diferença com relação ao código gerado após a compilação.

2) Não entendi o que você quer dizer, já que você pode sim adicionar ou subtrair ponteiros tipo float ou doble.

3) Na maioria das vezes o problema não é o ponteiro ser nulo, mas sim você não saber para onde ele aponta. Portanto na hora de declarar um ponteiro atribuia o valor dele como nulo. Não há uma maneira totalmente segura de todos os ponteiros apontarem para um lugar válido, o que você pode fazer é planejar/revisar/debugar seu código para ter certeza que todos os seus ponteiros estão corretos;

int *p = NULL, *q = NULL;
int a = 10;

p = &a;
q = malloc (sizeof (int));

4) Há alguns erros. Segue abaixo o código corrigido:

int main()
{
   int dezena = 10, *p = NULL;

   p = &dezena;

   /* imprime o valor da variável “dezena” */
   printf (“%d”, *p);

   /* imprime o endereco da variável “dezena” */
   printf (“%p”, p);

   /* imprime o endereco da variável “p” */
   printf (“%p”, &p);
}

Link para o comentário
Compartilhar em outros sites

1) Gostaria que alguém me explicasse a afirmativa abaixo:

“Além de adição e subtração entre um ponteiro e inteiro, nenhuma outra operação aritmética pode ser efetuada com ponteiros. Especificamente, você não pode multiplicar ou dividir ponteiros; não pode aplicar os operadores de deslocamento de mascaramento bit a bit com ponteiros e não pode adicionar ou subtrair o tipo float ou o tipo double a ponteiros”

FONTE: “ C Completo e total – págs. 125 e 126 -Herbert Schildt 1990”

Com base no texto acima, pergunto: Por que não posso adicionar ou subtrair os ponteiros tipo float e double ?

2) Considere a rotina abaixo: Ela está passando uma matriz de string como ponteiro. Pergunto: Por que o tipo de retorno da função “lenome”, não pode ser char se a matriz é uma string ? por que tem de ser do tipo int ? se eu colocar char na frente da função “lenome” vai dar erro.

#include <string.h>

void main(void)

{

char nome[30];

clrscr();

printf("Entre com um nome:\n\n");

lenome(nome); /* passagem de matriz como argumento */

}

int lenome (char *matriznome) /* passando matriz*/

{

char le[30];

gets (le);

strcpy (matriznome,le);

"matriznome" */

printf ("\nO nome impresso e: %s ",matriznome);

}

3) Poderia me fornecer uma definição do que seria diretiva de compilação ?

4) O tamanho dos tipos de dados, são definidos pelo padrão ANSI ou variam de acordo com cada compilador ? é correto afirmar que independente do compilador, os tamanhos são :

char = 1byte

int = 2 bytes

float = 4 bytes

Obrigado e aguardo.

Link para o comentário
Compartilhar em outros sites

o autor se refeira de q não pode se subrair ou somar um tipo float ou double a um ponteiro.. isso é obvio..

o endereço de minha memoria no computador é representado somente por numeros inteiros..

agora é totalmente diferente do q você esta tentando mostrar: o conteudo que um ponteiro aponta não tem nada a ver com a afirmação do autor..

exemplo:

eu tenho um vetor de 10 elementos e uma variavel ponteiro q aponta para o primeiro elemento..

para eu achar os demais elementos eu tenho q fazer a seguinte expressao:

*(ponteiro+1); retorna o valor que esta apos o primeiro elemento do vetor..

*(ponteiro+2); retorna o valor que esta duas "casas" apos o primeiro elemento do vetor

*(ponteiro+n); retorna o valor que esta 'n's casas apos o primeiro elemento do vetor..

eu não posso somar ao ponteiro um valor q não seja inteiro..

e também não posso multiplicar o ponteiro:

*(ponteiro*2); ERRADO!!!

então q fique claro: ele estava se referindo ao endereço de memoria... :D

Link para o comentário
Compartilhar em outros sites

Repito aqui algumas perguntas, porque acho que quem me respondeu, gentilmente, no outro tópico não percebeu ( é o que me pareceu) que se tratava de mais de uma pergunta independente. desculopem-me se não fui claro

1) Considere a rotina abaixo: Ela está passando uma matriz de string como ponteiro. Pergunto: Por que o tipo de retorno da função “lenome”, não pode ser char se a matriz é uma string ? por que tem de ser do tipo int ? se eu colocar char na frente da função “lenome” vai dar erro.

#include <string.h>

void main(void)

{

char nome[30];

clrscr();

printf("Entre com um nome:\n\n");

lenome(nome); /* passagem de matriz como argumento */

}

int lenome (char *matriznome) /* passando matriz*/

{

char le[30];

gets (le);

strcpy (matriznome,le);

"matriznome" */

printf ("\nO nome impresso e: %s ",matriznome);

}

2) Poderia me fornecer uma definição do que seria diretiva de compilação ?

3) O tamanho dos tipos de dados, são definidos pelo padrão ANSI ou variam de acordo com cada compilador ? é correto afirmar que independente do compilador, os tamanhos são :

char = 1byte

int = 2 bytes

float = 4 bytes

4) "O sistema de arquivos ANSI é composto de diversas funções interrelacionadas. As mais comuns são mostradas na tabela abaixo. Essas funções exigem que o cabeçalho STDIO.H seja incluído em qualquer programa em que são utilizadas. Note que a maior parte das funções começa com a letra “f”. Isso é uma convenção do padrão C UNIX, que definiu dois sistemas de arquivos. As funções de E/S do UNIX não começavam com um prefixo e a maioria das funções do sistema de E/S formatado tinha o prefixo ‘f”. O comitê do ANSI escolheu manter essa convenção de nomes com intuito de dar continuidade."

Gostaria que alguém comentasse o texto acima.

Obrigado

Link para o comentário
Compartilhar em outros sites

Vamos ao código-fonte que você escreveu:

void main(void)

Nos compiladores atuais e até mesmo os antigos não aceitam a função main() retornando void. Tem que ser int. corrija!

int lenome (char *matriznome) /* passando matriz*/

Toda vez que você iniciar uma função depois da função main(), você terá que digitar um protótipo da tal função no inicio do programa entre as diretivas e a função main(). Por exemplo:

#include <string.h>

int lenome (char *matriznome);  /* PROTÓTIPO DA FUNÇÃO lenome() */
int main(void)
{
char nome[30];
...
...
}

lenome(nome); /* passagem de matriz como argumento */

}

int lenome (char *matriznome) /* passando matriz*/

{
char le[30];
...
...
}

O motivo disto: O compilador precisa antes reconhecer o formato da função para depois ela ser usada. Seria a mesma coisa de você sair do trabalho para casa dirigindo o seu carro com os olhos vendados. Mesmo você conhecendo o caminho, pode em com certeza vai bater em algo. A mesma coisa é o compilador. Um outro exemplo e na diretia que você declarou: #include <string.h>, isso faz com que o compilador reconheça uma série de protótipos de funções apropriadas para uso de strings/arrays que o programador pode implementar. Uma dessas funções que você usou foi o strcpy(). que justamente está contido em string.h.

Considere a rotina abaixo: Ela está passando uma matriz de string como ponteiro. Pergunto: Por que o tipo de retorno da função “lenome”, não pode ser char se a matriz é uma string ? por que tem de ser do tipo int ? se eu colocar char na frente da função “lenome” vai dar erro.

Como eu disse, faça o teste. Coloque char em vez de int sem o protótipo da função logo acima pra você ver como vai dá erro! Depois disso, coloque a protótipo usando o char, assim vai compilar normal.

) Poderia me fornecer uma definição do que seria diretiva de compilação ?

Diretivas de compilação são comandos que não geram códigos mas que podem definir, apagar, redirecionar macros, sub-rotinas, etc. São examinadas pelo pre-processador do compilador C. E as diretivas são sempre iniciadas com o caractere "#". Exemplo: #include <stdlib.h>, #define MACRO 10, #ifdef WIN32. Procure na internet tutorias sobre essas diretivas.

O tamanho dos tipos de dados, são definidos pelo padrão ANSI ou variam de acordo com cada compilador ? é correto afirmar que independente do compilador, os tamanhos são :

char = 1byte

int = 2 bytes

float = 4 bytes

Algums compiladores (pelo menos os que eu conheço) Modificam apenas o int, onde em algums tem valor int = 2byts e outros com int = 4bytes. Então é sempre importante você usar operador sizeof() do C para verificar o tamanho de cada tipo de variável. Ex: printf("%d", sizeof(int));

4) "O sistema de arquivos ANSI é composto de diversas funções interrelacionadas. As mais comuns são mostradas na tabela abaixo. Essas funções exigem que o cabeçalho STDIO.H seja incluído em qualquer programa em que são utilizadas. Note que a maior parte das funções começa com a letra “f”. Isso é uma convenção do padrão C UNIX, que definiu dois sistemas de arquivos. As funções de E/S do UNIX não começavam com um prefixo e a maioria das funções do sistema de E/S formatado tinha o prefixo ‘f”. O comitê do ANSI escolheu manter essa convenção de nomes com intuito de dar continuidade."

Sinceramente, eu não compreendi 100% essa citação. Mas com certeza está realcionado com as funçoes da livraria stdio.h que faz parte da biblioteca padrão do C definidos pelo ANSI até hoje. Mas não esquenta com isso. Fique tranquilo!

valeu cara!

Link para o comentário
Compartilhar em outros sites

Gostaria de saber, quando é necessário, usar return na função ou quando usar return sem argumento. As vezes crio funções sem o uso de comando return, e não tenho problemas. Considerando os exemplos abaixo, qual a conduta mais correta no uso do comando return ?

Ex:1

int main()

{

mostra();

}

void mostra (void)

{

printf ( “texto na tela\n”);

}

Ex2:

int main()

{

mostra();

}

int mostra (void)

{

int a=2, b=3; soma=0;

soma = a + b;

printf ( “texto na tela\n”, soma);

}

Ex3

int main()

{

printf ( “O resultado é:\n”, mostra());

}

int mostra (void)

{

int a=2, b=3; soma=0;

soma = a + b;

}

Ex4

int main()

{

int r;

r = mostra();

printf (“O resultado da soma é: \n”, r);

}

int mostra (void)

{

int a=2, b=3; soma=0;

soma = a + b;

}

Ex5

Ex4

int main()

{

int r;

r = mostra();

printf (“O resultado da soma é: \n”, r);

}

int mostra (void)

{

int a=2, b=3; soma=0;

soma = a + b;

return

}

Ex6

int main()

{

printf (“O resultado da soma é: \n”, mostra());

}

int mostra (void)

{

int a=2, b=3; soma=0;

soma = a + b;

return (soma)

}

Link para o comentário
Compartilhar em outros sites

Com base no programa abaixo, fosse respondida algumas perguntas:

main()

{

printf("Este e um teste de caractere especial: sinal sonoro \a\a\n");

/*mostra sinal sonoro e quebra de linha */

printf("Este e um teste de caracteres especiais: retrocesso \\b \b\n");

/*exemplo de retrocesso */

printf("Este e um teste de caracteres especiais: retrocesso de cursor \\r \r\n");

/*exemplo de retrocesso cursor */

printf("Tab. horizontal \t", "feita\t\n");

/*exemplo de tab. Horizontal */

printf("Tab. vertical \v", "feita\v\n");

/*exemplo de tab. vertical*/

printf("\nUso de barra invertida \\\\n");

/*mostra barra invertida */

}

1) um programa C é multiplataforma, ou seja, um programa C roda em UNIX, Linux, DOS, Windows e OS2 ou ainda Mac ou PC. Caso não o que seria necessário ? inclusão de cabeçalhos (biliotecas .h) ?

2) Os controles caracter de barra invertida no programa acima estão sendo usados e explicados corretamente pelos comentários ?

3) São aceitos por todos os sistemas operacionais citados ou só funcionam no DOS ou UNIX. Para Windows alguns seriam nulos ?

Obrigado

Link para o comentário
Compartilhar em outros sites

1) Tentei ativar a tecla Esc com o programa C abaixo, mas não deu certo. O que está faltando ? Já vi alguns programas com macros com valores hexadecimais (LER-DISCO = 0x22), será que é isto que está faltando ? Como usar esse valores hexadecimais ? Já deu para perceber que eu estou perdido no assunto, não deu ?

2) Gostaria de saber se existe alguma página na internet, que liste e descreva os headers (bibliotecas.h), e se estas estão disponíveis para download. Caso sim, favor informar página

3) Se bibliotecas.h são programas C, porque as bibliotecas padrão tem extensão .h e não .c ?

Obrigado

#include <stdio.h>

int main()

{

char tecla;

tecla = getchar();

if (tecla == 27)

{

printf ("saiu");

exit(0);

}

else

{

printf ("falhou");

}

}

Link para o comentário
Compartilhar em outros sites

  • 2 semanas depois...

Por que a sadia do programa abaixo, só esta mostrando o primeiro valor corretamente, ou seja : o valor 40 ? entrei com outros três valores e está mostrando lixo. O que está errado no programa ?

Quando a matriz é string, o último elemento é um caracter nulo, no caso de matriz inteira ou float, seria o quê , zero ?

Int main(void)

{

int i=0, num[4];

clrscr();

while (i<4)

{

scanf("%d",&num);

printf ("o valor de num e: %d \n", num);

i++;

}

}

Saída do programa:

40

o valor de num é 40

50

o valor de num é 1119

60

o valor de num é 5802

70

o valor de num é 3616

Link para o comentário
Compartilhar em outros sites

Quando a matriz é string, o último elemento é um caracter nulo, no caso de matriz inteira ou float, seria o quê , zero ?

O último caractere de uma string é '\0', que é nulo.

E o último "caractere" de um vetor ou matriz de números é o prórprio número no qual foi iserido por último no vetor/matriz. Então não existe "caractere" nulo num vetor/matriz de números.

Mas caso uma linha seja feita desta forma:

char numeros[] = { "0,1,2,3,4,5,6,7,8,9" };

Ai sim terá automaticamente um '\0' depois do 9, porque o que está declarado é uma simples string num vetor de caracteres.

Já nesta linha:

char numeros[] = {'1' , ',' , '2' , ',' , '3' , '\0'};

Como pode ver os números(caracteres) são inseridos um por um e você será obrigado a digitar o último caractere '\0', que para uma string é o caractere nulo. Caso você não digite o '\0' imprimirá depois do '3', "lixos" da memória.

T+

Link para o comentário
Compartilhar em outros sites

Supondo que eu tenha uma matriz inteira de 4(quatro) elementos, e entre com 6 (seis ) elementos, o que poderá dar de errado ? ultrapassei com um 5o elemento, e nada aconteceu. Quando digitei o 6o elemento recebi a seguinte mensagem : “Abnormal program termination”. Algém poderia explicar essa contradição, afinal se deu problema com (6)seis elementos, era para dar com 5 (cinco). O que houve ?

Int main(void)

{

int i=0, num[4];

clrscr();

while (i<6)

{

scanf("%d",&num);

printf ("o valor de num e: %d \n", num);

i++;

}

}

Saída do programa:

10

o valor de num é 10

20

o valor de num é 20

30

o valor de num é 30

40

o valor de num é 40

50

o valor de num é 50

60

o valor de num é 60

Abnormal program termination

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Quando você coloca num[x] = 0; o compilador calcula o endereço corrspondente a esse indice e tenta gravar 0 la, ele não verifica se o endereço faz parte do vetor ou não, ele simplesmente tenta gravar, o processador nem sabe que esse vetor existe, apenas leu a instrução e tenta gravar, se o endereço for valido ele vai gravar, se não vai disparar uma exceção (esse erro que da ai), colocando num[5] apesar de estar fora do vetor o endereço é valido, ele escreveu em algum lugar fora do vetor (talvez na variavel i), a próxima chamada o num é invalido ai disparou a exceção.

Link para o comentário
Compartilhar em outros sites

  • 2 semanas depois...

:(

int main(void)

{

int x[3];

.func (x);

.

.

}

fuc ( int mat[3])

{

return ( mat[3]

O retorno da função está correto , ou estou retornando uma coisa que não existe ?, já que em C posição de matiz começa em 0, e no caso vai até 2 . O problema é que meu compilador não acusa erro Sei que internamente, matrizes e ponteiro são iguais e que só o endereço do primeiro elemento é passado para a função. Mas e o retorno como fica ?

Link para o comentário
Compartilhar em outros sites

No programa abaixo, quero ler dois nomes, e colocar em uma matriz de duas dimensões, da seguinte forma:

Linha Coluna

0 01234566789

casa

1 livro

E quero que a saída seja:

os valores da matriz são: casa

os valores da matriz são: livro

Entretanto, estou vendo lixo onde deveria mostrar essas palavras. Por que ?


char lecaracter(char mat[][10]);

/* prototipo da funcao numero*/

int main()
{
   char x[2][10],m, I=0,J=0;

     while ( I < 2 && J < 10)

   {
      scanf("%s",x);

     I++;
    J++;
   }

m=(sizeof(x)/sizeof(char));

  /* informa o tamanho da dimensÆo da matriz,*/

printf ("O tamanho da dimensao da matriz (x) e: %d\n\n", m);

lecaracter(x);

  return (0);

  }

char lecaracter (char mat[][10])
{
   int f,i=0,j=0;
   f =(sizeof(mat)/sizeof(int));
   printf ("O primeiro elemento(endereco) da matriz, e que sera passado para a funcao\n");
   printf ("e: %d\n\n", f);

   while ( i < 2 && j < 10)

   {
     printf (" os valores da matriz sao: %s\n", mat[i][j]);

     i++;
     j++;
   }



   return (mat[i][j]);
}

:unsure:

Link para o comentário
Compartilhar em outros sites

Adicionei o cabeçalho <string.h> para facilitar a contegem de caracteres.


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char lecaracter(char mat[][10]);

/* prototipo da funcao numero*/

int main()
{
   char x[2][10],m, I=0,J=0;

   scanf("%s", &x[0]);
   fflush(stdin);
   scanf("%s", &x[1]);
   fflush(stdin);
    
   m=(sizeof(x)/sizeof(char));

   /* informa o tamanho da dimensÆo da matriz,*/

   printf ("O tamanho da dimensao da matriz (x) e: %d\n\n", m);

   lecaracter(x);

   putchar('\n');
   system("pause");
   return (0);
}

char lecaracter (char mat[][10])
{
   int f,i=0,j=0;
   f =(sizeof(mat)/sizeof(int));
   printf ("O primeiro elemento(endereco) da matriz, e que sera passado para a funcao\n");
   printf ("e: %d = %c da palavra \"%s\"\n\n", f, mat[0][0], mat[0]);
  
   for(i=0;  i < 2; i++){
     printf (" os valores da matriz sao: ");        
     for(j=0; j<strlen(mat[i]); j++){          
       printf ("%c", mat[i][j]);
     }
     putchar('\n');
   }
   return (0);
}

T+

Link para o comentário
Compartilhar em outros sites

:(


int main()
{
char matriz[4]={'a','b','c','\0'};
int i;

for (i =0; i<3; i++)
{

  printf ("Mostra os elemento da matriz: %c\n", matriz[i]);
}
return (0);
}

Considere a rotina acima: É sabido, que a posição de elementos de uma matiz começa em 0, logo teríamos que ter na posição 0 a letra ‘a,’ na 1 a letra ‘b’, na 2 a letra ‘c” e na 3 o caracter ‘\0’.

Entretanto, para que eu informe o ‘\0’ tenho que criar uma Quarta posição para guardar o caracter nulo. O caracter nulo não deveria estar na posição 3 ?

Se eu fizer char matriz[3]={'a','b','c','\0'}; terei a seguinte mensagem: “too many initializers in funtion main”.

Entretanto, se eu fizer char matriz[3]=”abc” ou char matriz[3]={“abc”}; dá tudo certo,sem erro. Qual a explicação ?

Obrigado.

Link para o comentário
Compartilhar em outros sites

Joubet, quando você digita a linha:

char matriz[4]={'a','b','c','\0'};

será reservado 4 (matrix[4]) posições na memória para armenzanar os devidos caracteres atribuidos ao array, incluindo, obrigatoriamente, o caractere nulo. Mas note que o valor 4 da notação matriz[4], é a quantidade(contagem) nominal para facilitar o raciocínio do programador. Veja que:

1 2 3 4 --> contagem dentro da notação matriz[4]

e diferente de

0 1 2 3 --> contagem na memória, que no caso equivale a 1 2 3 4:

1 - 2 - 3 - 4 --> Para o programador

0 - 1 - 2 - 3 --> Para o compilador

a - b - c - \0 --> Caracteres armezenados

Agora se você faz:

matriz[3]={'a','b','c','\0'}; 

o compilador endenderá como erro lógico, porque você não esta dando espaço para o último caractere, no caso o '\0':

1 - 2 - 3 --> Para o programador

0 - 1 - 2 --> Para o compilador

a - b - c - \0 --> Caracteres armezenados

Para resolver isso "erroneamente" basta retirar o caractere nulo:

matriz[3]={'a','b','c'}; 

que dessa forma ele vai para algum lugar desconhecido da memória fora do array mas no mesmo segimento da string. Mas é errado fazer isso.

Entretanto, se eu fizer char matriz[3]=”abc” ou char matriz[3]={“abc”}; dá tudo certo,sem erro. Qual a explicação ?

Se você entendeu direito a explicação anterior vai achar a resposta para essa pergunta.

T+

Link para o comentário
Compartilhar em outros sites

:(

Jmac:: estou escrevendo, para tirar algumas dúvidas que ficaram de sua resposta. Abaixo reproduzo sua resposta, para poder partir dela

char matriz[4]={'a','b','c','\0'};

será reservado 4 (matrix[4]) posições na memória para armazenar os devidos caracteres atribuídos ao array, incluindo, obrigatoriamente, o caractere nulo. Mas note que o valor 4 da notação matriz[4], é a quantidade(contagem) nominal para facilitar o raciocínio do programador. Veja que:

1 2 3 4 --> contagem dentro da notação matriz[4]

e diferente de

0 1 2 3 --> contagem na memória, que no caso eqüivale a 1 2 3 4:

1 - 2 - 3 - 4 --> Para o programador

0 - 1 - 2 - 3 --> Para o compilador

a - b - c - \0 --> Caracteres armazenados

Agora se você faz:

matriz[3]={'a','b','c','\0'};

o compilador entenderá como erro lógico, porque você não esta dando espaço para o último caractere, no caso o '\0':

1 - 2 - 3 --> Para o programador

0 - 1 - 2 --> Para o compilador

a - b - c - \0 --> Caracteres armazenados

Para resolver isso "erroneamente" basta retirar o caractere nulo:

matriz[3]={'a','b','c'};

que dessa forma ele vai para algum lugar desconhecido da memória fora do array mas no mesmo segmento da string. Mas é errado fazer isso.

Entretanto, se eu fizer char matriz[3]=”abc” ou char matriz[3]={“abc”}; dá tudo certo, sem erro. Qual a explicação ?

Se você entendeu direito a explicação anterior vai achar a resposta para essa pergunta.

Se entendi corretamente sua explicação, escrever char matriz[3]=”abc” ou char matriz[3]={“abc”}, também é errado. Isto porque não deixei espaço para o ‘\o’. Seguindo a lógica, o certo, seria escrever matriz[4]=”abc” ou char matriz[4]={“abc”}. Então pergunto: Porque o compilador não “grita” ? Eu prensava que o ‘\o’, nesta sintaxe, fosse posto automaticamente. Que me lembre o livro do Hebert Schildt – C Completo e total - não faz esse tipo de alerta. Só diz que devo colocar o caracter nulo quando faço matriz[3]={'a','b','c','\0'};

Com base no que foi dito, se eu escrever : char inicia[5] ={‘a ‘,’b’,’c’}; seria errado afirmar que as posições 3 e 4 (compilador) seria completado com nulo ?

Por favor comente,

Ah!! No programa que você corrigiu, você aplicou uma solução interessante. Você pegou uma matriz bidimensional chamada: x[2][10], e leu apenas alinha. Ou seja, scanf(“%s”,&x[0]); como isso pode funcionar ? fiquei espantado. Eu achava que não poderia se desassociar a linha de coluna da matriz. Ou seja, que só pudesse ser escrever scanf(“%s”,&x[0][0]); qual a explicação ? acho que outras linguagens não permitem esse desmembramento.

Obrigado pelo auxilio.

Link para o comentário
Compartilhar em outros sites

Então pergunto: Porque o compilador não “grita” ?

Jubet, isso vai depender de compilador para compilador. Os compiladores atuais são muito boms como o gcc/MingW que tem um papel importante nesse tipo de situação, porque como eu disse: "...que dessa forma ele vai para algum lugar desconhecido da memória fora do array mas no mesmo segmento da string. Mas é errado fazer isso.". é uma grande tarefa do compilador. Da mesma forma podemos fazer a seguinte notação para testar se o compilador é mesmo dos boms:

Na notação de string como str[5], você também pode escrever assim 5[str] (mas não na declaração da mesma, como char str[5] ), é só apos a declaração do vetor. Ex: 0[str] = 100; ou printf(%d, 0[str]);

Depois mande compilar e veja se o seu compilador é dos boms ou não.

Que me lembre o livro do Hebert Schildt – C Completo e total - não faz esse tipo de alerta. Só diz que devo colocar o caracter nulo quando faço matriz[3]={'a','b','c','\0'};

Se eu não me engando, nesse livro é usado exemplos de códigos utilizando o Turbo C. E o turbo C é um compilador muito antigo, velho mesmo. Dai você já tem uma ideia não é? Muito desatualizado e o livro omite muita coisa! Porque se você escreve matriz[3]={'a','b','c','\0'}; do jeito que o livro manda, no compilador gcc imprimirá na tela depois 'c', caracteres estranhos. Logo é um erro!

Com base no que foi dito, se eu escrever : char inicia[5] ={‘a‘,’b’,’c’}; seria errado afirmar que as posições 3 e 4 (compilador) seria completado com nulo ?

Quase isso! A 3º posição estará com o caractere '\0', que é posto automaticamnte (que já tem espeço para ele) e a 4º posição estará vaga.

Ah!! No programa que você corrigiu, você aplicou uma solução interessante. Você pegou uma matriz bidimensional chamada: x[2][10], e leu apenas alinha. Ou seja, scanf(“%s”,&x[0]); como isso pode funcionar ? fiquei espantado. Eu achava que não poderia se desassociar a linha de coluna da matriz. Ou seja, que só pudesse ser escrever scanf(“%s”,&x[0][0]); qual a explicação ? acho que outras linguagens não permitem esse desmembramento.

Simples...

Se você fizer isso:

scanf(“%s”,&x[0]);

A pimeira linha (vetor) da matriz será lida e receberá os dados pela entrada padrão(teclado). Então com essa notação pode-se "desprender" a matiz de qualquer tipo de dado, porque você não está literalmente "desprendendo" a matriz e sim fazendo apenas referência a primira linha dela. Já dessa forma:

scanf(“%s”,&x[0][0]);

Que você achou que não pudesse ser alterada para não desprender a matriz, você está fazendo referência ao primeiro elemento da primeira linha da matriz, ou seja, o primeiro caractere. Porém a sintaxe está com um pequeno erro:

scanf(“%s”,&x[0][0]); <--Errado!

scanf(“%c”,&x[0][0]); <--Certo!

A primeiro caractere da primeira linha (vetor) da matriz receberá o caractere pela usuário através da entrada padrão (teclado).

Com um pouco de raciocínio e fazer muitos exercícios, modificar códigos já prontos, inventar e descobrir os macetes por si mesmo são boas práticas para conhecer a flexibilidade da linguagem.

Espero te-lo ajudado!

T+

Link para o comentário
Compartilhar em outros sites

:(

Estou tentando compreender o uso de união em C. Mas o exemplo que tenho é muito complicado, pois é misturado com o uso de estrutura e eu não estou conseguindo entender. Alguém poderia, a partir do código que forneço, fazer uma versão mais simples sem misturar união com estrutura, ou seja só um exemplo de união ?

Me disseram, que código feito com união, é mais instável do que o feito com estrutura, e por conseqüência está mais sujeito a erros. É verdade ? também li que o uso de uniões permite maior portabilidade de código. É verdade ? por quê ?

É correto afirmar que a união usa a área de memória da maior variável ?

No exemplo abaixo a união usou 4 bytes e a estrutura 7 bytes. Quanto aos 4 bytes da união, acho que entendi, afinal o tipo float tem 4 bytes. Mas como a união pode distribuir 7 bytes dentro de 4 bytes, já que a uinião usaria o espaço do maior tipo, no caso float ?

Como disse, gostaria de um exemplo mais simples, mas gostaria de entender, como posso declarar uma variável tipo união chamada recebe como parâmetro de uma função ? essa variável, não teria que ser declarada como variável da união após sua declaração ?

EX.:

union _temp

{

int i;

char letra;

float numero;

};

union _temp recebe;

veja como o código que tenho é difícil de entender:


#include <stdio.h>

union _temp
{
int i;
char letra;
float numero;
};

struct _temp1
{
int i;
char letra;
float numero;
};


/*
troca recebe com um ponteiro para uma union
e um ponteiro para struct fazendo assim o
uso necessario de -> para referenciar os seus campos
*/
void troca(union _temp *recebe, struct _temp1 *recebe1)
{

printf("Imprimindo o tipo int da union: %d\n\n", recebe->i);

printf("Colocando um valor do tipo float na union\n\n");
recebe->numero = 9.8;
printf("Imprimindo novo valor do tipo float: %f\n\n", recebe->numero);

printf("Colocando um valor do tipo char na union\n\n");
recebe->letra = 'a';
printf("Imprimindo novo valor do tipo char: %c\n\n", recebe->letra);

printf("tentando imprimir int da union: %d\n\n", recebe->i);


printf("Enquanto para a struct os valores não serao sobrescritos\n");
printf("Imprimindo int: %d, float: %f e char: %c da struct\n\n",
recebe1->i, recebe1->numero, recebe1->letra);


}

int main(void)
{
union _temp temp;// declarando variavel temp como sendo do tipo union _temp
struct _temp1 temp1;//declarando variavel temp como sendo do tipo struct _temp1

printf("Inicializando um valor para union\n\n");
temp.i = 10;/* atribuindo valor para o campo int na union
veja que como a declaracao de temp(variavel do tipo union _temp)
foi nesse bloco usa-se o . para referenciar um de seus campos
*/
/* O uso de uma struct e de uma union e igual
abaixo atriuindo os valores para a struct */
temp1.i = 5;
temp1.letra = 'a';
temp1.numero = 50.0;

/* Chamando a função troca, e passando o endereco que aponta para union
e struct respectivamente*/
troca(&temp, &temp1);



printf("Visualizando bytes ocupados na memoria:\n");
printf("Para a union: %d bytes\n\n", sizeof(temp));
printf("Para a struct: %d bytes\n\n", sizeof(temp1));

return 0;
}  

Obrigado.

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

O unioun e struct tem objetivos diferentes,

O struct é uma estrutura, ex: um ponto, um ponto tem dois valores (x e y) e esses dois valores que definem o ponto ex:


point struct
{
int x;
int y;
};

O union serve para definir maneiras diferentes de acessar a mesma área da memória, ex:


exemplo union
{
int i;
double y;
color c;
};

No exemplo acima existe apenas uma variavel (a variavel "exemplo") que pode ser int ou double ou color, mas sera apenas uma variavel, como ele pode ter qualquer um desses tipos de dado o tamanho dela tem que ser equivalente ao tamanho do maior, no exemplo acima o double.

Link para o comentário
Compartilhar em outros sites

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...