Sebagai contoh:
sizeof(char*)
mengembalikan 4. Seperti halnya int*
, long long*
, segala sesuatu yang saya sudah mencoba. Apakah ada pengecualian untuk ini?
Sebagai contoh:
sizeof(char*)
mengembalikan 4. Seperti halnya int*
, long long*
, segala sesuatu yang saya sudah mencoba. Apakah ada pengecualian untuk ini?
Jawaban:
Jaminan yang Anda dapatkan adalah itu sizeof(char) == 1
. Tidak ada jaminan lain, termasuk tidak ada jaminan itu sizeof(int *) == sizeof(double *)
.
Dalam prakteknya, pointer akan berukuran 2 pada sistem 16-bit (jika Anda dapat menemukan satu), 4 pada sistem 32-bit, dan 8 pada sistem 64-bit, tetapi tidak ada yang bisa diperoleh dengan mengandalkan pada yang diberikan ukuran.
Bahkan pada platform x86 32 bit biasa, Anda bisa mendapatkan berbagai ukuran penunjuk, coba ini sebagai contoh:
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;
}
Di bawah Visual C ++ 2008, saya mendapatkan 4, 12 dan 8 untuk ukuran fungsi pointer-ke-anggota.
Raymond Chen membicarakan hal ini di sini .
Hanya pengecualian untuk daftar yang sudah diposting. Pada platform 32-bit, pointer dapat mengambil 6, bukan 4 , byte:
#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;
}
Jika Anda mengkompilasi program ini dengan Open Watcom dan menjalankannya, Anda akan mendapatkan 6, karena pointer jauh yang didukungnya terdiri dari nilai segmen 32-bit dan 16-bit
jika Anda mengkompilasi untuk mesin 64-bit, maka mungkin 8.
sizeof(char*)==1
,? Apakah kamu yakin Bukankah maksud Anda size(char)==1
?
Secara teknis, standar C hanya menjamin bahwa sizeof (char) == 1, dan sisanya terserah implementasi. Tetapi pada arsitektur x86 modern (mis. Chip Intel / AMD) cukup dapat diprediksi.
Anda mungkin pernah mendengar prosesor yang digambarkan sebagai 16-bit, 32-bit, 64-bit, dll. Ini biasanya berarti bahwa prosesor menggunakan N-bit untuk bilangan bulat. Karena pointer menyimpan alamat memori, dan alamat memori adalah bilangan bulat, ini secara efektif memberi tahu Anda berapa banyak bit yang akan digunakan untuk pointer. sizeof biasanya diukur dalam byte, jadi kode yang dikompilasi untuk prosesor 32-bit akan melaporkan ukuran pointer menjadi 4 (32 bit / 8 bit per byte), dan kode untuk prosesor 64-bit akan melaporkan ukuran pointer menjadi 8 (64 bit / 8 bit per byte). Di sinilah batasan 4GB RAM untuk prosesor 32-bit berasal - jika setiap alamat memori sesuai dengan satu byte, untuk menangani lebih banyak memori, Anda membutuhkan bilangan bulat yang lebih besar dari 32-bit.
Ukuran pointer pada dasarnya tergantung pada arsitektur sistem di mana ia diterapkan. Misalnya ukuran pointer dalam 32 bit adalah 4 byte (32 bit) dan 8 byte (64 bit) dalam mesin 64 bit. Jenis bit dalam sebuah mesin hanyalah alamat memori, yang dapat dimilikinya. Mesin 32 bit dapat memiliki 2^32
ruang alamat dan mesin 64 bit dapat memiliki 2^64
ruang alamat upto . Jadi pointer (variabel yang menunjuk ke lokasi memori) harus dapat menunjuk ke salah satu alamat memori ( 2^32 for 32 bit and 2^64 for 64 bit
) yang dipegang mesin.
Karena alasan ini kita melihat ukuran pointer menjadi 4 byte dalam mesin 32 bit dan 8 byte dalam mesin 64 bit.
Selain perbedaan 16/32/64 bit bahkan hal-hal aneh dapat terjadi.
Ada mesin di mana sizeof (int *) akan menjadi satu nilai, mungkin 4 tetapi di mana sizeof (char *) lebih besar. Mesin yang secara alami menangani kata-kata alih-alih bytes harus "menambah" karakter pointer untuk menentukan bagian kata yang Anda inginkan untuk mengimplementasikan standar C / C ++ dengan benar.
Ini sekarang sangat tidak biasa karena perancang perangkat keras telah mempelajari nilai addressability byte.
void*
dan char*
ditangani dalam perangkat lunak, dan ditambah dengan 3-bit offset dalam kata - tetapi karena sebenarnya tidak ada ruang alamat 64-bit, offset disimpan dalam 3 bit orde tinggi dari 64-bit kata. Jadi char*
dan int*
ukurannya sama, tetapi memiliki representasi internal yang berbeda - dan kode yang mengasumsikan bahwa pointer "benar-benar" hanya bilangan bulat yang dapat gagal total.
8 bit dan 16 bit pointer digunakan di sebagian besar mikrokontroler low profile. Itu berarti setiap mesin cuci, mikro, lemari es, TV lama, dan bahkan mobil.
Bisa dibilang ini tidak ada hubungannya dengan pemrograman dunia nyata. Tapi di sini adalah satu contoh dunia nyata: Arduino dengan ram 1-2-4k (tergantung pada chip) dengan pointer 2 byte.
Baru-baru ini, murah, dapat diakses untuk semua orang dan layak untuk dikodekan.
Selain apa yang orang katakan tentang sistem 64-bit (atau apa pun), ada jenis pointer lain selain pointer-to-objek.
Sebuah pointer-to-member mungkin hampir semua ukuran, tergantung bagaimana mereka diimplementasikan oleh kompiler Anda: mereka bahkan belum tentu semua ukuran yang sama. Cobalah penunjuk-ke-anggota dari kelas POD, dan kemudian penunjuk-ke-anggota yang diwarisi dari salah satu kelas dasar dari sebuah kelas dengan banyak basis. Apanya yang seru.
Dari apa yang saya ingat, ini didasarkan pada ukuran alamat memori. Jadi pada sistem dengan skema alamat 32-bit, sizeof akan mengembalikan 4, karena itu 4 byte.
sizeof (unsigned int) == sizeof (signed int)
, persyaratan ini ditemukan di 3.9.1 / 3. "Untuk masing-masing standar integer ditandatangani jenis, terdapat standar tipe unsigned integer yang sesuai (tetapi berbeda): unsigned char
, unsigned short int
, unsigned int
, unsigned long int
, dan unsigned long long int
, yang masing-masing menempati jumlah yang sama penyimpanan dan memiliki persyaratan keselarasan sama dengan yang sesuai yang ditandatangani bilangan bulat jenis "
Secara umum, sizeof (hampir semuanya) akan berubah ketika Anda mengkompilasi pada platform yang berbeda. Pada platform 32 bit, pointer selalu berukuran sama. Pada platform lain (64 bit menjadi contoh nyata) ini dapat berubah.
Tidak, ukuran pointer dapat bervariasi tergantung pada arsitekturnya. Ada banyak pengecualian.
Ukuran pointer dan int adalah 2 byte dalam kompiler Turbo C pada mesin windows 32 bit.
Jadi ukuran pointer spesifik untuk kompiler. Tetapi umumnya sebagian besar kompiler diimplementasikan untuk mendukung variabel pointer 4 byte dalam 32 bit dan variabel pointer 8 byte dalam mesin 64 bit).
Jadi ukuran pointer tidak sama di semua mesin.
Alasan ukuran pointer Anda adalah 4 byte karena Anda mengkompilasi arsitektur 32-bit. Seperti yang FryGuy tunjukkan, pada arsitektur 64-bit Anda akan melihat 8.
Di Win64 (Cygwin GCC 5.4) , mari kita lihat contoh di bawah ini:
Pertama, uji coba struct berikut:
struct list_node{
int a;
list_node* prev;
list_node* next;
};
struct test_struc{
char a, b;
};
Kode tes di bawah ini:
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;
Outputnya di bawah ini:
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
Anda dapat melihat bahwa dalam 64-bit, sizeof(pointer)
adalah 8
.
Pointer hanyalah sebuah wadah untuk sebuah alamat. Pada mesin 32 bit, rentang alamat Anda adalah 32 bit, jadi sebuah pointer akan selalu 4 byte. Pada mesin 64 bit jika Anda memiliki kisaran alamat 64 bit, sebuah pointer akan menjadi 8 byte.
Hanya untuk kelengkapan dan minat historis, di dunia 64bit ada konvensi platform yang berbeda pada ukuran tipe lama dan panjang, bernama LLP64 dan LP64, terutama antara sistem tipe Unix dan Windows. Standar lama bernama ILP64 juga membuat lebar int = 64-bit.
Microsoft mempertahankan LLP64 di mana longlong = 64 bit lebar, tetapi lama tetap di 32, untuk porting lebih mudah.
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