C++语法基础(一)

news2024/11/23 5:09:27

第一个C++程序

1. <iostream>(C++)

<iostream> 是 C++ 标准库中的头文件,用于处理输入输出操作。它提供了基于流(stream)的输入输出机制。

特点:
  • 面向对象:C++ 中的输入输出操作是基于流的,这种机制是面向对象的。流可以看作是字节序列的抽象,输入流从数据源(如键盘或文件)读取数据,输出流将数据写入目标(如屏幕或文件)。
  • 常用的流对象
    • std::cin:标准输入流,通常与键盘关联,用于从用户输入读取数据。
    • std::cout:标准输出流,通常与显示器关联,用于输出数据到屏幕。
    • std::cerr:标准错误流,通常与显示器关联,用于输出错误信息。
    • std::clog:标准日志流,用于输出日志信息。

2. <stdio.h>(C)

<stdio.h> 是 C 标准库中的头文件,用于处理输入输出操作。它提供了一些用于文件操作和标准输入输出的函数。

特点:
  • 基于函数的输入输出:C 语言中的输入输出操作是基于函数的。常见的输入输出函数包括 printfscanffprintffscanffgetsfputs 等。
  • 低级别:与 C++ 的面向对象的流相比,C 的输入输出更为低级,操作更加直接。
//#include<stdio.h>
#include<iostream>

int main(){
   // printf("hello world\n");
    std::cout << "hello world" << std::endl;
    return 0;
}

  我们可以先暂时理解为endl \n 一样,功能就是输出时换行,它们有一些重要的区别,endl 是 C++ 标准库中的一个操控符(manipulator),它不仅用于在输出流中插入一个换行符,还会刷新输出缓冲区(flush the output buffer)。这意味着,endl 会强制将缓冲区中的内容立即输出到目标设备(如屏幕),而不仅仅是插入一个换行符。对于作用限定符::我们可以先简单地理解为什么中的什么。

命名空间

        命名空间(namespace) 是 C++ 中用于组织代码的一种机制,它允许将代码分组到不同的命名空间中,以避免名称冲突,特别是在大型项目或使用多个库时。命名空间为变量、函数、类等标识符提供了一个作用域,可以防止不同命名空间中的标识符相互干扰。

代码演示

#include<iostream>
namespace ICBC{
    int g_money = 0;
    void pay(int money){
        g_money -= money;
    }
    void save(int money){
        g_money += money;
    }
}
namespace CCB{
    int g_money = 0;
    void pay(int money){
        g_money -= money;
    }
    void save(int money){
        g_money += money;
    }
}

int main(){
    ICBC::pay(1000);
    ICBC::save(3000);
    CCB::save(10000);
    CCB::pay(2000);
    std::cout << "工行卡的余额:" << ICBC::g_money << std::endl;
    std::cout << "建行卡的余额:" << CCB::g_money << std::endl;
}

        在使用命名空间后,相同名字的变量和函数并没有发生冲突

名字空间声明

代码演示

//名字空间声明
#include<iostream>
using namespace std;
namespace ns{
    int v_tomato = 10;
}
int main(){
    int v_tomato = 30;
    using ns::v_tomato; //从这行代码开始,ns中的内容引入当前作用域(相当于定义)
    //上面的定义会造成重定义报错
    v_tomato = 20;  
    cout << "ns::v_tomato = " << ns::v_tomato << endl;
    return 0;
}

        因为所有标准库提供的 类型、对象和函数都位于std名字空间 ,所以我们在使用using namespace std;后,就可以对输出代码的写法进行简化,省略std::

 代码分析 

         编译器在编译每一个函数时都会构造两张表,在编译这个函数(main函数)结束后销毁。在函数体内定义的变量会放进定义表,对于函数体外定义的对本函数可见的变量会放进可见表。对于本例,使用名字空间声明也相当于在这个函数体内定义了这个变量,又因为函数体内先前已经定义了这个变量(int v_tomato=30),此时的名字空间声明会造成重定义,这是编译器绝对不允许的,因此会报错。当在函数内使用某个标识符时,如果存在同名,编译器需要确定你使用的是哪一个标识符,因此他会拿着这个名字先在定义表中查看,如果定义表中找不到,才会到可见表中找。

 

名字空间指令(using namespace [...])

        名字空间指令是指使用 using namespace 语句将整个命名空间引入当前作用域。这意味着命名空间中的所有标识符都可以直接使用,而不必再通过命名空间限定符来引用。这种方式在简化代码的同时也可能带来名称冲突的风险,尤其是在大型项目中。 

