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 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/48532.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JAVA周总结(集合) 0721day

一.Collection集合 集合:可以存放多种类型数据的容器。 集合和数组的区别 数组的长度是固定的,集合的长度根据存储的数据发生改变。 数组只能存同一种类型的数组,而集合可以存多种类型。 1.2 单列集合常用类的继承体系 java.util.List: 添加的元素是有序、可重复 ; Lis…

PostgreSQL简介和安装

一、Postgresql简介&#xff1a; 1、PostgreSql是功能强大的&#xff0c;开源的关系型数据库&#xff0c;底层基于C语言实现&#xff1b; 2、开源&#xff1a;允许对PostgreSql进行封装&#xff0c;用于商业收费&#xff1b; 3、版本迭代速度快&#xff0c;正式版本已经到15.R…

【轻松拿捏】java中为什么要使用克隆?如何实现对象克隆?深拷贝和浅拷贝区别是什么?

java中为什么要使用克隆&#xff1f;如何实现对象克隆&#xff1f;深拷贝和浅拷贝区别是什么&#xff1f; 一、如何在Java中实现对象克隆 1.1 浅拷贝 1.2 深拷贝 1.3 区别总结 二、面试回答技巧 1. 定义克隆及其用途 2. 解释浅拷贝和深拷贝 3. 具体实现浅拷贝和深拷贝 …

【Python】使用库 -- 详解

库就是别人已经写好了的代码&#xff0c;可以让我们直接拿来用。 一个编程语言能不能流行起来&#xff0c;一方面取决于语法是否简单方便容易学习&#xff0c;一方面取决于生态是否完备。所谓的 “生态” 指的就是语言是否有足够丰富的库&#xff0c;来应对各种各样的场景。在…

LeetCode 188题: 买卖股票的最佳时机IV优化(原创)

之前完成了LeetCode 188题&#xff1a; 买卖股票的最佳时机IV&#xff08;原创&#xff09;-CSDN博客&#xff0c;虽然完成代码编写&#xff0c;并提交成功&#xff0c;但运行效率还未达到最优的1ms&#xff0c;见下图&#xff1a; 仔细检查代码&#xff0c;感觉还是有可优化的…

OpenCV中的GrabCut图像分割算法的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 功能描述 GrabCut 算法是一种用于图像分割的技术&#xff0c;由 Carsten Rother、Vladimir Kolmogorov 和 Andrew Blake 在 2004 年 SIGGRAPH 会议的论文《…

AI多模态识别ALM大模型分享:Qwen-Audio

ALM (Large Audio Language Model) 1&#xff09;Qwen-Audio 声音音频对话 参考&#xff1a; https://qwen-audio.github.io/Qwen-Audio/ https://huggingface.co/Qwen/Qwen-Audio-Chat “Qwen-Audio 接受多种音频&#xff08;人类语音、自然声音、音乐和歌曲&#xff09;以及…

基于面向对象和递归的拦截器设计模式

1 定义 拦截器模式&#xff08;Interceptor Pattern&#xff09;&#xff0c;是指提供一种通用的扩展机制&#xff0c;可以在业务操作前后提供一些切面的&#xff08;Cross-Cutting&#xff09;的操作。这些切面操作通常是和业务无关的&#xff0c;比如日志记录、性能统计、安…

day2 单机并发缓存

文章目录 1 sync.Mutex2 支持并发读写3 主体结构 Group3.1 回调 Getter3.2 Group 的定义3.3 Group 的 Get 方法 4 测试 本文代码地址&#xff1a; https://gitee.com/lymgoforIT/gee-cache/tree/master/day2-single-node 本文是7天用Go从零实现分布式缓存GeeCache的第二篇。 …

【LeetCode】80.删除有序数组中的重复项II

