C++关键字之const、inline、static

news2024/11/13 18:57:00

C++ 关键字总结

1.const

  • const是 constant 的缩写,本意是不变的、不易改变的意思。
  • 在C++中用来修饰内置类型变量,自定义对象,成员函数,返回值,函数参数
  • 使用如下:
//修饰普通类型变量
const int a =7;
int b=a; //true
a=8;  //false
  • 修饰指针变量
//1.const修饰指针指向的内容,则内容为不可变量
const int *p=8;

//2.const修饰指针,则指针为不可变量
int a=9;
int* const p=&a;
*p=9; //正确
int b=7;
p=&b; //错误,指针不可变,改变其地址不对

//3.const修饰指针和指针指向的内容,则指针和指针指向的内容都为不可变量
int a=8;
const int * const p=&a;
  • const 参数传递和函数返回值
//1. A:值传递的 const 修饰传递,一般这种情况不需要 const 修饰,因为函数会自动产生临时变量复制实参值。
#include<iostream>
using namespace std;
 
void Cpf(const int a)
{
    cout<<a;
    // ++a;  是错误的,a 不能被改变
}
 
int main(void)
{
    Cpf(8);
    system("pause");
    return 0;
}

//2. 当 const 参数为指针时,可以防止指针被意外篡改。
#include<iostream>
using namespace std;
 
void Cpf(int *const a)
{
    cout<<*a<<" ";
    *a = 9;
}
 
int main(void)
{
    int a = 8;
    Cpf(&a);
    cout<<a; // a 为 9
    system("pause");
    return 0;
}

//3. 自定义类型的参数传递,需要临时对象复制参数,对于临时对象的构造,需要调用构造函数,比较浪费时间,
//因此我们采取 const 外加引用传递的方法,并且对于一般的 int、double 等内置类型,我们不采用引用的传递方式。
#include<iostream>
using namespace std;
 
class Test
{
public:
    Test(){}
    Test(int _m):_cm(_m){}
    int get_cm()const
    {
       return _cm;
    }
 
private:
    int _cm;
};
 
 
 
void Cmf(const Test& _tt)
{
    cout<<_tt.get_cm();
}
 
int main(void)
{
    Test t(8);
    Cmf(t);
    system("pause");
    return 0;
}
  • const 修饰函数的返回值
//1. const 修饰内置类型的返回值,修饰与不修饰返回值作用一样。
#include<iostream>
using namespace std;
 
const int Cmf()
{
    return 1;
}
 
int Cpf()
{
    return 0;
}
 
int main(void)
{
    int _m = Cmf();
    int _n = Cpf();
 
    cout<<_m<<" "<<_n;
    system("pause");
    return 0;
}

//2. const 修饰自定义类型的作为返回值,此时返回的值不能作为左值使用,既不能被赋值,也不能被修改。

//3. const 修饰返回的指针或者引用,是否返回一个指向 const 的指针,取决于我们想让用户干什么。
  • const修饰类成员函数
//const 修饰类成员函数,其目的是防止成员函数修改被调用对象的值
//如果我们不想修改一个调用对象的值,所有的成员函数都应当声明为 const 成员函数。
#include<iostream>
using namespace std;
 
class Test
{
public:
    Test(){}
    Test(int _m):_cm(_m){}
    int get_cm()const
    {
       return _cm;
    }
 
private:
    int _cm;
};
 
 
 
void Cmf(const Test& _tt)
{
    cout<<_tt.get_cm();
}
 
int main(void)
{
    Test t(8);
    Cmf(t);
    system("pause");
    return 0;
}
//***************************************************
class Test
{
public:
    Test(int _m,int _t):_cm(_m),_ct(_t){}
    void Kf()const
    {
        ++_cm; // 错误
        ++_ct; // 正确
    }
private:
    int _cm;
    mutable int _ct;
};

2.inline

  • 引入inline关键字原因

    • 在 c/c++ 中,为了解决一些频繁调用的小函数大量消耗栈空间(栈内存)的问题,特别的引入了 inline 修饰符,表示为内联函数。
    • 栈空间就是指放置程序的局部数据(也就是函数内数据)的内存空间。
    • 在系统下,栈空间是有限的,假如频繁大量的使用就会造成因栈空间不足而导致程序出错的问题,如,函数的死循环递归调用的最终结果就是导致栈内存空间枯竭。
  • 内联函数并不是一个增强性能的灵丹妙药。只有当函数非常短小的时候它才能得到我们想要的效果;但是,如果函数并不是很短而且在很多地方都被调用的话,那么将会使得可执行体的体积增大。

下面我们来看一个例子:

#include <stdio.h>
 
inline const char *num_check(int v)
{
    return (v % 2 > 0) ? "奇" : "偶";
}
 
