c++——c/c++中的static和const

C语言和c++中的static关键字与const关键字

static: //改变存储区域,限制作用域

①、改变存储区域:
在不同的上下文中,static 关键字可以用于改变变量或函数的存储区域。在函数内部,static 用于将局部变量的生存期从函数的生命周期扩展到整个程序的生命周期,并将其存储在静态存储区中。

示例:

void foo() {static int count = 0;  // 静态局部变量count++;std::cout << "Count: " << count << std::endl;
}int main() {foo();  // 输出:Count: 1foo();  // 输出:Count: 2return 0;
}

②、限制作用域:
static 还可以用于限制变量、函数或类的作用域,使其仅在声明它们的文件中可见,而不是跨越整个程序的多个文件。这种情况下,static 在全局变量、函数和类的上下文中使用。

示例:

Copy code
// File1.cpp
static int globalVar = 42;  // 在当前文件中可见// File2.cpp
extern int globalVar;  // 从另一个文件中访问失败,因为 globalVar 的作用域被限制在了 File1.cpp 中

在这个示例中,globalVar 被声明为静态全局变量,它的作用域限制在了声明它的文件 File1.cpp 中,其他文件无法直接访问。

一、C和c++中的static

static

1、修饰局部变量 //改变存储区域: 栈区–>数据段 ,作用域:局部作用域

②C语言中static修饰的局部变量:
​ 在修饰局部变量时,static修饰的静态局部变量只执行一次, 其会改变局部变量的存储位置,从而使得局部变量的生命周期变长,直到程序运行结束以后才释放。

void test()
{int x = 0;x++;printf("%d ", x);
}int main()
{int i = 0;while (i < 5){test();i++;}return 0;
}
//1 1 1 1 1 
void test()
{static int x = 0;x++;printf("%d ", x);
}int main()
{int i = 0;while (i < 5){test();i++;}return 0;
}
//1 2 3 4 5  

②c++中static修饰的局部变量:
局部变量也就是定义在函数内部的变量,函数局部变量存放在栈区,该变量的生命周期由所在 {} 决定,进入 {} 作用范围而分配内存空间,退出 {} 作用范围而释放内存空间。
在局部变量的前面加上static,变成静态局部变量,即使多次调用该函数,静态变量的空间也只分配一次。

using namespace std;
void fun()
{static int n = 5;printf("%d\n", n);n++;
}
int main()
{int i;for(i=0; i<5; i++){fun();}return 0;
}

2、修饰全局变量 //限制作用域:外部链接属性–>内部链接属性

①C语言中的static修饰的全局变量
​static修饰全局变量的时, 会改变全局变量的链接属性,从而使得全局变量作用域变为只能在本文件中访问,extern无法调用。

c文件1

int i = 10;

c文件2

extern int i;
int main()
{printf("%d\n",i);return 0;
}

如果全局变量被static修饰,那这个外部链接属性就会被修改成内部链接属性
②c++中static修饰的全局变量
全局变量的空间会在程序的生命周期内分配,在全局变量的前面加上static,变成静态全局变量。

using namespace std;
static int n = 5;
int main()
{n = 10;printf("%d\n", n);return 0;
}

3、修饰函数 //限制作用域:外部链接属性–>内部链接属性

①C语言中static修饰函数
​static修饰一个函数,则这个函数的只能在本文件中调用,不能被其他文件调用。

​函数本身也是有外部链接属性的,而被static修饰后,函数的外部链接属性被修改成内部链接属性

c文件1

int Add(int a,int b)
{return x+y;
}

c文件2

extern int Add(int a,int b);
int main()
{int x = 3;int y = 4;int z = Add(x,y);printf("%d\n",z);return 0;
}

②c++中的static修饰函数
被static修饰的函数,叫静态函数。静态函数只能在当前文件中被访问,不可再其他文件中调用。其它文件中可以定义相同名字的函数,不会发生冲突


4、在c++中static还可以修饰成员变量 :静态成员变量, //不用通过对象调用, 所有对象共有的变量,

类的所有实体共享这个变量。

类的数据成员在类外定义时不加static。

class Test {
public:double d;static int n;
};int Test::n;  // 静态成员变量需要在类外声明(分配空间,可以显式初始化,默认初始化为0)cout << sizeof(Test) << endl;
cout << Test::n << endl;// 运行结果:8 0