代码演示

//名字空间指令
#include<iostream>
using namespace std;
namespace ns{
    int v_tomato = 10;
}
int main(){

    using namespace ns; //从这行代码开始,ns中的内容在当前作用域中可见
    //ns::v_tomato = 20;
    v_tomato = 20;
    //std::cout << ns::v_tomato << std::endl;
    cout << "ns::v_tomato = " << ns::v_tomato << endl;
    return 0;
}

在上面的代码中,using namespace ns; 是一个名字空间指令,它将 ns1命名空间中的所有标识符引入到 main 函数的作用域中,因此你可以直接使用 v_tomato 而不需要在前面加上 ns::。 

 代码分析(不同于上个代码)

         对于本例,代码的输出结果依然是10,我们来分析一下。main函数内的int v_tomato = 10,这是一个放在定义表的局部变量,而对于ns命名空间的int v_tomato = 10是放在可见表中的。当出现v_tomato = 20这个变量,编译器需要确定究竟是这两个同名变量中的哪一个,编译器会先在定义表中寻找,此时他找到了就不会查看可见表,因此v_tomato = 20修改的是main函数内定义的局部变量而不是ns命名空间的同名变量。这也就是最后我们的输出结果依然是v_tomato = 10的原因,因为它实际上并没有修改我们ns命名空间中的这个变量。

 名字空间指令和名字空间声明的差别

        使用名字空间指令会让所指定命名空间的内容在当前作用域中可见,其中定义的变量会被放入可见表中,而使用名字空间声明会让所指定命名空间中的内容引入当前作用域(相当于定义),其中定义的变量放入定义表中

代码演示

//名字空间指令 和 名字空间声明 的差别
#include<iostream>
using namespace std;
namespace ns1{
    int g_money = 10;
    int g_other = 10;
}
namespace ns2{
    int g_money = 10;
    int g_other = 10;
}
int main(){
    using namespace ns1;//ns1中的所有内容都出现在可见表中
    using ns2::g_other;//只有ns2::g_other出现在定义表中
    
    g_money = 100;//修改的是ns1中的g_money
    cout << "ns1::g_money = " <<ns1::g_money <<
        ", ns2::g_money =" << ns2::g_money <<endl;
    g_other = 100;//修改的是ns2中的g_other
    cout << "ns1::g_other =" << ns1::g_other <<
        ", ns2::g_other =" << ns2::g_other <<endl;
        return 0;
}

命名空间的嵌套

        在C++中,嵌套命名空间的同名变量不冲突,因为每个变量在其所属的命名空间中都有唯一的作用域。变量的名称相同,但由于它们位于不同的命名空间中,编译器可以通过命名空间限定符(如ns1::ns2::g_money)来区分它们。因此,它们不会冲突。

//命名空间的嵌套
#include<iostream>
using namespace std;

namespace ns1{
    int g_money = 10;
    namespace ns2{
        int g_money = 20;
        namespace ns3{
            int g_money = 30;
            namespace ns4{
                int g_money = 40;
            }
        }
    }
}

int main(){
    //名字空间别名可以简化书写
    namespace ns_forth = ns1::ns2::ns3::ns4;
    //cout << ns1::ns2::ns3::ns4::g_money << endl;
    cout << ns_forth::g_money << endl;
}

扩展

        我们说使用名字空间声明引入的变量相当于定义在main函数中的变量,那他们有什么区别?

在C++中,namespace中的变量(如ns::v_tomato)通常具有进程级生命周期

1. 进程级生命周期的定义

  • 进程级生命周期的变量从程序开始执行(通常是在程序的初始化阶段)到程序结束时一直存在。
  • 这些变量通常分配在全局/静态数据区中,生命周期贯穿整个程序的运行过程。

2. namespace中的变量的生命周期

  • namespace ns { int v_tomato = 10; }
    • 这里的v_tomato是在命名空间ns中定义的全局变量。
    • 虽然它被封装在namespace中,但它的本质仍是一个全局变量。
特点:
  • 存储位置v_tomato会存储在全局/静态数据区中,而不是栈或堆中。这意味着它在程序的整个生命周期内都存在。
  • 生命周期:从程序启动时开始(即在main()函数执行之前),直到程序终止时结束。因此,它具有进程级的生命周期。
  • 作用范围:虽然v_tomato的作用范围被限制在命名空间ns中,但它仍然是一个全局变量。这意味着在程序的任何地方,只要通过ns::v_tomato访问,它都可以被引用和修改。

