uma coisa que percebi é que a primeira variável declarada sempre o numero do seu endereço é maior que a da segunda, por quê?
31 de maio de 2014 às 18:33
Anônimo disse...
é que cada variável ocupa 4 Bytes de memória, então soma mais quatro de uma para outra, se for Double soma mais oito, char soma mais uma...
9 de agosto de 2014 às 12:54
eduardo disse...
No gcc do ubuntu o primeiro exemplo da função sizeof dá esta mensagem de erro para os quatro tipos - char,int,float,double. format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=] printf("Double: %d bytes\n",sizeof(double)) No dev - c não dá.
22 de outubro de 2014 às 06:19
eduardo disse...
no primeiro exemplo da função sizeof() o gcc dá esta mensagem de erro: sizeof.c:15:3: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=] printf("Char: %d bytes\n",sizeof(char)); ^ sizeof.c:16:3: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=] printf("Int: %d bytes\n",sizeof(int)); ^ sizeof.c:17:3: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=] printf("Float: %d bytes\n",sizeof(float)); ^ sizeof.c:18:3: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=] printf("Double: %d bytes\n",sizeof(double)); no DEV - C não dá.
23 de outubro de 2014 às 19:18
Anônimo disse...
quanto aos erros, para int é %d, char é %c, float e double é %f, se usar %d em todos vai dar erro em char,float e double, só vai funcionar para int
17 de novembro de 2014 às 07:10
Anônimo disse...
Realmente %d, %c e %f são pra int, char e float, respectivamente. Pra double é %lf. Mas o que se está mandando imprimir é endereço de memória, não char ou float ou outra coisa. Outra coisa, warning não é erro.
Um detalhe interessante que pude notar é que o C não indexa na memória por ordem de declaração no código.
Isto é, se eu declaro dois ints e depois dois chars, ele não indexa primeiro os ints e depois os chars, mas o contrário.
Pelo que vi, a ordem fica: - char - int - float - double
31 de agosto de 2015 às 16:16
Anônimo disse...
Na verdade, quando se trata de endereços de memória, alguns compiladores não aceitam o especificador de formato %d, nesse caso como no próprio aviso informa tem que ser usado um numero inteiro sem sinal, ou seja o %u.
28 de outubro de 2015 às 07:41
Gabriel disse...
Uma coisa interessante é que independente de onde você declare ou realize o print das variáveis a alocação de memória é conforme descrito no texto por agrupamento de tipo, sendo sequencial.
Acredito que seja devido ao "compile and executing".
O compilador lê o programa inteiro e depois o executa por pilha de atividades, sendo assim ordenando automáticamente as posições de memória. (Posso estar errado em meus argumentos, se alguém souber complementar ou corrigir minha análise lógica... )
Enfim, bons estudos a todos e obrigado pelo curso, estou aprendendo bastante.
/* Eu NÃO percebi nenhum sequênciamento nos endereços de memória. Pra mim, continuaram aleatórios. O que houve com o endereço para 'Caracteres' ?? */
// As saídas foram essas:
// Caracteres: u@ ( e ïu@ ( // Inteiros: 0x28ff18 e 0x28ff14 // Floats: 0x28ff10 e 0x28ff0c // Doubles: 0x28ff00 e 0x28fef8
7 de dezembro de 2016 às 08:59
Anônimo disse...
Até onde eu saiba, se criar int X, y; não necessariamente ficarão um ao lado do outro, embora provavelmente fiquem. Deve ficar ao lado se declarar um vetor int x[10]; aí, sim, x[0] Ficar ao lado de x[1]. É o maior endereço vai depender da arquitetura do processador. Alguns processadores almoçam os bits invertidos.
Pode ser que eu tenha deixado algo passar (estou lendo esse blog na correria por razões de fim de semestre), mas não entendi o motivo de no primeiro código as variáveis do tipo char (caractere1 e caractere2) são escritas como '' %d '' no printf, já que %d é leitor de inteiro. Alguém sabe me dizer o porquê? No livro de C do Luís Damas, ele diz que é perigoso fazer isso e pode resultar em erros
Sarah, acredito que a resposta nao esta vindo a tempo, mas que isso seja um lembrete para nao deixar as coisas pra fazer de ultima hora.
O motivo de usar " %d" eh que nao eh o conteudo das variaveis do tipo char que esta sendo exibido, mas sim o endereco das variaveis do tipo char, que sempre eh um valor inteiro.
& sempre vai retornar um inteiro que corresponde ao endereco da variavel que vem logo apos o &
31 de janeiro de 2022 às 03:24
No artigo introdutório desta seção sobre ponteiros nossa apostila de C, demos uma ideia sobre o que são ponteiros em C, além de falarmos sobre os endereços de memória.
Agora, nesse artigo, vamos entrar mais a fundo no estudo
da memória e ver, de fato, onde as variáveis estão sendo declaradas e um importante relação entre ponteiros e variáveis que ocupam vários bytes.
Baixe este conteúdo: Apostila C Progressivo
Clique aqui e saiba como obter certificação de programação C
Quando cada variável ocupa em memória: A função sizeof()
Endereço de um bloco de variáveis
Agora que você já viu o tamanho e localização que cada
variável ocupa, vamos ensinar um fato importante, que será muito usado em nosso
estudo de strings e na compreensão da
passagem de parâmetro por referência, em funções.
Quando declaramos uma variável ou vetor de variáveis, os
blocos de memória são vizinhos, são separados em fila, numa ordem.
Você viu no exemplo passado que, tirando o tipo char, as outras variáveis ocupam mais de
uma posição em memória (lembrando que 1 byte é uma posição, ou bloco de
memória).
O tipo double, por
exemplo, ocupa 8 bytes. Então, esses 8 espaços de memória são alocados de forma
contígua (um ao lado do outro).
Sempre que declaramos uma variável que ocupa mais de um
bloco de memória, o seu endereço será o endereço
do primeiro bloco. Ou seja, se um inteiro ocupa 4 bytes (4 blocos), e
usamos o operador & para ver seu endereço, o endereço que vemos é o
endereço do primeiro byte. E qual o
endereço dos outros blocos? Ué, são vizinhos. Então, ocupam bytes, ou posições
de memória vizinha.
Se o primeiro byte está em 2112, o segundo vai estar na
posição 2113, o terceiro na posição 2114 e o quarto na posição 2115.
Vamos supor que queiramos declarar 1 milhão de inteiros em um vetor:
int numero_zao[1000000];
O endereço de 'numero_zao' é o endereço de 'numero_zao[0]', pois o endereço de uma variável ou vetor, é o endereço do primeiro bloco. E quantos bytes essa variável ocupa?
1 milhão * 4 bytes. = 4 000 000 bytes
Teste com : sizeof(numero_zao)
(Por ser um número muito grande de memória, há a possibilidade de sua máquina ficar lenta, de dar erro no programa, ou mesmo sua máquina travar. Lembre-se, a linguagem C é poderosa, você está manipulando e controlando cada pedacinho de sua máquina, por isso é fácil fazer alguma coisa que possa travar seu sistema. Não é à toa que C é a linguagem favorita dos hackers e a mais usada na criação de vírus).
O mesmo ocorre para um ponteiro. Sabemos que os ponteiros, ou apontadores, armazenam o endereço de apenas um bloco de memória.
Quando um ponteiro aponta para uma variável que ocupa vários bytes, adivinha pra qual desses bytes o ponteiro realmente aponta? Ou seja, o endereço que o tipo ponteiro armazena, guarda o endereço de qual byte?
Do primeiro. Sempre do primeiro.
E como ele sabe o endereço dos outros? Os outros estão em posições vizinhas!
Vamos mostrar isso na prática com um exemplo.
Para isso, temos que declarar duas variáveis de um mesmo
tipo, e ver seus endereços de memória.
Exemplo de código: Mostrando as
posições dos blocos de variáveis
Crie duas variáveis de cada
tipo: char, int, float e double - e mostre o endereço destas.
Ao declarar e ver os endereços,
note que as variáveis do mesmo tipo, que foram declaradas juntas, estão em
endereços de memória contínuos.
No caso das chars, elas estão ao lado da outra, pois só ocupam 1 byte cada.
No caso dos inteiros e floats,
o espaço de endereço de uma variável pra outra é de 4 unidades, pois cada
variável desta ocupa 4 bytes.
Nas variáveis do tipo double, seus
endereços estão distantes em 8 unidades, bytes, um do outro.
Rode o seguinte código e veja:
#include <stdio.h>
// Curso C Progressivo: www.cprogessivo.net
// O melhor curso de C! Online e gratuito !
// Artigos, apostilas, tutoriais e vídeo-aulas sobre
// a linguagem de programação C !
int main(void)
{
char caractere1, caractere2;
int inteiro1, inteiro2;
float Float1, Float2;
double Double1, Double2;
printf("Caracteres: %d e %d\n", &caractere1, &caractere2);
printf("Inteiros: %d e %d\n", &inteiro1, &inteiro2);
printf("Floats: %d e %d\n", &Float1, &Float2);
printf("Doubles: %d e %d\n", &Double1, &Double2);
return 0;
}
postado por Programação Progressiva às 19:36 em 8 de mar. de 2013
15 Comentários
Fechar esta janela Ir para formulário de comentáriouma coisa que percebi é que a primeira variável declarada sempre o numero do seu endereço é maior que a da segunda, por quê?
31 de maio de 2014 às 18:33
é que cada variável ocupa 4 Bytes de memória, então soma mais quatro de uma para outra, se for Double soma mais oito, char soma mais uma...
9 de agosto de 2014 às 12:54
No gcc do ubuntu o primeiro exemplo da função sizeof dá esta mensagem de erro para os quatro tipos - char,int,float,double.
format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
printf("Double: %d bytes\n",sizeof(double))
No dev - c não dá.
22 de outubro de 2014 às 06:19
no primeiro exemplo da função sizeof()
o gcc dá esta mensagem de erro:
sizeof.c:15:3: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
printf("Char: %d bytes\n",sizeof(char));
^
sizeof.c:16:3: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
printf("Int: %d bytes\n",sizeof(int));
^
sizeof.c:17:3: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
printf("Float: %d bytes\n",sizeof(float));
^
sizeof.c:18:3: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
printf("Double: %d bytes\n",sizeof(double));
no DEV - C não dá.
23 de outubro de 2014 às 19:18
quanto aos erros, para int é %d, char é %c, float e double é %f, se usar %d em todos vai dar erro em char,float e double, só vai funcionar para int
17 de novembro de 2014 às 07:10
Realmente %d, %c e %f são pra int, char e float, respectivamente. Pra double é %lf.
Mas o que se está mandando imprimir é endereço de memória, não char ou float ou outra coisa.
Outra coisa, warning não é erro.
21 de abril de 2015 às 16:54
Os blocos de memória são separados em ordem decrescente.
14 de agosto de 2015 às 09:33
Um detalhe interessante que pude notar é que o C não indexa na memória por ordem de declaração no código.
Isto é, se eu declaro dois ints e depois dois chars, ele não indexa primeiro os ints e depois os chars, mas o contrário.
Pelo que vi, a ordem fica:
- char
- int
- float
- double
31 de agosto de 2015 às 16:16
Na verdade, quando se trata de endereços de memória, alguns compiladores não aceitam o especificador de formato %d, nesse caso como no próprio aviso informa tem que ser usado um numero inteiro sem sinal, ou seja o %u.
28 de outubro de 2015 às 07:41
Uma coisa interessante é que independente de onde você declare ou realize o print das variáveis a alocação de memória é conforme descrito no texto por agrupamento de tipo, sendo sequencial.
Acredito que seja devido ao "compile and executing".
O compilador lê o programa inteiro e depois o executa por pilha de atividades, sendo assim ordenando automáticamente as posições de memória. (Posso estar errado em meus argumentos, se alguém souber complementar ou corrigir minha análise lógica... )
Enfim, bons estudos a todos e obrigado pelo curso, estou aprendendo bastante.
11 de abril de 2016 às 16:26
Para quem quer ficar livre dos warnings, use o %p ao invés de %d. Abs!
25 de abril de 2016 às 05:18
/* Eu NÃO percebi nenhum sequênciamento nos endereços de memória. Pra mim, continuaram aleatórios. O que houve com o endereço para 'Caracteres' ?? */
// As saídas foram essas:
// Caracteres: u@ ( e ïu@ (
// Inteiros: 0x28ff18 e 0x28ff14
// Floats: 0x28ff10 e 0x28ff0c
// Doubles: 0x28ff00 e 0x28fef8
7 de dezembro de 2016 às 08:59
Até onde eu saiba, se criar int X, y; não necessariamente ficarão um ao lado do outro, embora provavelmente fiquem. Deve ficar ao lado se declarar um vetor int x[10]; aí, sim, x[0] Ficar ao lado de x[1]. É o maior endereço vai depender da arquitetura do processador. Alguns processadores almoçam os bits invertidos.
8 de agosto de 2020 às 23:24
Pode ser que eu tenha deixado algo passar (estou lendo esse blog na correria por razões de fim de semestre), mas não entendi o motivo de no primeiro código as variáveis do tipo char (caractere1 e caractere2) são escritas como '' %d '' no printf, já que %d é leitor de inteiro. Alguém sabe me dizer o porquê? No livro de C do Luís Damas, ele diz que é perigoso fazer isso e pode resultar em erros
8 de dezembro de 2021 às 22:24
Sarah, acredito que a resposta nao esta vindo a tempo, mas que isso seja um lembrete para nao deixar as coisas pra fazer de ultima hora.
O motivo de usar " %d" eh que nao eh o conteudo das variaveis do tipo char que esta sendo exibido, mas sim o endereco das variaveis do tipo char, que sempre eh um valor inteiro.
& sempre vai retornar um inteiro que corresponde ao endereco da variavel que vem logo apos o &
31 de janeiro de 2022 às 03:24