静态成员变量存储在全局/静态区,静态成员变量只有在类外声明时才分配空间,可显式初始化,不显式初始化,默认初始化为0。
静态成员变量属于类不属于对象,sizeof()的结果不包括静态成员变量大小
可通过对象调用,也可以通过类名作用域调用(非静态成员变量只能通过对象调用)
静态常量整型数据成员可在类内初始化,也可在类外初始化


5、在c++中static还可以修饰成员函数: 静态成员函数,静态方法 //不用通过对象调用

静态成员函数中只能调用静态成员变量和静态成员函数

类的静态成员函数在类外实现时,与数据成员一样不需要加 static

class Test {
public:static void show() {cout << n << endl;}private:double d;static int n;
};int Test::n;cout << sizeof(Test) << endl;
Test::show();// 运行结果:8 0

二、C和c++中的const

const:

const含义:只要一个变量前用const来修饰,就意味着该变量里的时数据只能被访问,而不能被修改,也就是意味着“只读”(readonly)

const在类中既可以修饰成员变量也可以修饰成员函数本身,甚至还能修饰对象

const作用:
1:可以用来修饰变量,修饰函数参数,修饰函数返回值,且被const修饰的东西,都受到强制保护,可以预防其它代码无意识的进行修改,从而提高了程序的健壮性
2:使编译器保护那些不希望被修改的参数,防止无意代码的修改
3:增强代码的可读性


1、修饰变量

此时变量只能使用不可修改,直接修改(编译报错)与修改地址(程序异常)都不行

int main() {const int a = 20 ;printf("a = %d\n",a);a = 200 ;//errprintf("a = %d\n",a);return 0;
}

2、修饰指针变量类型(常量指针)

const修饰指针变量的类型,不可修改指针指向的地址里的内容(编译报错),可以修改指针的指向

void test()
{int c = 100;const int *p = &c;printf("c = %d\n",c);//*p = 888;//不可修改指针指向的地址里的内容,编译报错//printf("c = %d\n",c);int d =999;p = &d;//可以修改指针的指向printf("*p = %d\n",*p);
}
int main(int argc, char *argv[])
{test();return 0;
}

3、修饰指针变量(指针常量)

可以修改指针指向地址的内容,但是不能修改指针的指向(编译报错)

