【C\C++】花括号作用域的区别和声明变量的区别

news/2024/4/20 22:11:00/文章来源:https://blog.csdn.net/ZSZ_shsf/article/details/130337121

虽然在 C 和 C++ 中都使用花括号 { } 来表示作用域,但它们在作用域的范围、声明变量、初始化等方面有一些不同。

作用域的范围

在 C++ 中,所谓的块作用域(block scope)是指被一对花括号 { } 包围的一段代码。在这种情况下,块作用域内定义的变量只有在该块内才能访问,超出该块则不能访问。例如:

#include <iostream>int main() {int a = 10;{int b = 20;std::cout << "a + b = " << a + b << std::endl;}//std::cout << "b = " << b << std::endl; // 编译错误,b超出了其作用域return 0;
}

在上面的代码中,{ } 中的代码块是一个新的作用域,在其中定义了变量 b,该变量只在该作用域内有效,外部作用域无法访问该变量。如果将 std::cout << "b = " << b << std::endl; 的注释去掉,则编译时会报错,因为变量 b 已经超出了其作用域。

在 C 语言中,作用域的范围稍有不同。在 C 中,所谓的块作用域只在紧随其后的代码块内部有效。例如:

#include <stdio.h>int main() {int a = 10;{int b = 20;printf("a + b = %d\n", a + b);}//printf("b = %d\n", b); // 编译错误,b超出了其作用域return 0;
}

和 C++ 的示例代码类似,C 中的代码也使用了花括号 { } 表示作用域。但是,与 C++ 不同的是,C 语言中的变量在代码块结束后就会被销毁,超出该作用域后也无法访问该变量,即使是在后面的代码块中也不行。C 语言中的变量具有块作用域 (block scope),也就是说,变量只在其定义的代码块内以及子代码块内部有效。当代码块结束后,该变量就会被销毁,并且在超出该作用域后无法再访问该变量。这与 C++ 中的变量作用域规则是相同的。但是,C++ 中的对象还可以通过构造函数和析构函数实现对象生命周期的管理。

假设我们有一个类 MyString,用于表示一个字符串类型,并且需要在对象创建和销毁时执行一些操作,例如分配和释放内存等。

在 C 语言中,可以使用字符数组来表示一个字符串,如下所示:

#include <stdio.h>int main() {char str[] = "Hello, world!"; // 定义一个字符数组 str,其中包含字符串“Hello, world!”printf("%s\n", str); // 输出字符串 str// 在这里,字符数组 str 超出了作用域,将被自动销毁,内存也会被释放return 0;
}

在该示例中,我们使用字符数组 str 来保存字符串 “Hello, world!”。由于字符数组是一种普通变量,其作用域遵循块作用域规则,当 main() 函数执行完毕后,该字符数组超出作用域,自动被销毁,内存也会被释放。

在 C++ 语言中,我们使用类 MyString 来表示一个字符串,如下所示:

#include <iostream>
#include <cstring>class MyString {
public:MyString(const char* str) { // 构造函数,用于初始化字符串m_str = new char[strlen(str) + 1];strcpy(m_str, str);}~MyString() { // 析构函数,用于清理字符串分配的内存delete[] m_str;}void show() { // 显示字符串std::cout << m_str << std::endl;}private:char* m_str; // 字符串指针,指向分配的内存
};int main() {MyString mystr("Hello, world!"); // 定义一个 MyString 类对象 mystr,初始化为“Hello, world!”mystr.show(); // 输出字符串 mystr// 在这里,MyString 类对象 mystr 超出了作用域,将自动调用析构函数,释放分配的内存return 0;
}

在该示例中,我们定义了一个类 MyString,并在其中实现了构造函数和析构函数。在 main() 函数中,我们创建了一个 MyString 类型的对象 mystr,并在构造函数中初始化其内部的字符串成员变量,使用析构函数在对象销毁时释放内存。与 C 语言相比,C++ 中的对象是一种特殊的变量类型,具有更加灵活的管理生命周期的能力。C++ 对象的生命周期管理不仅仅是局限于作用域范围,而是包含了更加细致的构造和析构过程,从而保证对象的生命周期管理更加精细和安全。

在 C++ 中,对象的生命周期管理不像 C 语言中的变量那么简单,包含了更加细致的构造、初始化、赋值、拷贝、销毁等一系列过程,这些过程都是由编译器自动生成的。下面就分别对这些过程进行讲解:

构造(Construct):在创建一个对象时调用构造函数,对对象进行初始化。

初始化(Initialize):构造函数负责对对象成员变量进行初始化操作。如果未在构造函数中显式指定初始化值,将使用默认值进行初始化。

赋值(Assign):当使用赋值运算符给对象赋值时,调用重载的赋值运算符函数来完成赋值操作。

拷贝(Copy):当对象被复制到另一个对象中时,调用重载的拷贝构造函数,将原对象的内容复制到新对象中。

移动(Move):当对象被转移或移动到另一个对象中时,调用重载的移动构造函数或移动赋值运算符函数,将原对象的内容转移或移动到新对象中。