3.示例分析 

#include <iostream>

namespace ns {
    int v_tomato = 10; // 进程级生命周期的变量
}

int main() {
    std::cout << "v_tomato = " << ns::v_tomato << std::endl; // 输出 10
    ns::v_tomato = 20;
    std::cout << "v_tomato = " << ns::v_tomato << std::endl; // 输出 20
    return 0;
}

在这个示例中:

  • v_tomato 在程序开始时被初始化为10,并且在整个程序的生命周期中都存在。
  • 你可以在main()函数中(或程序的其他地方)访问和修改它的值。
  • 当程序结束时,v_tomato才会被销毁。

4. 总结

  • namespace中的变量v_tomato 是具有进程级生命周期的全局变量。
  • 它从程序启动时初始化,并在程序结束时销毁。
  • 尽管被封装在namespace中,它的生命周期和其他全局变量一样,不受namespace本身的影响。

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

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

相关文章

力扣面试经典算法150题:加油站

加油站 今天的题目是力扣面试经典150题中的数组的中等难度题&#xff1a;加油站。 题目链接&#xff1a;https://leetcode.cn/problems/gas-station/description/?envTypestudy-plan-v2&envIdtop-interview-150 问题描述 在一条环路上有 n 个加油站&#xff0c;其中第 i…

pySCENIC报错、解决和完整流程(IOS系统)

该文首发于生信技能树&#xff0c;推文链接&#xff1a;https://mp.weixin.qq.com/s/W23Reg6Hi4XWxpMvfctP8g 明白了基因调控网络的基础知识之后&#xff0c;就可以尝试实际操作一下SCENIC分析。 基因调控网络的基础知识可见推文&#xff1a;https://mp.weixin.qq.com/s/sL_8…

海康二次开发学习笔记4-参数模块配置

参数模块配置 参数配置控件 工具箱中提供了两个参数配置控件. VmParamsConfigControl是不带渲染的参数配置控件.VmParamsConfigWithRenderControl是带渲染的参数配置控件. 1. VmParamsConfigWithRenderControl 配置模块数据源 private void button3_Click(object sender, …

90%的设计师都不知道的设计神器,教你一招快速搞定中秋节创意海报设计!

设计师们&#xff0c;这是不是你&#xff1a;素材多到眼花缭乱&#xff0c;想用的时候总是找不到&#xff1f;海报设计千篇一律&#xff0c;完美没灵感&#xff1f;别担心&#xff0c;今天就来聊聊如何用千鹿设计助手&#xff0c;快速制作一张创意满满的中秋海报&#xff01; …

若依后端 MyBatis改为MyBatis-Plus

引用 1.引入MyBatis-Plus依赖 在总目录的pom.xml&#xff0c;导入依赖 <mybatis-plus.version>3.4.3</mybatis-plus.version> <!-- mybatis-plus 增强CRUD --> <dependency> <groupId>com.baomidou</groupId> <artifactId>…

关机软件项目规划

一、概述 1.1 编写目的 此项目开发规划书的编写主要是为《UPS SNMP卡网络监控系统》中配套使用的关机软件做主要的规划和整合&#xff0c;在开发过程中起到引导作用&#xff0c;以及给使用者提供简要的说明。 1.2 项目背景 关机软件是UPS网络监控适配器项目监控层的组成部分…

16岁激活交学费银行卡需要本人实名电话卡,线下营业厅不给办,怎么办?

16岁激活交学费银行卡需要本人实名电话卡&#xff0c;线下营业厅不给办&#xff0c;怎么办&#xff1f; 话卡办理规定&#xff1a; 根据《民法典》和《电话用户真实身份信息登记规定》的相关要求&#xff0c;未满16周岁的用户通常需要在监护人的陪同下办理电话卡&#xff0c;并…

IO多路复用几种函数

1. select() 函数原型 int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);参数说明 nfds&#xff1a;指定文件描述符的范围。这个值应设置为所有文件描述符中最大值加一。例如&#xff0c;如果监视的文件描述符是 0 到 …

斯坦福大学cs231n (图像分类)

1.介绍 当作图像分类时&#xff0c;分类系统接收一些分类图像&#xff0c;比如猫咪。并且系统清楚了一些已经确定了分类或者标签的集合。那么&#xff0c;计算机的工作就是根据图片&#xff0c;给他分配一些固定的分类或者标签。 对于一个计算机来说&#xff0c;这是一个非常…