int main(void)
{
    int i;
    for (i = 0; i < 100; i++)
        printf("%02d   %s\n", i, num_check(i));
    return 0;
}

3. static

  • 静态全局变量

    • 该变量在全局数据区分配内存
    • 未经初始化的静态全局变量会被成需自动初始化为0
    • 静态全局变量在声明它的整个文件都是可见的,而在文件之外是不可见的
    • 静态全局变量都在全局数据区分配内存,包括后边将要提到的静态局部变量。对于一个完整程序,在内存中的分布情况为:代码区//low address全局数据区堆区栈区//high address
    • 一般程序把新产生的动态数据存放在堆区,函数内部的自动变量存放在栈区。自动变量一般会随着函数的退出而释放空间,静态数据(即使是函数内部的静态局部变量)也存放在全局数据区。全局数据区的数据并不会因为函数的退出而释放空间。
      //示例1
      #include <iostream>
      using namespace std;
      void fn();  //声明函数
      static int n;  //声明静态全局变量
      int main()
      {
          n = 20;  //为n赋初值
          cout<<n<<endl;//输出n的值
          fn();  //调用fn函数
      }
      void fn()
      {
          n++;  //n的值自加一(n=n+1)
          cout<<n<<endl; //输出n的值
      }
      
  • 静态全局变量和全局静态变量的区别

    • 1)全局变量是不显视用static修饰的全局变量,全局变量默认是有外部链接性的,作用域是整个工程,在一个文件内定义的全局变量,在另一个文件中,通过extern 全局变量名的声明,就可以使用全局变量。
    • 2)全局静态变量是显式用static修饰的全局变量,作用域是声明此变量所在的文件,其他的文件即使用extern声明也不能使用。
//示例2
//File1.c第一个代码文件的代码
#include <iostream>
using namespace std;
void fn();  //声明fn函数
static int n;  //定义静态全局变量
int main()
{
    n = 20;
    cout<<n<<endl;
    fn();
}
//File2.c第二个代码文件的代码
#include <iostream>
using namespace std;
extern int n;
void fn()
{
    n++;
    cout<<n<<endl;
}

编译并运行Example 2,您就会发现上述代码可以分别通过编译,但运行时出现错误。试着将
static int n; //定义静态全局变量
改为
int n; //定义全局变量
再次编译运行程序,细心体会全局变量和静态全局变量的区别。

  • 静态局部变量

    • 该变量在全局数据区分配内存;
    • 静态局部变量在程序执行到该对象的声明处时被首次初始化,即以后的函数调用不再进行初始化;
    • 静态局部变量一般在声明处初始化,如果没有显式初始化,会被程序自动初始化为0;
    • 它始终驻留在全局数据区,直到程序运行结束。但其作用域为局部作用域,当定义它的函数或语句块结束时,其作用域随之结束;
//示例3
#include <iostream>
using namespace std;
void fn();
int main()
{
    fn();
    fn();
    fn();
    return 0;
}
void fn()
{
    static int n = 10;
    cout<<n<<endl;
    n++;
}
  • 静态函数

    • 静态函数不能被其他文件所用
    • 其他文件中可以定义相同名字的函数,不会发生冲突
  • 面向对象(类)中的静态属性使用

      1. 静态数据成员
      • 1)静态数据成员可以实现多个对象之间的数据共享,它是类的所有对象的共享成员,它在内存中只占一份空间,如果改变它的值,则各对象中这个数据成员的值都被改变。
      • 2)静态数据成员是在程序开始运行时被分配空间,到程序结束之后才释放,只要类中指定了静态数据成员,即使不定义对象,也会为静态数据成员分配空间。
      • 3)静态数据成员可以被初始化,但是只能在类体外进行初始化,若未对静态数据成员赋初值,则编译器会自动为其初始化为 0。
      • 4)静态数据成员既可以通过对象名引用,也可以通过类名引用。
      1. 静态成员函数
      • 1)静态成员函数和静态数据成员一样,他们都属于类的静态成员,而不是对象成员。
      • 2)非静态成员函数有 this 指针,而静态成员函数没有 this 指针。
      • 3)静态成员函数主要用来方位静态数据成员而不能访问非静态成员。

再给一个利用类的静态成员变量和函数的例子以加深理解,这个例子建立一个学生类,每个学生类的对象将组成一个双向链表,用一个静态成员变量记录这个双向链表的表头,一个静态成员函数输出这个双向链表。

#include <stdio.h>
#include <string.h>
const int MAX_NAME_SIZE = 30;  
 
class Student  
{  
public:  
    Student(char *pszName);
    ~Student();
public:
    static void PrintfAllStudents();
private:  
    char    m_name[MAX_NAME_SIZE];  
    Student *next;
    Student *prev;
    static Student *m_head;
};  
 