销毁(Destruct):当对象生命周期结束时,调用析构函数对对象进行清理和销毁操作。

这些过程的存在使得 C++ 对象的生命周期管理更加精细和安全,避免了由于内存泄漏、对象拷贝不正确等问题造成的程序故障。因此,与 C 语言相比,C++ 对象在生命周期管理方面具有更高的安全性和可靠性。

声明变量

首先是变量类型限定符(Type Qualifier)方面:C 中支持 const、volatile 和 restrict 三个类型限定符,而 C++ 中还额外支持了 mutable。其中 const 表示变量的值不可改变,volatile 表示变量的值可能发生改变,restrict 表示指针变量指向的内存区域没有被其他指针所指向,而 mutable 则用于成员变量,表示该变量即使在 const 成员函数中也可以被修改。

其次是变量作用域(Scope)方面:在 C 中,变量的作用域可以是文件级别(全局变量)、函数级别(局部变量)或块级别(在 if、for、while 等语句中定义的变量),而在 C++ 中还加入了名字空间(Namespace)的概念,使得变量的作用域更加灵活和清晰。

再者是变量声明方式方面:在 C 中,变量需要在使用之前进行声明,可以通过在局部作用域中使用自动变量或者在文件作用域中使用静态变量来完成声明。而在 C++ 中,则支持更加灵活的类成员变量和静态成员变量等多种声明方式。

最后,是变量的默认初始化方面:在 C 语言中,局部变量是不会自动进行初始化操作的,其值是不确定的,而全局变量和静态变量则默认被初始化为 0。而在 C++ 中,类成员变量、静态变量以及全局变量都可以使用构造函数来完成初始化操作,避免了未初始化的问题。

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

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

相关文章

【计算机网络】为什么 TCP 每次建立连接时,初始化序列号都要不一样呢?

【计算机网络】为什么 TCP 每次建立连接时&#xff0c;初始化序列号都要不一样呢&#xff1f; 为什么 TCP 每次建立连接时&#xff0c;初始化序列号都要不一样呢&#xff1f; 主要原因是为了防止历史报文被下一个相同四元组的连接接收。 TCP 四次挥手中的 TIME_WAIT 状态不是会…

机械键盘、口袋打印机,万元奖金等你拿!「万象格新」AI绘画X海报设计大赛即将开启...

号外&#xff01;「万象格新」大赛开启 如果阳光暖到你心里&#xff0c;那一定是一格在想你~ 春夏交替&#xff0c;万物焕发生机&#xff0c;明媚色彩娱情惬意 在这样一个美好的时节 如果你&#xff1a; 心中荡漾着色彩斑斓的 AI 绘画创意 想要 show 出独到的审美与非凡设计能力…

吴恩达团队AI诊断心律失常研究:准确率超人类医生

2019年&#xff0c;吴恩达团队在AI医疗领域实现了一项革命性的突破&#xff0c;他们成功地让AI诊断心律失常&#xff0c;其准确率高达83.7%&#xff0c;超过了人类心脏病医生的78.0%。这项研究成果已经发表在了知名期刊Nature Medicine上。 一、如何让AI学会诊断心律失常&…

闲谈【Stable-Diffusion WEBUI】的插件:美不美?交给AI打分

文章目录 &#xff08;零&#xff09;前言&#xff08;一&#xff09;咖啡店艺术评价&#xff08;Cafe Aesthetic&#xff09; &#xff08;零&#xff09;前言 本篇主要提到了WEBUI的Cafe Aesthetic插件&#xff0c;这是一个相对独立的插件&#xff0c;单独标签页&#xff0c;…

Python小姿势 - Python基础知识

Python基础知识 Python是一种解释型、面向对象、动态数据类型的高级程序设计语言。 Python的创始人为吉多范罗苏姆&#xff08;Guido van Rossum&#xff09;&#xff0c;于1989年底发布第一个公开发行版本——0.9.0。 自2004年以来&#xff0c;Python已经成为顶级开源项目&…

希尔排序的实现

希尔排序是插入排序的一种升级&#xff0c;其基本思想是&#xff1a; 先选定一个整数&#xff0c;把待排序文件中所有记录分成个组&#xff0c;所有距离为的记录分在同一组内&#xff0c;并对每 一组内的记录进行排序。然后&#xff0c;取&#xff0c;重复上述分组和排序的工 作…

使用Linux运维常识

一.基础操作 1.终端常用快捷键 快捷键描述ctrl键盘左键向左跳一个单词ctrl键盘右键向右跳一个单词Ctrl c停止当前正在运行的命令。Ctrl z将当前正在运行的命令放入后台并暂停它的进程。Ctrl d关闭当前终端会话。Ctrl l清屏&#xff0c;也可以用clear命令实现Tab自动补全当…

Asp.NET CORE实验室信息管理系统源码,支持IIS独立部署,Docker部署

技术架构&#xff1a;Asp.NET CORE 3.1 MVC SQLserver Redis等 基于B/S架构的实验室管理系统源码&#xff0c;整个系统的运行基于WEB层面&#xff0c;只需要在对应的工作台安装一个浏览器软件有外网即可访问。全套系统采用云部署模式&#xff0c;部署一套可支持多家医院检验…

