C/C++关键字大全

news2024/9/22 19:41:32

目录

一、const

二、static

三、#define 和 typedef

四、#define 和 inline

五、#define 和 const

六、new 和 malloc

七、const 和 constexpr

八、volatile

九、extern

十、前置 ++ 和后置 ++

十一、atomic

十二、struct 和 class


一、const


1、const 关键字可用于定义常量,一旦被赋值,其值在程序运行期间就不能被修改。

const int num = 10;  // 定义一个常量 num,值为 10

2、const 用来修饰指针时,有两种用法:

(1)const 数据类型 *指针变量 = 变量名 or  数据类型 const  *指针变量 = 变量名

当const在*前时,指的是不能通过这个指针变量来修改其指向的值,而指针本身可被修改

int temp = 10, b = 1;
const int* a = &temp;
int const *a = &temp;
// 更改:
*a = 9; // 错误:只读对象
temp = 9; // 正确
a = &b; //正确

(2)数据类型 * const 指针变量 = 变量名

当const在*后时,指的是指针本身不可被修改,但可以通过指针修改其指向的值

int temp = 10;
int temp1 = 12;
int* const p = &temp;
// 更改:
p = &temp2; // 错误
*p = 9; // 正确

3、const 可用来修饰引用,表示不能通过该引用修改变量

int temp = 10;
const int& t = temp;
temp = 9; // 正确
t = 9;  //错误

其中,const权限只可降级,即非const引用或非const值可以初始化const引用,而反过来不行

int temp1 = 10;
const int temp2 = 5;
int& a = temp1;
const int& b = a; //正确
int& c = b; //错误,const权限不可升级
int& d = temp2; //错误,const权限不可升级

4、const修饰成员函数和实例对象

  • 当一个成员函数被 const 修饰时,它表明这个函数不会修改类的成员变量,但可以修改类的静态成员变量,因为静态成员变量不属于对象本身,而是属于整个类的,是所有对象共享一个的。
  • 当一个对象被 const 修饰后,意味着这个对象在生命周期内的成员属性不可改变,故该对象只能调用 const 成员函数。
#include <iostream>

class MyClass {
private:
    int nonStaticValue;
public:
    static int staticValue;

    MyClass(int v) : nonStaticValue(v) {}

    int getNonStaticValue() const {  // const 成员函数
        return nonStaticValue;
    }

    void modifyStaticValue(int v) const {  // const 成员函数修改静态成员变量
        staticValue = v;
    }
};

int MyClass::staticValue = 0;  // 静态成员变量初始化

int main() {
    const MyClass obj(10);  // 创建 const 对象

    std::cout << obj.getNonStaticValue() << std::endl;  // 可以调用 const 成员函数获取非静态成员变量的值

    obj.modifyStaticValue(20);  // const 成员函数可以修改静态成员变量

    std::cout << MyClass::staticValue << std::endl;  // 输出修改后的静态成员变量的值

    return 0;
}

二、static

1、在函数内部,static 修饰的变量其生存期贯穿整个程序运行期间,但作用域仍在函数内部。

void func() {
    static int count = 0;  // 每次调用 func 函数,count 的值都会保留
    count++;
}

2、在类中,static 成员变量属于整个类,而非某个对象。

class MyClass {
public:
    static int staticVar;
};

int MyClass::staticVar = 0;

3、如果static修饰了全局变量,生命周期不变,还是全局,但是作用域降为了本文件有效;修饰全局函数是同样的道理

#include <iostream>

// 定义全局变量
static int globalStaticVar = 10;  // 使用 static 修饰的全局变量

void function() {
    std::cout << "globalStaticVar in function: " << globalStaticVar << std::endl;
}

int main() {
    std::cout << "globalStaticVar in main: " << globalStaticVar << std::endl;
    function();

    // 错误:在其他文件中无法访问这个 static 修饰的全局变量
    // extern int globalStaticVar;  

    return 0;
}

4、static修饰成员函数,不与特定的对象相关联,可以通过类名和作用域解析运算符直接调用,虽然仍然可以使用实例化对象调用静态成员函数,但在实际编程中不推荐这样的写法,因为静态成员函数不依赖于具体的对象实例,它是属于整个类的。通常更推荐使用类名直接来调用静态成员函数,如下所示:

MyClass::staticMethod();

三、#define 和 typedef

在 C 和 C++ 中,#define 和 typedef 都可以用于给类型取别名,但它们之间存在一些重要的区别。

1、语法和实现机制

  • #define 是预处理器指令,通过简单的文本替换来实现别名定义。
#define INT_PTR int*
  • typedef 则是在编译阶段起作用的关键字。
typedef int* IntPtr;