Student::Student(char *pszName)
{  
    strcpy(this->m_name, pszName);
 
    //建立双向链表,新数据从链表头部插入。
    this->next = m_head;
    this->prev = NULL;
    if (m_head != NULL)
        m_head->prev = this;
    m_head = this;  
}  
 
Student::~Student ()//析构过程就是节点的脱离过程  
{  
    if (this == m_head) //该节点就是头节点。
    {
        m_head = this->next;
    }
    else
    {
        this->prev->next = this->next;
        this->next->prev = this->prev;
    }
}  
 
void Student::PrintfAllStudents()
{
    for (Student *p = m_head; p != NULL; p = p->next)
        printf("%s\n", p->m_name);
}
 
Student* Student::m_head = NULL;  
 
void main()  
{   
    Student studentA("AAA");
    Student studentB("BBB");
    Student studentC("CCC");
    Student studentD("DDD");
    Student student("MoreWindows");
    Student::PrintfAllStudents();
}

程序将输出:
在这里插入图片描述

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

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

相关文章

人工智能对教育的冲击有多大?

人工智能对教育有巨大冲击 高考改革也会发生重大变化 教育系统其实是一个坚固的堡垒 再坚固也要适应未来 趣讲大白话&#xff1a;让我未来更有竞争力 *********** 创造和创新的意识和能力 复杂性和不确定性的适应能力 应该是改革的方向 【安志强趣讲信息科技】74期 掌握信息科…

【人工智能】对贝叶斯网络进行吉布斯采样

问题 现要求通过吉布斯采样方法&#xff0c;利用该网络进行概率推理&#xff08;计算 P(RT|SF, WT)、P2(CF|WT)的概率值&#xff09;。 原理 吉布斯采样的核心思想为一维一维地进行采样&#xff0c;采某一个维度的时候固定其他的维度&#xff0c;在本次实验中&#xff0c;假…

分享开放通达信l2接口的过程,开发之后怎么使用?

随着互联网的不断进步&#xff0c;信息技术的不断发展&#xff0c;通达信l2接口技术逐步成熟。那么&#xff0c;这些开放通达信l2接口开发的过程是怎么样的呢?期间又会遇到什么问题&#xff0c;开放之后又会怎么使用呢&#xff1f;这篇文章带你深入了解。 通达信l2接口不像一…

高通8155 GPS HAL层代码移植

1.添加gps hal层代码包 将ublox gps芯片的hal层代码拷贝至apps/LINUX/android/hardware/ublox/路径下&#xff0c;树状图如下&#xff1a; 2.修改编译选项 将新增的ublox gps hal层代码编译进入image&#xff0c;需要修改apps/LINUX/android/device/qcom/msmnile_gvmgh/路径下的…

基于Python来爬取某音动态壁纸,桌面更香了!

至于小伙伴们想要这个封图&#xff0c;我也没有。不过继续带来一波靓丽壁纸&#xff0c;而且是动态的&#xff0c;我的桌面壁纸又换了&#xff1a;每天换着花样欣赏一波波动态壁纸桌面立刻拥有了高颜值&#xff0c;简直跟刷美女短视频一样啊。对的&#xff0c;这些动态壁纸就是…

Linux信号一门搞定

1.信号是什么&#xff1f; 信号其实就是一个软件中断。 例&#xff1a; 输入命令&#xff0c;在Shell下启动一个前台进程。用户按下Ctrl-C&#xff0c;键盘输入产生一个硬件中断。如果CPU当前正在执行这个进程的代码&#xff0c;则该进程的用户空间代码暂停执行&#xff0c;…

Linux | Liunx安装Tomcat(Ubuntu版)

目录 一、下载并上传Tomcat压缩包到Ubuntu 1.1 下载并解压 1.2 执行 startup.sh 文件 二、验证Tomcat启动是否成功 2.1 查看启动日志 2.2 查看启动进程 三、Windows访问 Tomcat 服务 四、停止 Tomcat 服务 Tomcat是一款Web服务器&#xff0c;开发Web项目基本上都会用到…

应用篇|如何精准搜索一个答题考试小程序

应用篇|如何精准搜索一个答题考试小程序在线考试是一种非常节约成本的考试方式&#xff0c;考生通过微信扫码即可参加培训考试&#xff0c;不受时间、空间的限制&#xff0c;近几年越来越受企事业单位的青睐。比如有以下场景&#xff1a;为落实反电信网络诈骗普法宣传教育工作&…

【云原生-Docker】docker镜像制作、上传、dockerfile命令解析

场景 在实际业务场景中&#xff0c;需要制作多个不同版本进行镜像使用&#xff0c;如maven版本、JDK、openJDK不同使用等&#xff0c;所以需要做多个针对不同版本做不同的镜像。这里记录一下之前devops用的openJDK版本、某些部门需要用orcle JDK、特此需要做不同的镜像&#x…

