c++中的sizeof,可以通过以下宏定义实现。

 #include <stdio.h>

 #define sizeof_T(T) ((size_t)((T*)0+1))             ///求类型的大小
#define sizeof_V(T) ((size_t)(&T+1)-(size_t)(&T)) ///求变量的大小 int main() {
int a=, b[]={};
printf("这个类型大小:%d \n这个类型单个变量的大小:%d \n这个类型数组变量的大小%d\n", sizeof_T(int), sizeof_V(a), sizeof_V(b));
return ;
}

那么为什么可以这样实现呢?

对于求类型大小的sizeof_T:

首先我们通过(T*)0得到一个指向00000000的指针,而且这个指针是int类型的,现在我们将这个指针+1。比如我们用一个int *p指针指向一块new int[10]的地址,那么此时很显然(p+1)-p==4而不是1,因为我们其实不是在地址上加1,而是让指针向前前进了一步,而这一步就是T这个类型的大小,也就是我们求的其实是指针步长。

可以通过以下程序发现这个特点,然后我们将00000000位置的指针向前移动一步,很显然,这个时候我们就得到了这个类型的大小。

 #include <stdio.h>
#include <iostream>
using namespace std;
int main() {
char *p=new char[];
int *q=new int[];
printf("%p %p\n%p %p\n", p, p+, q, q+);
delete p;
delete q;
return ;
}

对于求变量大小的sizeof_V:

也是利用了指针步长的原理,这里值得注意的有两点.

一是因为这里我们不是类型,所以说不可能定义一个指向0的指针,只能将自己的地址拿来运算。

二是数组名有一个特性,对于int p[10];这个数组,&p+1的值并不是数组首地址加上指针步长,此时的步长是数组本身,也就是一步跨越了整个数组。

第二点可以通过以下程序来验证

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

所以由以上特性我们就可以手动实现sizeof的功能了,说白了就是求指针步长。

我们既然知道了对数组来说&T+1相当于一步跨过整个数组,那么这是为什么呢,我由自己的做出相应的猜测,如有错误请在评论区指出。

对于int p[10];这个数组来说&p和什么相等呢?我测试的结果是&p==p[][10],也就是&p等于一个二维数组的数组名。也就是相当于将p提高了一个维度,原因就是如下的代码:

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

在运行了代码后你会发现p+1和&T+1的步长都是8。

那么其实就是对于数组,我们将他本身作为一个变量类型,就是相当于int [10]是一个变量类型。

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

最新文章

  1. kettle系列-4.kettle定制化开发工具类
  2. Socket通信代码(原理)
  3. VIM辅导:视频教程,文档资料,经典插件
  4. 四、优化及调试--网站优化--Yahoo军规中
  5. mysql慢日志设置
  6. Force.com微信开发系列(三)申请测试账号及回复图文消息
  7. &lt;META http-equiv=X-UA-Compatible content=IE=EmulateIE7&gt;
  8. MVC分页控件之二,为IQueryable定义一个扩展方法,直接反回PagedList&lt;T&gt;结果集(转)
  9. js css优化-- 合并和压缩
  10. poj1258prim算法
  11. [uwsgi]使用建议(类似最佳实践)
  12. Spring获取bean的步骤
  13. ITU-T Technical Paper: NP, QoS 和 QoE的框架以及它们的区别
  14. EntityFramework Core笔记:保存数据(4)
  15. SBC数据格式转换软件
  16. 越狱解决iphone4s外放无声音
  17. Framework7 索引列表插件的异步加载实现
  18. NOIP2018游记(划掉) 滚粗记
  19. asp.net重要小知识
  20. linux下怎样查看哪些进程占用swap空间

热门文章

  1. Supervised pre-trainning有监督预训练
  2. 在 mac 系统上安装 python 的 MySQLdb 模块
  3. 前端面试题-HTML结构语义化
  4. vue项目使用axios发送请求让ajax请求头部携带cookie
  5. Python发送邮件(常见四种邮件内容)
  6. centos6最小化安装默认没有 NetworkManager服务
  7. 在一个shell中查看管理 任务(前台和后台)/工作jobs 的命令
  8. 阶段1 语言基础+高级_1-3-Java语言高级_04-集合_08 Map集合_8_LinkedHashMap集合
  9. 网络编程之urllib
  10. delphi 语法 点滴总结clientdataset