2、作用域

  • #define 不受作用域限制,在预处理器阶段进行替换,全局有效
  • typedef 遵循作用域规则,在其定义的作用域内有效。

3、类型检查

  • #define 只是简单的文本替换,没有类型检查。
  • typedef 是类型定义,具有类型检查。

4、复杂类型处理

  • 对于复杂的类型,如指针、数组等,typedef 更清晰和直观。例如,对于指向函数的指针,使用 typedef 更易理解。
typedef int (*FuncPtr)(int);
  • #define 在处理复杂类型时可能会导致混淆和错误。

5、可移植性

  • typedef 的行为在不同的编译器中通常更一致,具有更好的可移植性。

总的来说,虽然 #define 和 typedef 都能给类型取别名,但在大多数情况下,特别是对于复杂类型和需要类型检查及良好可移植性的场景,typedef 是更推荐的选择。


四、#define 和 inline

在 C/C++ 中,inline 函数和宏函数都有在代码中进行内联展开以提高性能的作用,但它们之间存在一些显著的区别。

1、语法和定义方式

  • inline 函数是使用 inline 关键字修饰的正常函数。
inline int add(int a, int b) {
    return a + b;
}
  • 宏函数则是通过 #define 宏定义来实现的,只是在预处理阶段简单的文本替换
#define ADD(a, b) ((a) + (b))

2、类型检查

  • inline 函数具有严格的类型检查,参数类型必须匹配。
  • 宏函数只是简单的文本替换,不进行类型检查,可能会导致潜在的类型错误。

3、参数处理

  • inline 函数对参数的处理是按照函数的参数传递规则进行的。
  • 宏函数如果定义不当可能会出现不符合预期的情况,例如:
#define SQUARE(x) (x * x)
int a = 2 + 3;
int b = SQUARE(a);  // 会被替换为 (2 + 3) * 2 + 3),结果不符合预期

//正确定义:
#define SQUARE(x) ((x) * (x))

4、调试

  • inline 函数可以像普通函数一样进行调试,可以设置断点、查看调用栈等。
  • 宏函数在调试时可能会带来困难,因为它们在预处理阶段就被替换了。

5、代码可读性

  • inline 函数的定义方式更符合函数的常规语法,代码可读性更好。
  • 宏函数的定义可能会使代码看起来比较复杂,可读性较差。

在大多数情况下,inline 函数由于具有更好的类型安全性、可读性和调试性,是更优的选择。然而,在一些简单且性能关键的场景中,宏函数可能仍然有用。最后一点就是,inline只是对编译器的建议,具体做不做内联,要看编译器的选择。

五、#define 和 const


const和#dfine都可以用来定义常量,#define只是对字面量的文本替换,没有类型检查,预处理器在替换时也不会考虑作用域;const定义的常量是在编译时要进行类型检查的

#define PI 3.14159    
const double Pi = 3.14159;

六、new 和 malloc

1、new内存分配失败时,会抛出bac_alloc异常,它不会返回NULL;malloc分配内存失败时返回NULL。

2、使⽤new操作符申请内存分配时⽆须指定内存块的⼤⼩,⽽malloc则需要显式地指出所需内存的尺⼨。

3、opeartor new /operator delete可以被重载,⽽malloc/free并不允许重载。

4、new/delete会调⽤对象的构造函数/析构函数以完成对象的构造/析构。⽽malloc/free则不会

5、malloc与free是C++/C语⾔的标准库函数,new/delete是C++的运算符

6、new会返回申请类型的指针,malloc是返回void*指针,需要强制转换

七、const 和 constexpr


const 和 constexpr 都用于定义常量,const 的值可以在运行时确定,而 constexpr 的值必须在编译时确定。constexpr 对值的确定时间有更严格的要求,并且在一些特定的场景中能提供更好的性能和代码可读性。

八、volatile


volatile 用于告诉编译器,该变量的值可能会被意外地改变,不要进行 volatile修饰的变量,旨在告诉编译器,关闭对这个变量的编译优化,当需要对改变了进行读写和运算时,必须从内存重新装载内容,而不允许读取寄存器中的缓存。

九、extern


extern 用于声明一个在其他文件中定义的全局变量或函数。

十、前置 ++ 和后置 ++


前置++返回已经修改过的对象本身,而后置++返回被修改之前的临时对象,所以后置++的表达式不能作为左值,但前置++可以

int num = 6;
int preIncrement = ++num;  // 返回7
int postIncrement = num++;  // 返回 6

十一、atomic

