c++ sizeof的實現


c++中的sizeof,可以通過以下宏定義實現。

 1 #include <stdio.h>
 2 
 3 #define sizeof_T(T) ((size_t)((T*)0+1))             ///求類型的大小
 4 #define sizeof_V(T) ((size_t)(&T+1)-(size_t)(&T))   ///求變量的大小
 5 
 6 int main() {
 7     int a=1, b[3]={0};
 8     printf("這個類型大小:%d  \n這個類型單個變量的大小:%d  \n這個類型數組變量的大小%d\n", sizeof_T(int), sizeof_V(a), sizeof_V(b));
 9     return 0;
10 }

那么為什么可以這樣實現呢?

對於求類型大小的sizeof_T:

首先我們通過(T*)0得到一個指向00000000的指針,而且這個指針是int類型的,現在我們將這個指針+1。比如我們用一個int *p指針指向一塊new int[10]的地址,那么此時很顯然(p+1)-p==4而不是1,因為我們其實不是在地址上加1,而是讓指針向前前進了一步,而這一步就是T這個類型的大小,也就是我們求的其實是指針步長。

可以通過以下程序發現這個特點,然后我們將00000000位置的指針向前移動一步,很顯然,這個時候我們就得到了這個類型的大小。

 1 #include <stdio.h>
 2 #include <iostream>
 3 using namespace std;
 4 int main() {
 5     char *p=new char[10];
 6     int *q=new int[10];
 7     printf("%p %p\n%p %p\n", p, p+1, q, q+1);
 8     delete p;
 9     delete q;
10     return 0;
11 }

對於求變量大小的sizeof_V:

也是利用了指針步長的原理,這里值得注意的有兩點.

一是因為這里我們不是類型,所以說不可能定義一個指向0的指針,只能將自己的地址拿來運算。

二是數組名有一個特性,對於int p[10];這個數組,&p+1的值並不是數組首地址加上指針步長,此時的步長是數組本身,也就是一步跨越了整個數組。

第二點可以通過以下程序來驗證

1 #include <stdio.h>
2 int main() {
3     int p[3];
4     printf("%p %p\n", p, &p+1);
5     return 0;
6 }

 

所以由以上特性我們就可以手動實現sizeof的功能了,說白了就是求指針步長。

 

我們既然知道了對數組來說&T+1相當於一步跨過整個數組,那么這是為什么呢,我由自己的做出相應的猜測,如有錯誤請在評論區指出。

對於int p[10];這個數組來說&p和什么相等呢?我測試的結果是&p==p[][10],也就是&p等於一個二維數組的數組名。也就是相當於將p提高了一個維度,原因就是如下的代碼:

#include <stdio.h>
int main() {
    int p[2][2], T[2];
    printf("%p %p\n%p %p\n", p, p+1, T, &T+1);
    return 0;
}

在運行了代碼后你會發現p+1和&T+1的步長都是8。

那么其實就是對於數組,我們將他本身作為一個變量類型,就是相當於int [10]是一個變量類型。

再次感受到了那些大佬們的牛逼。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM