Por exemplo:
sizeof(char*)
retorna 4. Como é que int*
, long long*
, tudo o que eu tentei. Há alguma exceção a isso?
Por exemplo:
sizeof(char*)
retorna 4. Como é que int*
, long long*
, tudo o que eu tentei. Há alguma exceção a isso?
Respostas:
A garantia que você recebe é essa sizeof(char) == 1
. Não há outras garantias, incluindo nenhuma garantia disso sizeof(int *) == sizeof(double *)
.
Na prática, os ponteiros serão do tamanho 2 em um sistema de 16 bits (se você puder encontrar um), 4 em um sistema de 32 bits e 8 em um sistema de 64 bits, mas não há nada a ganhar com a confiança em um determinado Tamanho.
Mesmo em uma plataforma simples de x86 de 32 bits, você pode obter vários tamanhos de ponteiro; tente isso por exemplo:
struct A {};
struct B : virtual public A {};
struct C {};
struct D : public A, public C {};
int main()
{
cout << "A:" << sizeof(void (A::*)()) << endl;
cout << "B:" << sizeof(void (B::*)()) << endl;
cout << "D:" << sizeof(void (D::*)()) << endl;
}
No Visual C ++ 2008, recebo 4, 12 e 8 para os tamanhos da função ponteiros para membro.
Raymond Chen falou sobre isso aqui .
Apenas mais uma exceção à lista já publicada. Em plataformas de 32 bits, os ponteiros podem levar 6, não 4 , bytes:
#include <stdio.h>
#include <stdlib.h>
int main() {
char far* ptr; // note that this is a far pointer
printf( "%d\n", sizeof( ptr));
return EXIT_SUCCESS;
}
Se você compilar esse programa com o Open Watcom e executá-lo, obterá 6, porque os indicadores remotos que ele suporta consistem em valores de deslocamento de 32 bits e segmento de 16 bits
se você estiver compilando para uma máquina de 64 bits, pode ser 8.
sizeof(char*)==1
,? Você tem certeza? Você não quer dizer size(char)==1
?
Tecnicamente falando, o padrão C apenas garante esse sizeof (char) == 1, e o restante depende da implementação. Mas nas arquiteturas modernas x86 (por exemplo, chips Intel / AMD) é bastante previsível.
Você provavelmente já ouviu processadores descritos como sendo de 16 bits, 32 bits, 64 bits etc. Isso geralmente significa que o processador usa N bits para números inteiros. Como os ponteiros armazenam endereços de memória, e os endereços de memória são inteiros, isso indica efetivamente quantos bits serão usados para os ponteiros. sizeof é geralmente medido em bytes; portanto, o código compilado para processadores de 32 bits reportará o tamanho dos ponteiros como 4 (32 bits / 8 bits por byte) e o código para processadores de 64 bits informará o tamanho dos ponteiros como 8. (64 bits / 8 bits por byte). É daí que vem a limitação de 4 GB de RAM para processadores de 32 bits - se cada endereço de memória corresponder a um byte, para endereçar mais memória, você precisará de números inteiros maiores que 32 bits.
O tamanho do ponteiro depende basicamente da arquitetura do sistema em que é implementado. Por exemplo, o tamanho de um ponteiro em 32 bits é de 4 bytes (32 bits) e 8 bytes (64 bits) em máquinas de 64 bits. Os tipos de bits em uma máquina nada mais são do que o endereço de memória que ela pode ter. Máquinas de 32 bits podem ter 2^32
espaço de endereço e máquinas de 64 bits podem ter 2^64
espaços de endereço até . Portanto, um ponteiro (variável que aponta para um local de memória) deve ser capaz de apontar para qualquer endereço de memória ( 2^32 for 32 bit and 2^64 for 64 bit
) que uma máquina mantenha.
Por esse motivo, vemos que o tamanho de um ponteiro é de 4 bytes em uma máquina de 32 bits e de 8 bytes em uma máquina de 64 bits.
Além das diferenças de 16/32/64 bits, coisas ainda mais estranhas podem ocorrer.
Houve máquinas em que sizeof (int *) terá um valor, provavelmente 4, mas onde sizeof (char *) é maior. Máquinas que endereçam naturalmente palavras em vez de bytes precisam "aumentar" ponteiros de caracteres para especificar qual parte da palavra você realmente deseja para implementar corretamente o padrão C / C ++.
Isso agora é muito incomum, pois os projetistas de hardware aprenderam o valor da endereçamento de bytes.
void*
e char*
são manipulados em software e aumentados com um deslocamento de 3 bits dentro da palavra - mas como na verdade não existe um espaço de endereço de 64 bits, o deslocamento é armazenado nos 3 bits de alta ordem dos 64 bits. palavra. Assim, char*
e int*
são do mesmo tamanho, mas têm diferentes representações internas - e código que pressupõe que os ponteiros são "realmente" apenas números inteiros pode deixar mal.
Ponteiros de 8 e 16 bits são usados na maioria dos microcontroladores de perfil baixo. Isso significa que todas as máquinas de lavar, micro, geladeira, TVs mais antigas e até carros.
Você poderia dizer que isso não tem nada a ver com a programação do mundo real. Mas aqui está um exemplo do mundo real: Arduino com 1-2-4k de ram (dependendo do chip) com ponteiros de 2 bytes.
É recente, barato, acessível para todos e vale a pena codificar.
Além do que as pessoas disseram sobre sistemas de 64 bits (ou qualquer outra coisa), existem outros tipos de ponteiros que não o ponteiro para o objeto.
Um ponteiro para membro pode ter quase qualquer tamanho, dependendo de como são implementados pelo seu compilador: eles não são necessariamente do mesmo tamanho. Tente um ponteiro para membro de uma classe POD e, em seguida, um ponteiro para membro herdado de uma das classes base de uma classe com várias bases. Que divertido.
Pelo que me lembro, é baseado no tamanho de um endereço de memória. Portanto, em um sistema com um esquema de endereços de 32 bits, sizeof retornará 4, já que são 4 bytes.
sizeof (unsigned int) == sizeof (signed int)
, esse requisito é encontrado em 3.9.1 / 3. "Para cada um dos padrão inteiro assinado tipos, existe um tipo inteiro sem sinal padrão correspondente (mas diferente): unsigned char
, unsigned short int
, unsigned int
, unsigned long int
, e unsigned long long int
, cada um dos quais ocupa a mesma quantidade de armazenamento e tem os mesmos requisitos de alinhamento como a correspondente inteiro assinado tipo "
Em geral, sizeof (praticamente qualquer coisa) muda quando você compila em plataformas diferentes. Em uma plataforma de 32 bits, os ponteiros são sempre do mesmo tamanho. Em outras plataformas (sendo o exemplo óbvio de 64 bits) isso pode mudar.
Não, o tamanho de um ponteiro pode variar dependendo da arquitetura. Existem inúmeras exceções.
O tamanho do ponteiro e int é de 2 bytes no compilador Turbo C na máquina Windows de 32 bits.
Portanto, o tamanho do ponteiro é específico do compilador. Mas geralmente a maioria dos compiladores é implementada para suportar variáveis de ponteiro de 4 bytes em 32 bits e variável de ponteiro de 8 bytes em máquinas de 64 bits).
Portanto, o tamanho do ponteiro não é o mesmo em todas as máquinas.
A razão pela qual o tamanho do seu ponteiro é de 4 bytes é porque você está compilando para uma arquitetura de 32 bits. Como FryGuy apontou, em uma arquitetura de 64 bits você veria 8.
No Win64 (Cygwin GCC 5.4) , vamos ver o exemplo abaixo:
Primeiro, teste a seguinte estrutura:
struct list_node{
int a;
list_node* prev;
list_node* next;
};
struct test_struc{
char a, b;
};
O código de teste está abaixo:
std::cout<<"sizeof(int): "<<sizeof(int)<<std::endl;
std::cout<<"sizeof(int*): "<<sizeof(int*)<<std::endl;
std::cout<<std::endl;
std::cout<<"sizeof(double): "<<sizeof(double)<<std::endl;
std::cout<<"sizeof(double*): "<<sizeof(double*)<<std::endl;
std::cout<<std::endl;
std::cout<<"sizeof(list_node): "<<sizeof(list_node)<<std::endl;
std::cout<<"sizeof(list_node*): "<<sizeof(list_node*)<<std::endl;
std::cout<<std::endl;
std::cout<<"sizeof(test_struc): "<<sizeof(test_struc)<<std::endl;
std::cout<<"sizeof(test_struc*): "<<sizeof(test_struc*)<<std::endl;
A saída está abaixo:
sizeof(int): 4
sizeof(int*): 8
sizeof(double): 8
sizeof(double*): 8
sizeof(list_node): 24
sizeof(list_node*): 8
sizeof(test_struc): 2
sizeof(test_struc*): 8
Você pode ver que em 64 bits, sizeof(pointer)
é 8
.
Um ponteiro é apenas um contêiner para um endereço. Em uma máquina de 32 bits, seu intervalo de endereços é de 32 bits; portanto, um ponteiro sempre terá 4 bytes. Em uma máquina de 64 bits, se você tiver um intervalo de endereços de 64 bits, um ponteiro terá 8 bytes.
Apenas por questões de integridade e interesse histórico, no mundo de 64 bits havia diferentes convenções de plataforma nos tamanhos de tipos longos e longos, denominados LLP64 e LP64, principalmente entre sistemas do tipo Unix e Windows. Um padrão antigo chamado ILP64 também tornou int = 64 bits de largura.
A Microsoft manteve o LLP64 em que longlong = 64 bits de largura, mas permaneceu em 32, para facilitar a portabilidade.
Type ILP64 LP64 LLP64
char 8 8 8
short 16 16 16
int 64 32 32
long 64 64 32
long long 64 64 64
pointer 64 64 64