atomic 用于实现原子操作,确保在多线程环境中的操作是原子性的,不会被其他线程打断。

  • 定义

    • atomic 通常用于多线程编程中,用于确保对特定类型的操作是原子性的。
  • 用途

    • 保证操作的原子性:在多线程环境下,原子操作可以避免数据竞争和不一致性。例如,对一个整数的递增或读取操作,如果使用 atomic 类型包装,就能保证在多线程并发访问时不会出现中间状态的错误。
  • 示例

    #include <atomic>
    
    // 定义一个原子整数
    std::atomic<int> atomicVar(0);  //C++17支持"="初始化
    
    void threadFunction() {
        atomicVar++;  // 原子性的递增操作
    }
    
    int main() {
        // 创建多个线程执行 threadFunction
        return 0;
    }
    
  • 注意事项

    • 并非所有的操作都能被原子化,具体取决于所使用的原子类型和编译器的支持。
    • 使用 atomic 虽然能保证原子性,但可能会带来一定的性能开销。

总之,atomic 是多线程编程中的重要工具,能有效地提高程序在多线程环境下的正确性和稳定性,但需要在性能和正确性之间进行权衡。

十二、struct 和 class

在 C 语言中,struct 主要用于简单地将不同类型的数据组合在一起,形成一个新的数据类型。其成员均为公开的,并且 struct 本身无法包含成员函数,仅仅是纯粹的数据组合。

在 C++ 中,struct 得到了显著的提升,实际上被视为类的一种形式。尽管 struct 的成员默认访问权限为 public,但它也能够像 class 一样显式地指定成员的访问权限为私有或受保护。并且,struct 还可以在其内部声明成员函数,从而实现更为复杂的行为和操作。

以下是 C++ 中 struct 包含成员函数的示例:

struct Student {
    std::string name;
    int age;

    void displayInfo() {  // 成员函数
        std::cout << "Name: " << name << ", Age: " << age << std::endl;
    }
};

基于上述特性,在实际编程中,建议采取以下最佳实践:

对于仅仅是数据的简单组合,且希望成员默认具有公共访问权限的情况,使用 struct 是一个不错的选择。例如,当定义一些纯粹用于数据传递或存储的结构体时,struct 能够清晰地表达数据的结构,并且方便数据的访问和操作。

当面对更为复杂的对象,涉及到数据的封装、隐藏以及更丰富的行为和操作时,使用 class 进行定义会更为合适。通过将成员设置为私有,并提供公共的接口函数来控制对象的状态和行为,可以更好地实现面向对象编程中的封装和信息隐藏原则,增强代码的健壮性、可维护性和可扩展性。

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

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

相关文章

在vscode中远程连接linux进行开发

目录 引言 配置过程 1.本机安装OpenSSH 2.本机生成RSA公钥和私钥 3.将rsa公钥添加到远程linux的authorized_keys文件中 4.vscode安装Remote - SSH插件 5.在vscode中ssh连接服务器 6.在本地vscode操作远程linux文件进行开发 7.在vscode上给远程linux机器需安装插件 常…

路径规划——贪婪最佳优先搜索

路径规划——贪婪最佳优先搜索 学习A算法前先学习一下贪婪最佳优先搜索算法&#xff0c;在学习过程中在网上找了一些博客、文章还有视频来看以深入理解此算法&#xff0c;但是实际情况却是非常令人恼怒。有些文章标题是贪婪最佳优先搜索&#xff0c;内容却是其他的算法&#x…

【密码学】椭圆曲线密码体制(ECC)

椭圆曲线密码体制&#xff08;Elliptic Curve Cryptography, ECC&#xff09;是一种基于椭圆曲线数学特性的公钥密码系统。在介绍椭圆曲线之前&#xff0c;我们先来了解一下椭圆曲线的基本概念。 一、椭圆曲线是什么&#xff1f; &#xff08;1&#xff09;椭圆曲线的数学定义…

PolSARPro软件安装处理TerraSAR数据(CSDN_20240804)

1. 打开polSARPro软件&#xff0c;点击Enter 2. 点击OK 3. 点击左侧第一个图像&#xff0c;进入PolSARPro Bio。 4. 点击Enter. 5. 点击Environment&#xff0c;选择Single Data Set 6. 选择工作路径 7. 点击No 8. Import -> Spaceborne Sensors ->TerraSAR-X->Quad-P…

C++的vector类

目录 简介 特点 接口 构造函数 迭代器函数 Capacity系列 element access系列 modifiers系列 定义在全局的重载函数 find 总结 简介 vector 是 C 标准模板库&#xff08;Standard Template Library&#xff0c;简称 STL&#xff09;中的一个模板类&#xff0c;用于表…

【iOS】——GCD总结

