当前位置: 首页 > news >正文

C++面试题之判断一个变量是不是指针

对于变量其实对应的就是内存,而内存并没有表明一定是什么数据类型,所以判断变量是否是一个指针其实是一个参数类型匹配问题,在C++中支持函数的重载,那么不同的函数因为参数的不同从而匹配不同函数调用过程。
编译器在进行函数匹配调用的时候会遵循如下优先级:
重载函数 > 函数模板 > 可变参数。

#include <iostream>void Test(int a)
{std::cout<<"Normal Function"<<std::endl;
}template<typename T >
void Test(T a)
{std::cout<<"Template Function"<<std::endl;
}void Test(...)
{std::cout<<"... Function"<<std::endl;
}int main(int argc, char** argv)
{Test(100);Test(1, 100);Test(100.1);return 0;
}


有前面的语法基础以后,我们便可以利用可变参数与函数模板来进行相关程序设计进而判断一个变量是否为指针了。

#include <iostream>template<typename T >
bool isPtr(T * a)
{return true;
}bool isPtr(...)
{return false;
}class MyClass
{};int main(int argc, char** argv)
{int *ptr = nullptr;int  var = 0;MyClass mc;if(isPtr(ptr)){std::cout<<"This is ptr"<<std::endl;}if(!isPtr(var)){std::cout<<"This is not ptr"<<std::endl;}if(!isPtr(mc)){std::cout<<"This is not ptr"<<std::endl;}return 0;
}

变参函数是C++从C中继承过来的,虽然这里传入类对象能正常编译运行,并得到正确结果。但这样做存在风险,编辑器在做代码静态检查时会报警告:warning: passing object of class type 'MyClass' through variadic function,因为类对象可能包含非POD(Plain Old Data)类型,这些类型不能通过变参函数来安全地复制和访问,触发对象的切割(slicing)问题,运行时可能发生意想不到的错误。
其实我们匹配到函数时已经可以区分了,能不能只进行匹配,不调用函数呢?当然可以,如下所示:

#include<iostream>
template<typename T >
char isPtr(T * a)
{return '\0';
}int isPtr(...)
{return 0;
}class MyClass
{};#define ISPTR(p) (sizeof(isPtr(p)) == sizeof(char))int main(int argc, char** argv)
{int *ptr = nullptr;int  var = 0;MyClass mc;std::cout<<"ptr is ptr: "<< ISPTR(ptr)<<std::endl;std::cout<<"var is ptr: "<<ISPTR(var)<<std::endl;std::cout<<"mc is ptr: "<<ISPTR(mc)<<std::endl;return 0;
}


这里我们用了宏,编译时sizeof(isPtr(p))就能确定大小,这样就可以只匹配不调用函数。

首先可以明确的是,sizeof既是关键字也是运算符,它用来计算存放某一个量需要占用多少字节,它的结合性是从右到左。下图是来自C语言标准文档里的说明:


sizeof不是函数,虽然它的使用方法很像函数。如果sizeof是函数,那么 int i; sizeof i;这种表达式一定不能成立,因为函数参数不可能不用括号包裹起来。事实上这个sizeof i;可以正常编译运行的,这就说明sizeof绝对不是函数。因此sizeof它不会产生运行时开销,它的结果在编译时就已经确定,并且在程序运行的任何时刻都不会改变。 

原文链接:https://blog.csdn.net/caoshangpa/article/details/140562652 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • JavaWeb(4)JavaScript入门2—— JS的对象和JSON
  • 【附源码】Python :校园导航与最短路径算法
  • 【数学建模】——前沿图与网络模型:新时代算法解析与应用
  • gitee的怎么上传项目
  • PowerShell 使用介绍
  • 【C++中的IO流和文件操作精讲】
  • 【RaspberryPi】树莓派系统UI优化
  • googleTest 源码主线框架性分析——TDD 01
  • 自动发卡机器人来看:生成式AI的未来,是聊天还是代理?
  • vue echarts 柱状图表,点击柱子,路由代参数(X轴坐标)跳转
  • 复杂网络的任意子节点的网络最短距离
  • AIoTedge 智能边缘物联网平台
  • 如何用手机压缩视频?手机压缩视频方法来了
  • 【HarmonyOS4学习笔记】《HarmonyOS4+NEXT星河版入门到企业级实战教程》课程学习笔记(二十三)
  • 【两种方法】多位数的数字和问题
  • 【附node操作实例】redis简明入门系列—字符串类型
  • k8s 面向应用开发者的基础命令
  • Laravel 实践之路: 数据库迁移与数据填充
  • LeetCode29.两数相除 JavaScript
  • Next.js之基础概念(二)
  • nginx 配置多 域名 + 多 https
  • node和express搭建代理服务器(源码)
  • PHP 7 修改了什么呢 -- 2
  • Python实现BT种子转化为磁力链接【实战】
  • Redux 中间件分析
  • vue-loader 源码解析系列之 selector
  • vue脚手架vue-cli
  • Vue组件定义
  • 产品三维模型在线预览
  • 关于Android中设置闹钟的相对比较完善的解决方案
  • 前端攻城师
  • 通过几道题目学习二叉搜索树
  • 我这样减少了26.5M Java内存!
  • 自动记录MySQL慢查询快照脚本
  • 东超科技获得千万级Pre-A轮融资,投资方为中科创星 ...
  • ​ ​Redis(五)主从复制:主从模式介绍、配置、拓扑(一主一从结构、一主多从结构、树形主从结构)、原理(复制过程、​​​​​​​数据同步psync)、总结
  • ​云纳万物 · 数皆有言|2021 七牛云战略发布会启幕,邀您赴约
  • # dbt source dbt source freshness命令详解
  • (7)摄像机和云台
  • (pojstep1.1.2)2654(直叙式模拟)
  • (八)Flask之app.route装饰器函数的参数
  • (办公)springboot配置aop处理请求.
  • (纯JS)图片裁剪
  • (分布式缓存)Redis哨兵
  • (附源码)springboot家庭装修管理系统 毕业设计 613205
  • (十七)Flask之大型项目目录结构示例【二扣蓝图】
  • (转)甲方乙方——赵民谈找工作
  • .gitignore文件_Git:.gitignore
  • .NET 2.0中新增的一些TryGet,TryParse等方法
  • .net wcf memory gates checking failed
  • .NET/C# 异常处理:写一个空的 try 块代码,而把重要代码写到 finally 中(Constrained Execution Regions)
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)
  • .net图片验证码生成、点击刷新及验证输入是否正确
  • .NET中winform传递参数至Url并获得返回值或文件
  • .sh