【CVPR‘24】DeCoTR:使用 2D 和 3D 注意力增强深度补全

DeCoTR: Enhancing Depth Completion with 2D and 3D Attentions DeCoTR: Enhancing Depth Completion with 2D and 3D Attentions 中文解析摘要介绍方法方法3.1 问题设置3.2 使用高效的 2D 注意力增强基线3.3 3D中的特征交叉注意力点云归一化位置嵌入3.4 捕捉 3D 中的全局上下…

软件测试常见面试题汇总(2024版)

一、常见的面试题汇总 1、你做了几年的测试、自动化测试&#xff0c;说一下 selenium 的原理是什么&#xff1f; 我做了五年的测试&#xff0c;1年的自动化测试&#xff1b; selenium 它是用 http 协议来连接 webdriver &#xff0c;客户端可以使用 Java 或者 Python 各种编…

MySQL的InnoDB、MyISAM的参数及常见错误码

1&#xff1a;参数 参数&#xff0c;也被称之为MySQL的系统变量&#xff0c;这些变量是影响MySQL运行的关键&#xff0c;对每个参数做出不同调整&#xff0c;都有可能直接影响到线上数据库的性能&#xff0c;具体的完整系统参数可参考《MySQL官网文档-系统变量》&#xff0c;官…

图表检测检测系统源码分享 # [一条龙教学YOLOV8标注好的数据集一键训练_70+全套改进创新点发刊_Web前端展示]

图表检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vision …

通过写文件方式写入 Hive 数据

通过写文件方式写入 Hive 数据 Hive最简单的写入数据方式就是通过Hive Jdbc写入Hive数据&#xff0c;但这并不是写入Hive最高效的方法。 Hive通过读取相关Hdfs的文件来获取数据信息&#xff0c;而通过直接写入Hdfs文件数据达到写入Hive数据的效果&#xff0c;这是目前最高效的…

《python语言程序设计》2018版第8章第2题检测子串,你可以用str类中的find方法检测一个字符串

我先用in来做一次 def find_text(text_input1, text_input2):a str(text_input1)b str(text_input2)if b in a:print(f"The {b} is in {a} ")else:print(f"The {b} is not in {a} ")text_n1 "Welcome to shenyang" text_n2 "to"fi…

zdppy_cache缓存框架升级,支持用户级别的缓存隔离,支持超级管理员管理普通用户的缓存

启动服务 import zdppy_api as api import zdppy_cachekey1 "admin" key2 "admin"app api.Api(routes[*zdppy_cache.zdppy_api.cache(key1, key2, api) ])if __name__ __main__:import zdppy_uvicornzdppy_uvicorn.run(app, host"0.0.0.0",…

JVM-类加载过程

类加载过程是 Java 虚拟机 (JVM) 将 Java 代码编译后的字节码文件加载到内存中&#xff0c;并进行解析和验证&#xff0c;最终使程序能够运行的关键步骤。 类加载过程&#xff1a;加载->连接->初始化。连接过程又可分为三步&#xff1a;验证->准备->解析。 1. 加载…

Vitis AI 基本认知(Tiny-VGG 标签获取+预测后处理)

目录 1. 简介 2. 解析 2.1 获取标签 2.1.1 载入数据集 2.1.2 标签-Index 2.1.3 保存和读取类别标签 2.2 读取单个图片 2.3 载入模型并推理 2.3.1 tiny-vgg 模型结构 2.3.2 运行推理 2.4 置信度柱状图 2.5 预测标签 3. 完整代码 4. 总结 1. 简介 本博文在《Vitis …

Python酷库之旅-第三方库Pandas(105)

目录 一、用法精讲 456、pandas.DataFrame.rdiv方法 456-1、语法 456-2、参数 456-3、功能 456-4、返回值 456-5、说明 456-6、用法 456-6-1、数据准备 456-6-2、代码示例 456-6-3、结果输出 457、pandas.DataFrame.rtruediv方法 457-1、语法 457-2、参数 457-3…

云计算实训38——docker网络、跨主机容器之间的通讯

一、docker⽹络 1.桥接--bridge 所有容器连接到桥就可以使⽤外⽹&#xff0c;使⽤nat让容器可以访问外⽹ 使⽤ ip a s指令查看桥&#xff0c;所有容器连接到此桥&#xff0c;ip地址都是 172.17.0.0/16 ⽹段&#xff0c;桥是启动docker服务后出现&#xff0c;在centos使⽤ br…