同步和异步的区别 同步执行等待操作完成&#xff0c;而异步执行允许程序在操作完成前继续运行&#xff0c;提高了效率和响应性。这里的关键就是上一个操作需不需要等待当前操作的执行&#xff0c;如果需要就是同步&#xff0c;如果不需要就是异步。 异步有开启新线程的能力但…

如何构建AI产品:OpenAI与前Shopify产品负责人Miqdad Jaffer的经验分享

一、引言 构建AI产品是一项复杂且充满挑战的任务&#xff0c;尤其是当涉及到面向消费者的解决方案时。在最近的一期播客节目中&#xff0c;OpenAI 和前Shopify产品负责人 Miqdad Jaffer 分享了他在构建AI产品的经验和策略。下面我们将探讨构建AI产品的最佳实践&#xff0c;以及…

行为型设计模式1:状态/策略/命令

行为型设计模式&#xff1a;状态/策略/命令 (qq.com)

【秋招笔试】24-08-03-米哈游-秋招提前批笔试题

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 编程一对一辅导 ✨ 本系列打算持续跟新 秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 🍰 米哈游提前批笔试也是来了,本次题目…

初谈表的约束

文章目录 概念空属性默认值空属性和默认值对比列描述zerofill主键 概念 真正约束字段的是数据类型&#xff0c;但是数据类型约束很单一&#xff0c;需要有一些额外的约束&#xff0c;更好的保证数据的合法性&#xff0c;从业务逻辑角度保证数据的正确性。比如有一个字段是emai…

Open3D 计算点云的归一化协方差矩阵

目录 一、概述 1.1原理 1.2实现步骤 1.3应用 二、代码实现 2.1关键函数 2.2完整代码 三、实现效果 3.1原始点云 3.2数据显示 Open3D点云算法汇总及实战案例汇总的目录地址&#xff1a; Open3D点云算法与点云深度学习案例汇总&#xff08;长期更新&#xff09;-CSDN博…

文章相关接口

1.新增文章分类 文章分类的表结构和实体类 实体类 接口文档 实现 新创建CategoryController,CategoryService,(CategoryServiceImpl),CategoryMapper 在CategoryController中添加方法 使用注解PostMapping,没有映射路径&#xff0c;我们在CategoryController的类上添加一个映…

Java 并发编程:Java 中的乐观锁与 CAS

大家好&#xff0c;我是栗筝i&#xff0c;这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 025 篇文章&#xff0c;在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验&#xff0c;并希望进…

【DOCKER】显示带UI的软件

1. Linux 1.1 宿主机开放X server权限 xhost 1.2 启动容器 docker run -it --rm --privilegedtrue --useru20 --workdir/home/u20 \ -e DISPLAYhost.docker.internal:0 u20:dev1.3 测试 # 安装测试软件 sudo apt-get -y install x11-apps# 显示测试程序 xclock2. Windows …

websocket的学习

第一步&#xff1a;配置Spring <dependency><groupId>org.springframework</groupId><artifactId>spring-messaging</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> …

RabbitMQ知识总结(基本原理+高级特性)

文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 基本原理 消息的可靠性投递 RabbitMQ 消息的投递路径为&#xff…

Idea包含UI内容的插件开发

Idea包含UI内容的插件开发 前言插件效果项目结构配置功能的实现找一个股票接口完成最终的页面配置Plugin.xml源码地址 前言 在这一篇文章中将会做一个包含UI内容的能看股票的插件。 插件效果 首先是在设置中配置股票的编号&#xff0c;如sh000001,sh600519。 接着在侧边栏中…

手机端微信聊天记录无法全部同步到电脑端的微信?搞定它!

前言 昨天晚上深夜…… 哼哼&#xff0c;想哪去了&#xff1f; 昨天有个深圳的哥们跟小白吐槽&#xff1a;手机端的微信聊天记录怎么没办法自动同步到电脑端上&#xff1f; 刚开始小白还以为他是因为电脑端的微信在线也没办法同步聊天记录&#xff0c;所以就给出了答案&…

样式与特效(3)——实现一个测算页面

这次我们使用前端实现一个简单的游戏页面,理论上可以增加很多玩法&#xff0c;&#xff0c;但是这里为了加深前端的样式和JS点击事件&#xff0c;用该案例做练习。 首先需要掌握手机端的自适应&#xff0c;我们是只做手机端玩家页面 。需要允许自适应手机端页面&#xff0c; 用…

OpenCV||超详细的图像处理模块

一、颜色变换cvtColor dst cv2.cvtColor(src, code[, dstCn[, dst]]) src: 输入图像&#xff0c;即要进行颜色空间转换的原始图像。code: 转换代码&#xff0c;指定要执行的颜色空间转换类型。这是一个必需的参数&#xff0c;决定了源颜色空间到目标颜色空间的转换方式。dst…