C#学习笔记--泛型函数的==和Equals(看完你一定能学到!)

前言 工作的同事发现了这个问题&#xff0c;觉得实际游戏开发中会有这样的问题&#xff0c;所以在此记录 准备 开一个Unity项目&#xff0c;新建一个Test.cs脚本&#xff0c;并且生成一个Cube&#xff0c;直接把Test.cs挂在Cube上写一个Nulltest.cs脚本 using System.Colle…

【C++从入门到放弃】初识C++(基础知识入门详解)

&#x1f9d1;‍&#x1f4bb;作者&#xff1a; 情话0.0 &#x1f4dd;专栏&#xff1a;《C从入门到放弃》 &#x1f466;个人简介&#xff1a;一名双非编程菜鸟&#xff0c;在这里分享自己的编程学习笔记&#xff0c;欢迎大家的指正与点赞&#xff0c;谢谢&#xff01; C基础…

CentOS搭建博客typecho

Ubuntu搭建博客typecho_Dyansts的博客-CSDN博客 见过这样的文章展示页面吗&#xff1f; 详细视频安装教程&#xff1a; 9分钟快速搭建typecho博客&#xff0c;让你不再烦恼_哔哩哔哩_bilibili 现在就把他搭建出来 展示页面&#xff1a;Hello World 其他的插件&#xff1a;…

真的要用SaaS类产品做企业的移动办公平台吗?

面对越来越多的企业信息移动化解决方案&#xff0c;作为CIO该如何选择移动平台呢&#xff1f;先看看最常见的SaaS产品的情况。真的要用SaaS类产品做企业的移动门户吗&#xff1f;当前&#xff0c;热门SaaS类产品主要是企业微信和钉钉&#xff0c;适合小微初创企业。企业在不同成…

Chem. Sci.|AlphaFold加速了人工智能药物的发现:一种新型CDK20小分子抑制剂

​ 题目&#xff1a;AlphaFold accelerates artificial intelligence powered drug discovery: efficient discovery of a novel CDK20 small molecule inhibitor 文献来源&#xff1a;Chem. Sci., 2023, 14, 1443 代码&#xff1a;是一个很大的流程 https://www.pandaomics…

CountDownLatch的定义、使用 、原理

一、定义 CountDownLatch的作用很简单&#xff0c;就是一个或者一组线程在开始执行操作之前&#xff0c;必须要等到其他线程执行完才可以。我们举一个例子来说明&#xff0c;在考试的时候&#xff0c;老师必须要等到所有人交了试卷才可以走。此时老师就相当于等待线程&#xff…

《Terraform 101 从入门到实践》 Terraform在公有云Azure上的应用

《Terraform 101 从入门到实践》这本小册在南瓜慢说官方网站和GitHub两个地方同步更新&#xff0c;书中的示例代码也是放在GitHub上&#xff0c;方便大家参考查看。 简介 Azure是微软的公有云&#xff0c;它提供了一些免费的资源&#xff0c;具体可以查看&#xff1a; https:/…

从零开始学数据分析之数据分析概述

当今世界对信息技术的依赖程度在不断加深&#xff0c;每天都会有大量的数据产生&#xff0c;我们经常会感到数据越来越多&#xff0c;但是要从中发现有价值的信息却越来越难。 这里所说的信息&#xff0c;可以理解为对数据集处理之后的结果&#xff0c;是从数据集中提炼出的可…

11- 聚类算法 (KMeans/DBSCAN/agg) (机器学习)

聚类算法 聚类算法和降维算法那都属于无监督算法。KMeans 是以一个值为中心, 然后所有其他点到该点距离最小值的累积和。 kmeans KMeans(n_clusters3) # n_clusters 分类数量 kmeans.fit(data.iloc[:,1:]) # 无监督&#xff0c;只需要给数据X就可以 DBSCAN 算法是…

GAMES101作业7及课程总结(重点实现多线程加速,微表面模型材质)

目录闲言碎语最终全部效果展示&#xff08;均为10241024512ssp&#xff09;课程总结与理解&#xff08;Path Tracing&#xff09;框架梳理任务一&#xff1a;迁移相关代码任务二&#xff1a;实现path tracing任务三&#xff1a;多线程加速&#xff08;包括其他加速的小trick&am…

Cocos Creator 3.x开发《切水果3D》

今天跟大家分享一个Cocos Creator 3D切水果的实战案例&#xff0c;帮助大家掌握Cocos Creator开发3D微信抖音小游戏&#xff0c;开发工具我们采用的是Cocos Creator 3.6。先上一波游戏操作效果图&#xff0c;接下来通过本文来讲解这个游戏的一些核心的技术点。 对啦&#xff0…