【C++进阶】一些小知识点

news2024/10/3 4:32:53

const限定符

用const给字面常量起个名字(标识符),这个标识符就称为标识符常量;因为标识符常量的声明和使用形式很像变量,所以也称常变量。声明方式:

const int a = 77;
const float PI = 3.14159f;

需要注意的是,常量必须在定义时初始化,初始化常量不能重新被赋值。

关于指针,

const int * p;

const在左边,这表示我们定义了一个指针,指向的数据类型为const int,即p是一个常量。

int a = 77;
int * const p = &a;

const在*右边,表示p是一个地址常量,必须对p 进行赋值。

const定义的常量与#define定义的符号常量的区别:
1.const定义的常量有类型,而#define定义的没有类型,编译可以对前者进行类型安全检查,而后者仅仅只是做简单替换;
2.const定义的常量在编译时分配内存,而#define定义的常量是在预编译时进行替换,不分配内存。
3.作用域不同,const定义的常变量的作用域为该变量的作用域范围。而#define定义的常量作用域为它的定义点到程序结束,当然也可以在某个地方用#undef取消。

定义常量还可以用enum,高层次编程尽量用const、enum、inline替换#define定义常量。在底层编程,#define是很灵活的。

结构体内存对齐

内存对齐:编译器为每个“数据单元”按排在某个合适的位置上。C、C++语言非常灵活,它允许你干涉“内存对齐”。
为什么要对齐?性能原因:在对齐的地址上访问数据块。
如何对齐:
第一个数据成员放在offset为0的位置;
其它成员对齐至min(sizeof(member),#pragma pack所指定的值)的整数倍。#pragma pack为编译器预设的一个对齐数;
整个结构体也要对齐,结构体总大小对齐至各个成员中最大对齐数的整数倍。

举个例子:

#include <iostream>
using namespace std;

struct Test{
	char a;
	double b;
	char c;
};

int main() {
	Test test;
	cout<<sizeof(test);
	return 0;
}

输出为24。a在offset为0的位置。#pragma pack默认为8,double类型占8个字节,对齐数取两者最小值为8,所以b对齐至8,占offset为8~15的8个字节。c对齐至16,结构体总大小对齐至各个成员中最大对齐数的整数倍,也就是8,所以整个结构体大小为24。

下面我们将编译器默认的对齐数改为4,

#include <iostream>
using namespace std;

#pragma pack(4)
struct Test{
	char a;
	double b;
	char c;
};
#pragma pack()

int main() {
	Test test;
	cout<<sizeof(test);
	return 0;
}

输出结果为16。a在offset为0的位置。#pragma pack为4,double类型占8个字节,对齐数取两者最小值为4,所以b对齐至4,占offset为4~11的8个字节。c对齐至12,结构体总大小对齐至各个成员中最大对齐数的整数倍,也就是16,所以整个结构体大小为16。

域运算符

C++中增加的作用域标识符::用于对与局部变量同名的全局变量进行访问,或者用于表示类的成员。举个例子:

#include <iostream>
using namespace std;

int var = 100; 

int main() {
	int var = 50;
	cout<<var<<endl;
	cout<<::var<<endl;
	return 0;
}

输出结果为:
在这里插入图片描述

new、delete运算符

new运算符可以用于创建堆空间,成功返回首地址,失败抛出异常。声明方式:

#include <iostream>
using namespace std;

int main(){
	
	int* p = new int;//分配一个整数空间,4字节
	int* pt = new int(77);//初始化为77,分配一个整数空间,4字节 
	int* p2 = new int [50];//分配连续的50个整数空间,200字节
	
	delete p;
	delete pt;
	delete[] p2; 
	return 0;
}

new一个新对象,首先进行内存分配(operator new),然后调用构造函数。delete释放一个对象,首先调用析构函数,然后进行释放内存(operator delete)。

重载

相同的作用域,如果两个函数名称相同,而参数不同,我们把它们称为重载overload。函数的重载又称为函数的多态性。
函数重载的不同形式有:
1.形参数量不同;
2.形参类型不用;
3.形参的顺序不同;
4.形参数量和形参类型都不同。
调用重载函数时,编译器通过检查实际参数的个数、类型和顺序来确定相应的被调用函数。
举个例子:

#include <iostream>
using namespace std;

void fun(int a,int b){
	cout<<"int fun"<<endl;
} 

void fun(double a,double b){
	cout<<"double fun"<<endl;
}
int main() {
	
	fun(3,4);
	fun(3.3,4.4);
	return 0;
}

如果返回类型不同而函数名相同、形参也相同,则是不合法的,编译器会报语法错误。

//合法的重载例子
int abs(int i);
long abs(long i);
double abs(double i);
//非法的重载例子
int abs(int i);
long abs(int i);
double abs(int i);

name managling

name managling这里把他翻译成名字改编。C++为了支持重载,需要进行name managling。

//合法的重载例子
int abs(int i);
long abs(long i);
double abs(double i);

比如这三个abs函数,运行时编译器会对其进行名字改编,以便对这三个abs函数进行区分。

extern “C”

extern "C"实现C与C++混合编程。

extern "C" int abs(int i);

extern "C"表示不进行名字改编,按C语言的方式来解释这个函数名,C语言不支持名字改编,也就不支持函数重载,规范使用如下:

#include <iostream>
using namespace std;

#ifdef _cplusplus
extern "C"
{
#endif
void fun(int a){
	cout<<a<<endl;
} 

void fun2(double a){
	cout<<a<<endl;
}
#ifdef _cplusplus
}
#endif

int main() {
	
	fun(7);
	fun2(7.7);
	return 0;
}

带默认形参值的函数

函数声明或者定义的时候,可以给形参赋一些默认值。调用函数时,若没有给出实参,则按指定的默认值进行工作。
函数没有声明时,在函数定义中指定形参的默认值。函数既有定义又有声明时,声明时指定后,定义就不能再指定默认值 。
默认值的定义必须遵守从右到左的顺序,如果某个形参没有默认值,则它左边的参数就不能有默认值。

void func1 (int a, double b=4.5, int c=3 ) ; //合法
void func1 (int a=1, double b, int c=3 ) ;//不合法

内联函数

当程序执行函数调用时,系统要建立栈空间,保护现场,传递参数以及控制程序执行的转移等等,这些工作需要系统时间和空间的开销。有些情况下,函数本身功能简单,代码很短,但使用频率却很高,程序频繁调用该函数所花费的时间却很多,从而使得程序执行效率降低。

为了提高效率,一个解决办法就是不使用函数,直接将函数的代码嵌入到程序中。但这个办法也有缺点,一是相同代码重复书写,二是程序可读性往往没有使用函数的效果好。

为了协调好效率和可读性之间的矛盾,C++提供了另一种方法,即定义内联函数,方法是在定义函数时用修饰词inline。

内联函数与带参数宏区别

内联函数调用时,要求实参和形参的类型一致,另外内联函数会先对实参表达式进行求值,然后传递给形参;而宏调用时只用实参简单地替换形参。

内联函数是在编译的时候、在调用的地方将代码展开的,而宏则是在预处理时进行替换的。

在C++中建议采用inline函数来替换带参数的宏。

#include <iostream>
using namespace std;

inline int max(int a,int b){
	return a > b ? a : b;
}

#define MAX(a,b)((a)>(b)?(a):(b))

int main() {
	
	int a = 1;
	int b = 2;
	
	cout<<max(a,b)<<endl;
	cout<<MAX(a,b)<<endl;
	return 0;
} 

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

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

相关文章

单核CPU, 1G内存,也能做JVM调优吗?

最近&#xff0c;笔者的技术群里有人问了一个有趣的技术话题&#xff1a;单核CPU, 1G内存的超低配机器&#xff0c;怎么做JVM调优&#xff1f;这实际上是两个问题。单核CPU的超低配机器&#xff0c;怎么充分利用CPU&#xff1f;单核CPU, 1G内存的超低配机器&#xff0c;怎么做J…

python学习之OpenCV-Python模块的部分应用示例(生成素描图和动漫图)

文章目录前言一、图片转灰度二、对图片进行二值化处理三、对图片去除噪点四、调整图片透明度五、生成素描滤镜效果图&#xff08;方法结合应用&#xff09;六、生成动漫卡通滤镜效果图&#xff08;方法结合应用&#xff09;总结前言 OpenCV 是一个图像和视频处理库&#xff0c…

由Geoscene Enterprise 2.1 升级至Geoscene Enterprise 3.1

文章目录一、升级前工作二、升级Geoscene portal三、升级Web Adaptor&#xff08;针对portal门户&#xff09;四、升级Server 站点&#xff08;作为门户托管服务器&#xff09;五、升级Web Adaptor&#xff08;针对server&#xff09;六、升级Data Store需求&#xff1a;由GeoS…

bestSync外网转内网操作

一&#xff0e;外网笔记本操作 设置管理员密码打开笔记本电脑&#xff0c;设置管理员密码&#xff08;如果已经设置了的&#xff0c;请忽略该操作&#xff09;:左下角鼠标左键点击->控制面板->用户帐户和家庭安全->用户帐户->密码&#xff0c;密码设置完成后回到桌…

【Acwing 周赛复盘】第90场周赛复盘(2023.2.11)

【Acwing 周赛复盘】第90场周赛复盘&#xff08;2023.2.11&#xff09; 周赛复盘 ✍️ 本周个人排名&#xff1a;1488/2884 AC情况&#xff1a;1/3 这是博主参加的第五次周赛&#xff0c;这次做题的时候&#xff0c;感觉题目好难 &#x1f602; 但是一听y总讲解&#xff0c;又…

ORA error集锦

1、oralce 数据客户端需要安装的问题 保存信息为&#xff1a; “无法连接到数据库&#xff0c;因为数据库客户端软件无法加载。确保已正确安装并配置数据库客户端软件” 从百度网盘下载&#xff0c;并安装win32 oracle client 安装包 2、ORA错误 “执行异常,ORA-00911: inval…

TCP四次挥手

TCP 四次挥手过程是怎样的&#xff1f; TCP 断开连接是通过四次挥手方式。 双方都可以主动断开连接&#xff0c;断开连接后主机中的「资源」将被释放&#xff0c;四次挥手的过程如下图&#xff1a; 客户端打算关闭连接&#xff0c;此时会发送一个 TCP 首部 FIN 标志位被置为 1…

Revit标注问题:尺寸界线长度和“快速尺寸定位标注”

一、 Revit中关于标注的问题 1.有时候&#xff0c;但我们建完模型要进行一定的标注&#xff0c;往往会出现这样的间题&#xff0c;如图1所示 按照正常的标注来说&#xff0c;通常它的标注的正确方式应该是这样的&#xff0c;尺寸界线长度应该是指向图元的&#xff0c;如图2所示…

【源码系列】Faster RCNN源码详解(一)——transform

系列文章目录 文章目录系列文章目录前言一、transform二、总结1.标准化2.缩放3.batch前言 Faster RCNN的源码整体可以分为7个模块&#xff0c;每个模块负责不同的功能。推荐B站up霹雳吧啦Wz讲解的Faster RCNN源码&#xff0c;已经很详细了&#xff0c;这里只是个人的一些理解总…

【Unity VR开发】结合VRTK4.0:创建滑块

语录&#xff1a; 只有经历地狱般的磨练&#xff0c;才能炼出创造天堂的力量。 前言&#xff1a; 滑块是一个非常简单的控件&#xff0c;它允许通过沿有限的驱动轴滑动 Interactable 来选择不同的值。我们将使用线性驱动器创建一个滑块控件&#xff0c;该控件允许我们根据与滑…

蓝桥杯刷题五

1.01背包问题这题就是01背包问题的模板题 回顾一下01背包 01就是这个东西选和不选01背包的表达式是f[i]max(f[i-v]w,f[i]);那么这题就可以直接做了 值得注意的是这里只用了一维数组 所以更新的时候要从后往前面更新#include <bits/stdc.h> using namespace std; const in…

【JDK8新特性之Stream流-Stream结果收集案例实操】

一.JDK8新特性之Stream流-Stream结果收集以及案例实操 二.Stream结果收集(collect函数)-实例实操 2.1 结果收集到集合中 /*** Stream将结果收集到集合中以及具体的实现 collect*/Testpublic void test01(){// 收集到List中 接口List<Integer> list Stream.of(1, 2, 3…

码住!新手容易上手的5个tiktok数据分析网站

当下短视频已经称霸了各大内容平台&#xff0c;越来越多的创作者进入到短视频赛道&#xff0c;为了更好地运营自己的内容平台&#xff0c;数据分析是必不可少的。很多人都入局了tiktok&#xff0c;对于商家或者博主红人来说&#xff0c;这是比较新平台&#xff0c;希望能在这个…

Spring Cloud Gateway的使用

Spring Cloud Gateway网关Spring Cloud Gateway三大核心概念Route(路由)Predicate(断言)Filter(过滤)开始使用动态路由配置路由断言过滤器实现TokenIP验证拦截Spring Cloud Gateway 网关&#xff1a;微服务中最边缘的服务&#xff0c;用来做用户和微服务的桥梁 没有网关❓&…

Python使用VTK对容积超声图像进行体绘制(三维重建)

目录VTK简介什么是体绘制&#xff1f;体绘制效果图流程CodeQ&AReferenceVTK简介 VTK&#xff08;Visualization Toolkit&#xff09;是一个用于3D计算机图形学、图像处理和可视化的开源软件包。它包括一组C类和工具&#xff0c;可以让用户创建和处理复杂的3D图形和数据可视…

论文投稿指南——中文核心期刊推荐(音乐)

【前言】 &#x1f680; 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊 &#x1f384; 在期刊论文的分布中&#xff0c;存在一种普遍现象&#xff1a;即对于某一特定的学科或专业来说&#xff0c;少数期刊所含…

超纯水制备,MB-106UP抛光树脂的技术解析

超纯水&#xff08;Ultrapure water&#xff09;又称UP水&#xff0c;是指电阻率达到18 MΩ*cm&#xff08;25℃&#xff09;的水。这种水中除了水分子外&#xff0c;几乎没有什么杂质&#xff0c;更没有细菌、病毒、含氯二噁英等有机物&#xff0c;当然也没有人体所需的矿物质…

低代码是什么意思?企业为什么要用低代码平台?

低代码是什么意思&#xff1f;企业为什么要用低代码平台&#xff1f; 这两个问题似乎困扰了很多人&#xff0c;总有粉丝跟小简抱怨&#xff0c;一天到晚念叨低代码&#xff0c;倒是来个人解释清楚啊&#xff01; 来了&#xff0c;这次一文让你全明白。 先解释这几个名词&…

mysql5.7.39数据库服务搭建(win10)

mysql下载下载地址&#xff1a;https://downloads.mysql.com/archives/community如上图&#xff0c;选择了mysql 5.7.39版本&#xff0c;64位Windows操作系统&#xff1b;然后下载ZIP Archive格式的安装文件&#xff0c;点击“Download” 按钮即可。下载好后&#xff0c;进行解…

kafka入门到精通

文章目录一、kafka概述&#xff1f;1.定义1.2消息队列1.2.1 传统消息队列的使用场景1.2.2 消息队列好处1.2.3 消息队列两种模式1.3 kafka基础架构二、kafka快速入门1.1使用docker-compose安装kafka1.2测试访问kafka-manager1.3 查看kafka版本号1.4 查看zookeeper版本号1.5 扩展…