void test()
{int c = 200;int  * const p = &c;//const修饰指针,即指针常量printf("*p = %d\n",*p);*p = 888;//修改指针指向地址里的内容printf("*p = %d\n",*p);int d =999;//p = &d;//不能修改指针的指向,编译报错//printf("*p = %d\n",*p);}
int main(int argc, char *argv[])
{test();return 0 ;
}

4、既修饰指针变量类型又修饰指针(常量指针常量)

不能修改指针指向地址的内容,不能修改指针指向

void test()
{int c = 200;const int * const p = &c;//即修饰指针变量类型又修饰指针变量printf("*p = %d\n",*p);//*p = 888;//不能修改指针指向地址里的内容,编译报错//printf("*p = %d\n",*p);//int d =999;//p = &d;//不能修改指针指向,编译报错//printf("*p = %d\n",*p);
}
int main(int argc, char *argv[])
{test();return 0;
}

5、修饰函数返回值

如果给以“指针传递”方式的函数返回值加 const 修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加 const 修饰的同类型指针。

const char * GetString(void);//如下语句将出现编译错误:
//char *str = GetString();//正确的用法是
const char *str = GetString();

6、修饰函数参数

​ 如果函数参数采用“指针传递”,那么加 const 修饰可以防止意外地改动该指针,起到保护作用。

​ 如果参数作为输出参数,不论它是什么数据类型,也不论它采用“指针传递”还是“引用传递”,都不能加 const 修饰,否则该参数将失去输出功能(因为有 const 修饰之后,不能改变他的值)。

​ 如果参数作为输入参数,可以防止数据被改变,起到保护作用,增加程序的健壮性。


7、修饰类中的变量与函数

<1>修饰成员变量

对成员变量的修饰与修饰普通变量差不多,都是设置为只读数据,但是类中的const变量
只能 通过构造函数初始化列表进行初始化 或者 直接值,

using namespace std;
class A
{
public:A(int a):m_a(a){}  //正常A(int a){       //报错m_a = a;}
private:const int m_a;   //成员变量 只读   const变量
};
int main()
{A A1(1);
}

<2>修饰成员函数

​首先,const修饰成员函数,保留了const修饰普通函数的用法;其次,增加了在成员函数的声明后边添加const的用法,表示成员函数内部无法修改成员变量

using namespace std;
class A {
public:int a = 1;/*第一个const:表示返回指针指向不可被更改第二个const:参照const修饰变量的用法第三个const:表示该成员函数不可修改成员变量*/void  show(const int* p) const ;  //修饰函数 cosnt函数 : 函数不能修改变量
};void A::show(const int* p) const {a = 2;//报错,被第三个const限制*p = 2;//报错,被第二个const限制cout<<"a="<<a<<endl;cout<<"*p="<<*p<<endl;
}int main(){A a;int c = 2;const int *b = &c;b = a.show(b);*b = &c;//报错,被第一个const限制
}

<3>修饰对象 类似于修饰变量

​ 在实例化对象的时候,添加const关键字,就是const对象,const对象只能访问类中的const成员变量和const成员函数

const  class  object(params);
const class *p = new class(params);  //两种用法等价

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

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

相关文章

线性代数的学习和整理7:各种特殊矩阵(草稿-----未完成)

目录 1 单位矩阵 为什么单位矩阵I是 [1,0;0,1]T 而不是[1,1;1,1]T 2 旋转矩阵 3 伸缩矩阵 放大缩小倍数矩阵 4 镜像矩阵 5 剪切矩阵 1 矩阵 1.1 1维的矩阵 行向量列向量 1.2 2维的矩阵 一般2维表都可以看作矩阵。矩阵的每个维度可以是1个数字&#xff0c;也可以是多个…

Appium-移动端自动测试框架,如何入门?

Appium是一个开源跨平台移动应用自动化测试框架。 既然只是想学习下Appium如何入门&#xff0c;那么我们就直奔主题。文章结构如下&#xff1a; 1、为什么要使用Appium&#xff1f; 2、如何搭建Appium工具环境?(超详细&#xff09; 3、通过demo演示Appium的使用 4、Appium如何…

通讯录的实现

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大一&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 望小伙伴们点赞&#x1f44d;收藏✨加关注哟&#x1f495;&#x1…

【Java 排序】冒泡排序(升降序,Int类型,Double类型,多数组排序)(111)

思路&#xff1a; 用二重循环实现&#xff0c;外循环变量设为i&#xff0c;内循环变量设为j。假如有n个数需要进行排序&#xff0c;则外循环重复n-1次&#xff0c;内循环依次重复n-1&#xff0c;n-2&#xff0c;…&#xff0c;1次。每次进行比较的两个元素都是与内循环j有关的&…

深入理解分布式架构,构建高效可靠系统的关键

深入探讨分布式架构的核心概念、优势、挑战以及构建过程中的关键考虑因素。 引言什么是分布式架构&#xff1f;分布式架构的重要性 分布式系统的核心概念节点和通信数据分区与复制一致性与一致性模型负载均衡与容错性 常见的分布式架构模式客户端-服务器架构微服务架构事件驱动…

[国产MCU]-W801开发实例-GPIO输入与中断

GPIO输入与中断 文章目录 GPIO输入与中断1、硬件准备2、软件准备3、驱动实现4、驱动测试W801的GPIO支持软件配置中断,中断触发方式包含:上升沿触发、下降沿触发、高电平触发、低电平触发。本文在前面[ 国产MCU]-W801开发实例-按键与GPIO输入的基础上实现GPIO中断配置。 1、硬…

Android瀑布流

以下是一个简单的示例代码&#xff0c;演示如何在Android Studio中解析指定网页的图片URL&#xff0c;并展示在错乱瀑布流布局中&#xff1a; 1. 添加网络权限&#xff1a;在项目的AndroidManifest.xml文件中添加以下权限&#xff1a; <uses-permission android:name"…

Linux定时任务crontab

常用命令 crontab -e 进入定时脚本&#xff0c;编辑后保存即立即生效 crontab -l 查看用户定时脚本 tail -f /var/log/cron 查看执行日志 service crond status 查看定时器运行状态 service crond restart 重启定时器 定时任务不执行原因 定时任务设置的格式正确&#xff0c;手…

分布式 | 如何搭建 DBLE 的 JVM 指标监控系统

本篇文章采用 Docker 方式搭建 Grafana Prometheus 实现对 DBLE 的 JVM 相关指标的监控系统。 作者&#xff1a;文韵涵 爱可生 DBLE 团队开发成员&#xff0c;主要负责 DBLE 需求开发&#xff0c;故障排查和社区问题解答。 本文来源&#xff1a;原创投稿 爱可生开源社区出品&a…

亚马逊点击广告对于卖家有什么好处

亚马逊点击广告对卖家来说有许多好处&#xff0c;它们可以帮助卖家增加产品曝光、提高销售量&#xff0c;并改善他们在亚马逊平台上的竞争地位。以下是一些卖家可能从亚马逊点击广告中获益的好处&#xff1a; 1、增加产品曝光度&#xff1a;通过在关键搜索结果页面上投放广告&…

更新Ubuntu18.04上的CUDA和GCC

问题&#xff1a; 有一台服务器的GPU是1080&#xff0c;有八张卡&#xff0c;已经好久没有人用了。cuda版本是10.1,我现在拿来复现一些论文的模型&#xff0c;经常遇到版本依赖问题&#xff0c;报错Driver is too old。所以要更新一下驱动。遇到的主要问题是gcc版本也太低了&am…

MySQL8.0.26-Linux版安装

MySQL8.0.26-Linux版安装 1. 准备一台Linux服务器 云服务器或者虚拟机都可以; Linux的版本为 CentOS7; 2. 下载Linux版MySQL安装包 MySQL :: Download MySQL Community Server (Archived Versions) 3. 上传MySQL安装包 4. 创建目录,并解压 mkdir mysql ​ tar -xvf mysql-8…

Flink 数据集成服务在小红书的降本增效实践

摘要&#xff1a;本文整理自实时引擎研发工程师袁奎&#xff0c;在 Flink Forward Asia 2022 数据集成专场的分享。本篇内容主要分为四个部分&#xff1a; 小红书实时服务降本增效背景Flink 与在离线混部实践实践过程中遇到的问题及解决方案未来展望 点击查看原文视频 & 演…

Spring Clould 负载均衡 - Ribbon

视频地址&#xff1a;微服务&#xff08;SpringCloudRabbitMQDockerRedis搜索分布式&#xff09; Ribbon-负载均衡原理&#xff08;P14&#xff09; 具体实现时通过LoaBalanced注解实现&#xff0c;表示RestTemplate要被Ribbon拦截处理 orderservice调用user时候&#xff0c…

​亚商投资顾问 早餐FM/0817创新发展机器人产业措施

01/亚商投资顾问 早间导读 总理&#xff1a;要着力扩大国内需求&#xff0c;继续拓展扩消费、促投资政策空间&#xff0c;提振大宗消费新华社&#xff1a;抹黑打压改变不了中国市场吸引力北京市印发《促进机器人产业创新发展若干措施》 02/亚商投资顾问 新闻早餐 // 热点聚焦…

FPGA原理与结构——RAM IP核的使用与测试

目录 一、前言 二、RAM IP核定制 1、RAM IP核 step1 打开vivado工程&#xff0c;点击左侧栏中的IP Catalog step2 在搜索栏搜索RAM&#xff0c;找到Block Memory Generator IP核&#xff1a; 2、IP核定制 step3 Baisc界面定制 step4 端口定制 step5 Other Options st…

18 眼前一亮:带你玩转GUI自动化的测试报告

开源GUI测试框架的测试报告实现思路 需要自己去实现截图以及高亮显示操作元素的功能。实现的思路通常是&#xff1a; 利用 Selenium WebDriver 的 screenshot 函数在一些特定的时机&#xff08;比如&#xff0c;页面发生跳转时&#xff0c;在页面上操作某个控件时&#xff0c;…

Docker分布式仓库

Harbor 是一个用于存储和分发 Docker 镜像的企业级 Registry 服务器&#xff0c;由 vmware 开源&#xff0c;其通过添加一些企业必需的功能特性&#xff0c;例如安全、标识和管理等&#xff0c;扩展了开源 Docker Distribution。作为一个企业级私有 Registry 服务器&#xff0c…

八种架构演进

日升时奋斗&#xff0c;日落时自省 目录 1、单机架构 2、应用数据分离架构 3、应用服务集群架构 4、读写分离/主从分离架构 5、冷热分离架构 6、垂直分库架构 7、微服务架构 8、容器编排架构 9、小结 1、单机架构 特征&#xff1a;应用服务和数据库服务器公用一台服务…

【vim 学习系列文章 5 - cscope 过滤掉某些目录】

文章目录 cscope 过滤目录介绍 cscope 过滤目录介绍 第一步创建自己的cscope脚本~/.local/bin/cscope.sh&#xff0c;如下&#xff1a; function my_cscope() {CODE_PATHpwdecho "$CODE_PATH"echo "start cscope...."if [ ! -f "$CODE_PATH/cscope.…