Ví dụ:
sizeof(char*)
trả 4. Khi nào int*
, long long*
, tất cả những gì tôi đã cố gắng. Có bất kỳ ngoại lệ cho điều này?
Ví dụ:
sizeof(char*)
trả 4. Khi nào int*
, long long*
, tất cả những gì tôi đã cố gắng. Có bất kỳ ngoại lệ cho điều này?
Câu trả lời:
Sự đảm bảo bạn nhận được là vậy sizeof(char) == 1
. Không có đảm bảo nào khác, kể cả không đảm bảo điều đó sizeof(int *) == sizeof(double *)
.
Trong thực tế, con trỏ sẽ có kích thước 2 trên hệ thống 16 bit (nếu bạn có thể tìm thấy một), 4 trên hệ thống 32 bit và 8 trên hệ thống 64 bit, nhưng không có gì đạt được khi dựa vào một hệ thống nhất định kích thước.
Ngay cả trên nền tảng x86 32 bit đơn giản, bạn có thể nhận được nhiều kích cỡ con trỏ khác nhau, hãy thử ví dụ này:
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;
}
Trong Visual C ++ 2008, tôi nhận được 4, 12 và 8 cho các kích thước của hàm con trỏ đến thành viên.
Raymond Chen đã nói về điều này ở đây .
Chỉ là một ngoại lệ khác cho danh sách đã được đăng. Trên nền tảng 32 bit, con trỏ có thể mất 6, không phải 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;
}
Nếu bạn biên dịch chương trình này với Open Watcom và chạy nó, bạn sẽ nhận được 6, bởi vì các con trỏ xa mà nó hỗ trợ bao gồm các giá trị phân đoạn 32 bit và 16 bit
nếu bạn đang biên dịch cho máy 64 bit, thì nó có thể là 8.
sizeof(char*)==1
? Bạn có chắc không? Ý bạn là size(char)==1
sao?
Về mặt kỹ thuật, tiêu chuẩn C chỉ đảm bảo sizeof (char) == 1, và phần còn lại tùy thuộc vào việc thực hiện. Nhưng trên các kiến trúc x86 hiện đại (ví dụ như chip Intel / AMD) thì điều đó khá dễ đoán.
Bạn có thể đã nghe các bộ xử lý được mô tả là 16 bit, 32 bit, 64 bit, v.v. Điều này thường có nghĩa là bộ xử lý sử dụng N-bit cho các số nguyên. Vì con trỏ lưu địa chỉ bộ nhớ và địa chỉ bộ nhớ là số nguyên, điều này cho bạn biết có bao nhiêu bit sẽ được sử dụng cho con trỏ. sizeof thường được đo bằng byte, do đó mã được biên dịch cho bộ xử lý 32 bit sẽ báo cáo kích thước của con trỏ là 4 (32 bit / 8 bit mỗi byte) và mã cho bộ xử lý 64 bit sẽ báo cáo kích thước của con trỏ là 8 (64 bit / 8 bit mỗi byte). Đây là nơi giới hạn 4GB RAM cho bộ xử lý 32 bit xuất phát - nếu mỗi địa chỉ bộ nhớ tương ứng với một byte, để giải quyết nhiều bộ nhớ hơn, bạn cần số nguyên lớn hơn 32 bit.
Kích thước của con trỏ về cơ bản phụ thuộc vào kiến trúc của hệ thống mà nó được thực hiện. Ví dụ, kích thước của một con trỏ trong 32 bit là 4 byte (32 bit) và 8 byte (64 bit) trong máy 64 bit. Các loại bit trong một máy không có gì ngoài địa chỉ bộ nhớ mà nó có thể có. Máy 32 bit có thể có 2^32
không gian địa chỉ và máy 64 bit có thể có tối đa 2^64
không gian địa chỉ. Vì vậy, một con trỏ (biến trỏ đến một vị trí bộ nhớ) sẽ có thể trỏ đến bất kỳ địa chỉ bộ nhớ ( 2^32 for 32 bit and 2^64 for 64 bit
) nào mà máy giữ.
Vì lý do này, chúng tôi thấy kích thước của một con trỏ là 4 byte trong máy 32 bit và 8 byte trong máy 64 bit.
Ngoài sự khác biệt 16/32/64 bit, ngay cả những thứ khác cũng có thể xảy ra.
Đã có những máy mà sizeof (int *) sẽ là một giá trị, có thể là 4 nhưng trong đó sizeof (char *) lớn hơn. Các máy xử lý các từ tự nhiên thay vì byte phải "gia tăng" các con trỏ ký tự để chỉ định phần nào của từ bạn thực sự muốn để thực hiện đúng tiêu chuẩn C / C ++.
Điều này bây giờ rất bất thường vì các nhà thiết kế phần cứng đã học được giá trị của địa chỉ byte.
void*
và char*
được xử lý trong phần mềm và được tăng thêm phần bù 3 bit trong từ - nhưng vì thực tế không có không gian địa chỉ 64 bit, phần bù được lưu trữ trong 3 bit thứ tự cao của 64 bit từ. Vì vậy char*
, int*
có cùng kích thước, nhưng có các biểu diễn bên trong khác nhau - và mã giả định rằng các con trỏ là "thực sự" chỉ các số nguyên có thể thất bại nặng.
Con trỏ 8 bit và 16 bit được sử dụng trong hầu hết các bộ vi điều khiển cấu hình thấp. Điều đó có nghĩa là mọi máy giặt, micro, tủ lạnh, TV cũ và thậm chí cả ô tô.
Bạn có thể nói những điều này không liên quan gì đến lập trình trong thế giới thực. Nhưng đây là một ví dụ trong thế giới thực: Arduino với 1-2-4k ram (tùy thuộc vào chip) với con trỏ 2 byte.
Đó là gần đây, giá rẻ, có thể truy cập cho tất cả mọi người và đáng để mã hóa.
Ngoài những gì mọi người đã nói về các hệ thống 64 bit (hoặc bất cứ điều gì), còn có các loại con trỏ khác ngoài con trỏ tới đối tượng.
Một con trỏ thành viên có thể có kích thước gần như bất kỳ, tùy thuộc vào cách chúng được trình biên dịch của bạn triển khai: chúng không nhất thiết phải có cùng kích thước. Hãy thử một con trỏ đến thành viên của một lớp POD và sau đó một con trỏ thành thành viên được kế thừa từ một trong các lớp cơ sở của một lớp có nhiều cơ sở. Có gì vui
Từ những gì tôi nhớ lại, nó dựa trên kích thước của một địa chỉ bộ nhớ. Vì vậy, trên một hệ thống có sơ đồ địa chỉ 32 bit, sizeof sẽ trả về 4, vì đó là 4 byte.
sizeof (unsigned int) == sizeof (signed int)
, yêu cầu này được tìm thấy trong 3.9.1 / 3. "Đối với mỗi tiêu chuẩn ký số nguyên chủng loại, có tồn tại một tiêu chuẩn tương ứng (nhưng khác nhau) kiểu dữ liệu integer unsigned: unsigned char
, unsigned short int
, unsigned int
, unsigned long int
, và unsigned long long int
, mỗi trong số đó chiếm cùng một lượng lưu trữ và có yêu cầu tương tự liên kết là tương ứng ký số nguyên loại "
Nói chung, sizeof (khá nhiều thứ) sẽ thay đổi khi bạn biên dịch trên các nền tảng khác nhau. Trên nền tảng 32 bit, con trỏ luôn có cùng kích thước. Trên các nền tảng khác (64 bit là ví dụ rõ ràng) điều này có thể thay đổi.
Không, kích thước của một con trỏ có thể thay đổi tùy theo kiến trúc. Có rất nhiều trường hợp ngoại lệ.
Kích thước của con trỏ và int là 2 byte trong trình biên dịch Turbo C trên máy Windows 32 bit.
Vì vậy, kích thước của con trỏ là trình biên dịch cụ thể. Nhưng nhìn chung hầu hết các trình biên dịch được triển khai để hỗ trợ biến con trỏ 4 byte trong biến con trỏ 32 bit và 8 byte trong máy 64 bit).
Vì vậy, kích thước của con trỏ không giống nhau trong tất cả các máy.
Lý do kích thước của con trỏ của bạn là 4 byte là do bạn đang biên dịch cho kiến trúc 32 bit. Như FryGuy đã chỉ ra, trên kiến trúc 64 bit, bạn sẽ thấy 8.
Trong Win64 (Cygwin GCC 5.4) , hãy xem ví dụ dưới đây:
Đầu tiên, kiểm tra cấu trúc sau:
struct list_node{
int a;
list_node* prev;
list_node* next;
};
struct test_struc{
char a, b;
};
Mã kiểm tra dưới đây:
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;
Đầu ra dưới đây:
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
Bạn có thể thấy rằng trong 64-bit, sizeof(pointer)
là 8
.
Một con trỏ chỉ là một thùng chứa cho một địa chỉ. Trên máy 32 bit, phạm vi địa chỉ của bạn là 32 bit, do đó, một con trỏ sẽ luôn là 4 byte. Trên máy 64 bit, bạn có dải địa chỉ 64 bit, con trỏ sẽ là 8 byte.
Chỉ để hoàn thiện và quan tâm lịch sử, trong thế giới 64 bit, có các quy ước nền tảng khác nhau về kích thước của các loại dài và dài, được đặt tên là LLP64 và LP64, chủ yếu giữa các hệ thống kiểu Unix và Windows. Một tiêu chuẩn cũ có tên ILP64 cũng tạo ra int = 64-bit.
Microsoft duy trì LLP64 trong đó longlong = 64 bit, nhưng vẫn duy trì ở mức 32, để chuyển dễ dàng hơn.
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