1. 题目 2. 分析 3. 代码 class Solution:def removeDuplicates(self, nums: List[int]) -> int:if len(nums) < 3:return len(nums)i 0j 1k 2while(k < len(nums)):if (nums[i] nums[j]):while(k < len(nums) and nums[j] nums[k] ):k1if (k < len(nums…

校验deb、rpm、apt、yum安装文件完整性测试

简介&#xff1a;deb包在Linux操作系统中类似于windows中的软件包&#xff08;msi&#xff09;&#xff0c;几乎不需要什么复杂的编译即可通过鼠标点击安装使用。此外,deb广泛应用于越狱后iOS软件及MeeGo&#xff08;含Maemo软件&#xff09;中。deb 格式是 Debian 系统(包含 D…

StringBuilder和StringBuffer

目录 &#xff08;一&#xff09;为什么要引入StringBuilder和StringBuffer &#xff08;二&#xff09;StringBuilder和StringBuffer &#xff08;1&#xff09;底层数组长度 (2)StringBuilder与StringBuffer扩容机制 &#xff08;3&#xff09;StringBuilder和StringBuf…

并发编程面试题1

并发编程 1、线程池中提交一个任务的流程是怎样的&#xff1f; 1、提交任务&#xff1a;首先&#xff0c;一个任务被提交到线程池。这个任务通常是一个实现了Runnable或Callable接口的对象&#xff1b; 2、检测线程池状态&#xff1a;线程池会首先检测其运行状态。如果线程池…

javafx使用发现的问题

1.按钮的方法 如果在fxml按钮的方法报错&#xff0c;并且你已在lei中添加了它的按钮及其按钮方法&#xff0c;那么可能是FXML和控制器类未正确关联&#xff1a; 确保你的FXML文件通过 fx:controller 属性正确指定了与之关联的控制器类。例如&#xff0c;fx:controller"c…

数据库之存储引擎

目录 一、MySQL支持的存储引擎 二、查看MySQL默认存储引擎 三、修改MySQL默认存储引擎 四、常用的存储引擎 1.InnoDB 2.MyISAM 3.MEMORY 一、MySQL支持的存储引擎 使用SHOW ENGINES \G; 命令查看 以“\G”结尾&#xff0c;其作用是将查询结果按列显示。 Engine&#xff…

更加深入Mysql-04-MySQL 多表查询与事务的操作

文章目录 多表查询内连接隐式内连接显示内连接 外连接左外连接右外连接 子查询 事务事务隔离级别 多表查询 有时我们不仅需要一个表的数据&#xff0c;数据可能关联到俩个表或者三个表&#xff0c;这时我们就要进行夺标查询了。 数据准备&#xff1a; 创建一个部门表并且插入…

Fiddler 导出请求为curl格式

来自:https://www.cnblogs.com/yudongdong/p/15418181.html Fiddler 下载地址: https://downloads.getfiddler.com/fiddler-classic/FiddlerSetup.5.0.20243.10853-latest.exe 这段代码加到类中 public static RulesOption("关闭请求体转代码", "生成代码&qu…

达梦数据库系列—29. DTS迁移ORACLE到DM

目录 1.ORACLE源端信息 2.DM目的端信息 3.DTS 迁移评估 4.数据库迁移 4.1 Oracle 源端数据库准备 4.2 目的端达梦数据库准备 初始化参数设置 兼容性参数设置 表空间规划 用户规划 创建迁移用户和表空间 4.3迁移步骤 创建迁移 配置数据源 配置迁移对象及策略 开…

django-vue-admin项目运行

文本主要对django-vue-admin项目进行了简要介绍&#xff0c;并且对前后端进行了源码安装和运行。在此基础上可作为管理系统二次开发的基础框架。 一.django-vue-admin简介和安装 1.简介 django-vue-admin项目是基于RBAC模型权限控制的中小型应用的基础开发平台&#xff0c;采…

昇思MindSpore学习总结十六 —— 基于MindSpore的GPT2文本摘要

1、mindnlp 版本要求 !pip install tokenizers0.15.0 -i https://pypi.tuna.tsinghua.edu.cn/simple # 该案例在 mindnlp 0.3.1 版本完成适配&#xff0c;如果发现案例跑不通&#xff0c;可以指定mindnlp版本&#xff0c;执行!pip install mindnlp0.3.1 !pip install mindnlp …