自定义RecyclerView.LayoutManager实现类实现卡片层叠布局的列表效果

一.前言 先看效果&#xff08;大佬们请忽略水印&#xff09;&#xff1a; 卡片层叠列表的实现效果已经发布成插件&#xff0c;集成地址&#xff1a;implementation ‘com.github.MrFishC:YcrCardLayoutHepler:v1.1’&#xff1b; 先讲解如何快速实现&#xff0c;然后再来讲解…

托福高频真词List05 // 附托福TPO阅读真题

目录 4月23日单词 生词 熟词 4月24日真题 4月23日单词 生词 sparsethinly distributedadj 稀疏的sparselythinlyadv 稀疏地congestion / kənˈdʒestʃən / overcrowdingn 拥挤continuallyregularlyadv 持续的eradicateeliminatev 消除facilitatemake easiereasev 使..…

《面试1v1》java泛型

我是 javapub&#xff0c;一名 Markdown 程序员从&#x1f468;‍&#x1f4bb;&#xff0c;八股文种子选手。 面试官&#xff1a;小伙子,说实话,泛型这个机制一开始我也是一头雾水,搞不太明白它到底要解决什么问题。你能不能不那么书呆子,给我普普通通地讲一讲泛型? 候选人…

如何测试信号源或者发射机的回波损耗

信用源或者发射机的return loss测试过程 1.用网分线缆的第一步就是看线的抖动情况&#xff0c;后面还是要多注意 经过一系列排查后&#xff0c;选用两个抖动比较小的线缆&#xff0c;然后开始测试另外一台仪器。 2.检查测试仪器的输出功率&#xff0c;见图1 打开信号源或者发射…

可以一学的代码优化小技巧:减少if-else冗余

前言 if-else 语句对于程序员来说&#xff0c;是非常非常熟悉的一个判断语句&#xff0c;我们在日常开发和学习中都经常看见它&#xff0c;if-else语句主要用于需要做出选择的地方进行判断&#xff0c;这里就不再赘述if-else语法和特点了。 ​ 我们在写代码&#xff08;如图下…

PC1 - 搭建项目

先看路由&#xff0c;可以查看功能模块划分。熟悉什么看什么 router文件夹下routerConfig.tsx 配置路由&#xff0c;创建模块文件&#xff08;写好内容模块&#xff09;&#xff0c;lazy可懒加载导入。App.tsx配置一级路由&#xff0c;配置二级路由出口 { path:/, element: …

【记录】FFmpeg|超大视频本地有损压缩,500MB变5MB(支持 Windows、Linux、macOS)

参考&#xff1a; 如何将一分钟长的1080p视频压缩至5MB以内&#xff1f;-知乎-滔滔清风近期HEVC扩展备用安装方法-B站-悲剧天下 总共三个步骤&#xff0c;安装FFmpeg、运行指令、打开视频。 亲测 500MB 变 5MB。 1 安装FFmpeg 对于不需要看教程可以自行完成安装的同学们&…

7. 堆的简单学习

7. 堆 7.1 堆的定义 堆是计算机科学中一类特殊的数据结构的统称&#xff0c;堆通常可以被看做是一棵完全二叉树的数组实现。 堆的特性&#xff1a; 它是完全二叉树&#xff0c;除了树的最后一层结点不需要是满的&#xff0c;其它的每一层从左到右都是满的&#xff0c;如果最…

使用python实现自动点击功能

猜你感兴趣 使用Pyqt5玩转ChatGpt内网文件共享服务快速搭建私有pip镜像源python设计模式-创建型模式docker搭建私有git服务器&#xff0c;项目备份和迁移redis持久化方案 被测点击界面 新建counter.html添加下面代码并保存,使用编辑器或浏览器打开 <!DOCTYPE html> &l…

23.4.21总结

正则表达式 正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串&#xff0c;通常被用来检索、替换那些符合某个模式&#xff08;规则&#xff09;的文本。 正则表达式是一种对字符串操作的一种逻辑公式&#xff0c;就是用事先定义好的一些特定字符、及这些…

深度学习 - 42.特征交叉与 SetNET、Bilinear Interaction 与 FiBiNet

目录 一.引言 二.摘要 - ABSTRACT 三.介绍 - INTRODUCTION 四.相关工作 - RELATED WORK 1.因式分解机及其变体 - Factorization Machine and Its relevant variants 2. 基于深度学习的点击率模型 - Deep Learning based CTR Models 3.SENET Module 五.FiBiNet Model 1…

【C++】哈希的应用:位图和布隆过滤器

目录 1. 位图1.1 位图的概念1.2 位图的结构1.3 位图的实现 2. 布隆过滤器2.1 概念2.2 结构2.3 布隆过滤器的实现 1. 位图 1.1 位图的概念 &#x1f4ad;位图&#xff08;bitset&#xff09;是一种基于哈希思想设计的数据结构&#xff0c;其功能主要用于判断数据是否已存在。适…