C++学习笔记二

一、常量

1.用const关键字声明常量变量
  1. const常量变量在定义时必须进行初始化,并且不能通过赋值来改其值
const double gravity { 9.8 };  //首选在类型之前使用const
int const sidesInSquare { 4 }; // “east const”风格,可以,但不是首选

  1. const 变量可以从其他变量(包括非常量变量)初始化
#include <iostream>

int main()
{
    std::cout << "Enter your age: ";
    int age{};
    std::cin >> age;

    const int constAge { age }; // initialize const variable using non-const value

    age = 5;      // ok: age is non-const, so we can change its value
    constAge = 6; // error: constAge is const, so we cannot change its value

    return 0;
}
  1. 将函数参数设为常量可借助编译器的帮助来确保函数内部不会更改参数的值。然而,在现代 C++ 中,我们不会将值参数设为常量,因为我们通常不关心函数是否会更改参数的值(因为它只是一个副本,无论如何都会在函数结束时被销毁)。该const关键字还会给函数原型带来少量不必要的混乱。const按值传递时不要使用。
2. constexpr变量
  1. 编译时常量变量和运行时常量变量。只有编译时常量变量可用于常量表达式——运行时常量变量(和非常量变量)不能。由于编译时常量变量没有实际缺点,因此我们通常希望尽可能使用编译时常量
int a {5};//不是const
int b {a};//显然是运行时const(因为初始化器是非const)
const int c {5};//显然是编译时const(因为初始化器是常量表达式)

const int d {someVar};//不清楚这是运行时const还是编译时const
const int e{getValue()};//不清楚这是运行时const还是编译时const
  1. constexpr(“Constant expression”的缩写)变量始终是编译时常量。因此,必须使用常量表达式初始化constexpr变量,否则会导致编译错误。
#include <iostream>

int five()
{
    return 5;
}

int main()
{
    constexpr double gravity { 9.8 }; // ok: 9.8 is a constant expression
    constexpr int sum { 4 + 5 };      // ok: 4 + 5 is a constant expression
    constexpr int something { sum };  // ok: sum is a constant expression

    std::cout << "Enter your age: ";
    int age{};
    std::cin >> age;

    constexpr int myAge { age };      // compile error: age is not a constant expression
    constexpr int f { five() };       // compile error: return value of five() is not a constant expression

    return 0;
}
3. const 与 constexpr 对变量的含义
  1. 对于变量,“const”表示对象的值在初始化后不能更改。“Constexpr”表示对象必须具有编译时已知的值。
    constexpr 变量隐式为 const。Const 变量不隐式为 constexpr(带有常量表达式初始化器的 const 整型变量除外)。
  2. const
  • 定义:const 关键字用于声明一个变量为常量。一旦被初始化,其值不能被修改。
  • 作用域:const 可以用于修饰局部变量、全局变量、类成员变量和指针。
  • 编译时:const 变量的值在编译时不需要是已知的,它们可以在运行时初始化。
  1. constexpr
  • 定义:constexpr 关键字用于声明一个常量表达式,其值在编译时就可以确定。它用于更严格的编译时常量。
  • 作用域:constexpr 通常用于修饰变量和函数。
  • 编译时:constexpr 变量的值必须在编译时是已知的。
  • 函数:用 constexpr 修饰的函数意味着该函数可以在编译时求值,并且返回值也是一个常量表达式。
  1. const变量称为运行时常量,constexpr称为编译时常量。constexpr 关键字可以用于函数,而 const 不能。

二、条件运算符

  1. Conditional ?: c ? x : y If conditional c is true then evaluate x, otherwise evaluate y
  2. C++ 中唯一的三元运算符,因此有时也称为“三元运算符”。
  3. 由于 C++ 将大多数运算符的求值优先级置于条件运算符的求值之上,因此很容易使用条件运算符编写无法按预期求值的表达式。
#include <iostream>

int main()
{
    int x { 2 };
    int y { 1 };
    int z { 10 - x > y ? x : y };
    std::cout << z;

    return 0;
}
----------------------------------------------------------------------------
您可能期望它的计算结果为10 - (x > y ? x : y)(计算结果为8),但实际上它的计算结果为(10 - x) > y ? x : y(计算结果为2)。
  1. 第二和第三个操作数的类型必须匹配。编译器必须能够找到一种方法将第二个和第三个操作数中的一个或两个转换为匹配的类型。编译器使用的转换规则相当复杂,在某些情况下可能会产生令人惊讶的结果。

三、内联函数和变量

  1. 内联扩展是一个将函数调用替换为被调用函数定义中的代码的过程。这使我们能够避免这些调用的开销,同时保留代码的结果。
  2. 内联扩展最适合简单、短的函数(例如不超过几个语句),尤其是单个函数调用可以执行多次的情况(例如循环内的函数调用)。
  3. inline关键字,使用inline关键字声明的函数为内联函数
#include <iostream>

inline int min(int x, int y) // inline keyword means this function is an inline function
{
    return (x < y) ? x : y;
}

int main()
{
    std::cout << min(5, 6) << '\n';
    std::cout << min(3, 2) << '\n';
    return 0;
}
  1. C++17 引入了内联变量,即允许在多个文件中定义的变量。内联变量的工作方式与内联函数类似,并且具有相同的要求(编译器必须能够在使用该变量的任何地方看到相同的完整定义)。

四、std::string 简介

  1. std::string和std::string_view都可以用于定义字符串变量
#include <string> // allows use of std::string

int main()
{
    std::string name {}; // empty string

    return 0;
}
  1. 最巧妙的事情std::string之一就是存储不同长度的字符串,字符串的最后一个字符是’\0’。如果std::string没有足够的内存来存储字符串,它将使用一种称为动态内存分配的内存分配形式(在运行时)请求额外的内存。这种获取额外内存的能力是其std::string如此灵活的部分原因,但也相对较慢。
  2. 使用std::cin读取字符串会返回遇到第一个空格之前的字符。其它的字符都在缓冲区内,等待下一次提取
    在这里插入图片描述
  3. std::ws 是 C++ 标准库中的一个流操作符,用于从输入流中提取和丢弃所有空白字符,直到遇到第一个非空白字符。它常用于处理用户输入以确保输入流中没有多余的空白字符干扰后续读取操作。
#include <iostream>
#include <string>

int main() {
    std::string input;
    std::cout << "Enter a string: ";
    std::cin >> std::ws; // 跳过所有前导空白字符
    std::getline(std::cin, input); // 读取输入
    std::cout << "You entered: " << input << std::endl;
    return 0;
}
-------------------------------------------------------------------
提取到变量时,提取运算符 ( >>) 会忽略前导空格。遇到非前导空格时会停止提取。

std::getline()不会忽略前导空格。如果您希望它忽略前导空格,请将其std::cin >> std::ws作为第一个参数传递。遇到换行符时,它会停止提取。

  1. 对于string字符串中的长度可以使用string input; cout<<input.length()<<endl;得出,因为length()成员函数在std::string有声明。它的长度不包含’\0’字符。
  • 如果要把它赋值给int变量,那么int length{static_cast<int>(input.length())};
  1. 范例
    编写一个程序,要求用户输入全名和年龄。输出是告诉用户他们的年龄总和和名字中的字母数(使用成员std::string::length()函数获取字符串的长度)。为简单起见,将名字中的任何空格都算作一个字母。

---------------------------------------------------------------------------------------
#include <iostream>
#include <string>

int main()
{
    std::cout << "Enter your full name: ";
    std::string name{};
    std::getline(std::cin >> std::ws, name); // read a full line of text into name
	//cin>>std::ws;std::getline(std::cin,name);等同于
	//
    std::cout << "Enter your age: ";
    int age{}; // age needs to be an integer, not a string, so we can do math with it
    std::cin >> age;

    // age is signed, and name.length() is unsigned -- we shouldn't mix these
    // We'll convert name.length() to a signed value
    int letters{ static_cast<int>(name.length()) }; // get number of letters in name (including spaces)
    std::cout << "Your age + length of name is: " << age + letters << '\n';

    return 0;
}

五、用户命名空间

1.关键字namespace
//语法如下,命名空间必须在全局范围内定义,或者在另一个命名空间内定义。与函数的内容非常相似,命名空间的内容通常缩进一级。
namespace NamespaceIdentifier 
{ 
    // 此处为命名空间的内容
}
  • 使用范围解析运算符 (:😃 访问命名空间,范围解析运算符告诉编译器应在左侧操作数的范围内查找右侧操作数指定的标识符。
#include <iostream>

namespace Foo // define a namespace named Foo
{
    // This doSomething() belongs to namespace Foo
    int doSomething(int x, int y)
    {
        return x + y;
    }
}

namespace Goo // define a namespace named Goo
{
    // This doSomething() belongs to namespace Goo
    int doSomething(int x, int y)
    {
        return x - y;
    }
}

int main()
{
    std::cout << Foo::doSomething(4, 3) << '\n'; // use the doSomething() that exists in namespace Foo
    std::cout << Goo::doSomething(4, 3) << '\n'; // use the doSomething() that exists in namespace Goo
    return 0;
}
  • 范围解析运算符也可以用在标识符前面,而无需提供命名空间名称(例如::doSomething)。在这种情况下,doSomething将在全局命名空间中查找标识符。
  • 如果使用命名空间内的标识符且未提供范围解析,则编译器将首先尝试在同一命名空间中查找匹配的声明。 如果未找到匹配的标识符,则编译器将依次检查每个包含的命名空间以查看是否找到匹配项,最后检查全局命名空间。

在这里插入图片描述
使用 ::print() 时,编译器只会在全局命名空间中寻找 print 函数。如果全局命名空间中不存在 print 函数,则会报错。不会在其他命名空间中寻找名为 print 的函数。命名空间有全局和定义的命名空间之分。

2、命名空间嵌套
#include <iostream>

namespace Foo
{
    namespace Goo // Goo is a namespace inside the Foo namespace
    {
        int add(int x, int y)
        {
            return x + y;
        }
    }
}

int main()
{
    std::cout << Foo::Goo::add(1, 2) << '\n';
    return 0;
}
--------------------------------------------------------
请注意,由于命名空间Goo位于命名空间内部Foo,因此我们add以身份访问Foo::Goo::add。
  • 命名空间别名 namespace Active = Foo::Goo; // active now refers to Foo::Goo
  • 允许跨文件或者同一文件的多个位置声明同一个命名空间,命名空间内的所有声明均视为命名空间的一部分。

编译和链接

  1. Linux(或其他操作系统)上编译 C++ 程序时,链接步骤在以下情况下是必需的:
  • 多个源文件:当你的程序由多个源文件(.cpp 文件)组成时,需要将这些文件编译并链接在一起。例如,如果你有一个 main.cpp 和一个 add.cpp,你需要将它们都编译并链接成一个可执行文件。

  • 使用外部库:如果你的程序依赖于一个或多个外部库(例如,Boost 库、SQLite 库等),你需要在链接阶段指定这些库,以便将库中的函数和对象链接到你的程序中。

  • 使用头文件和实现分离:当你将函数声明放在头文件(.h 文件)中,而将函数定义放在源文件(.cpp 文件)中时,需要在链接阶段将编译后的目标文件(.o 文件)链接在一起。

  1. 编译和链接的步骤
    编译和链接可以分为两个主要步骤:
  • 编译:将每个源文件(.cpp 文件)编译成目标文件(.o 文件)。
  • 链接:将所有目标文件(.o 文件)和库文件链接在一起,生成最终的可执行文件。
  1. 示例
    假设我们有三个文件:main.cpp、add.h 和 add.cpp。
  • 编译源文件
g++ -c main.cpp -o main.o//编译main.cpp为main.o
g++ -c add.cpp -o add.o //编译add.cpp为add.o
  • 链接目标文件
g++ main.o add.o -o main//将main.o和add.o链接后输出为main可执行文件
  • 一步完成上诉所有步骤
g++ -o main main.cpp add.cpp
g++ main.cpp add.cpp//此时可执行文件默认为a.out
  • 链接外部库
g++ -o main main.cpp add.cpp -lm

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

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

相关文章

Java实习手册(小白也看得懂)

秃狼说 距离俺发布的学习路线已经六个月了&#xff0c;那我给小伙伴的学习周期是四五个月左右&#xff0c;我相信大多的小伙伴已经学习的差不多了。正好赶上暑期实习的阶段&#xff0c;在暑期找到实习就成为暑期的头等大事。 实习经验在校招的起到决定性的作用&#xff0c;所…

单元测试Spring 上下文加载过程中遇到的阻塞或死锁问题

IDEA单元测试一直转圈&#xff0c;阻塞&#xff0c;前置后置的方法都不执行&#xff0c;无任何输出 1.单元测试类 SpringBootTest(classes {BareMetalApplication.class}) RunWith(SpringRunner.class) public class K8sUserNfsStoreInitServiceImplTest {BeforeEachpublic…

国家力推!国家人工智能产业标准化指南

在科技日新月异的今天&#xff0c;人工智能&#xff08;AI&#xff09;作为推动社会进步和产业升级的关键力量&#xff0c;正以前所未有的速度改变着我们的世界。从自动驾驶到智能制造&#xff0c;从智慧医疗到金融科技&#xff0c;人工智能的触角已经深入到了经济社会的各个角…

三万字带你一遍跑通uer

三万字带你一遍跑通uer 参考文档 今天给大家介绍个非常强大的项目uer&#xff0c;集成了许多可以做自然语言的东西&#xff0c;效果的话也非常好&#xff0c;很适合企业级的应用&#xff01; 1. 先将项目uer从github拉取下来&#xff08;zip或git都ok&#xff09; 2. 用pycha…

linux查看当前文件夹的剩余空间

要查看当前文件夹所在的文件系统的剩余空间&#xff0c;并以GB为单位显示&#xff0c;可以使用以下命令&#xff1a; df -BG .其中&#xff1a; B&#xff1a;用于指定块大小&#xff08;block size&#xff09;。你可以通过指定后缀来改变输出的单位&#xff0c;如K&#xf…

船舶雷达与导航系统选择7/8防水插座的原因分析

概述 船舶雷达与导航系统在现代航海中扮演着至关重要的角色&#xff0c;它们为船舶提供准确的导航信息&#xff0c;确保航行的安全和效率。在这些系统中&#xff0c;7/8防水插座的使用尤为重要&#xff0c;因为它们能够在恶劣的海上环境中提供稳定的电力和信号连接。接下来&am…

Finding Global Homophily in Graph Neural Networks When Meeting Heterophily

本文发表于:ICML22 推荐指数: #paper/⭐⭐⭐ 问题背景: 异配图的邻接矩阵难以确定,以及异配图的计算复杂度开销大 可行的解决办法:高通滤波多跳邻居,GPRGNN(pagerank一类&#xff0c;各阶邻居的权重不同,ACM-GCN&#xff08;高低通滤波,H2GCN&#xff08;应该复杂度很大&…

《梦醒蝶飞:释放Excel函数与公式的力量》8.8 STDEVP函数

8.8 STDEVP函数 STDEVP函数是Excel中用于计算总体数据的标准偏差的函数。标准偏差是统计学中的一个重要指标&#xff0c;用于衡量数据集中各数值偏离平均值的程度。总体标准偏差考虑了整个数据集&#xff0c;而不是样本。 8.8.1 函数简介 STDEVP函数用于返回总体数据的标准偏…

Infinitar链游新发展新机遇

区块链游戏市场在近年来经历了显著增长&#xff0c;吸引了大量的投资和关注。随着加密货币和NFT&#xff08;非同质化代币&#xff09;概念的普及&#xff0c;越来越多的投资者、游戏开发者和看到了区块链技术在游戏领域的应用潜力&#xff0c;纷纷涌入市场。区块链游戏的用户量…

LeetCode 算法:二叉树的最近公共祖先 III c++

原题链接&#x1f517;&#xff1a;二叉树的最近公共祖先 难度&#xff1a;中等⭐️⭐️ 题目 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个节点 p、q&#xff0c;最近公共祖先表示为一个节点…

Jackson与Json、Json和各种Java数据类型的互相转化

jackson是什么 json是最常用的数据交换格式 Jackson是最流行的Json库 首先对于这种JSON序列化的库其实有非常多&#xff0c;比如我们熟悉的Gson&#xff0c;Fastjson等等&#xff0c;当然技术没有完全的好坏&#xff0c;但是从使用情况和社区生态等方面综合看来&#xff0c;Ja…

uni-app x 跨平台开发框架

目录 uni-app x 是什么 和Flutter对比 uts语言 uvue渲染引擎 组合式API的写法 选项式API写法 页面生命周期 API pages.json全局配置文件 总结 uni-app x 是什么 uni-app x&#xff0c;是下一代 uni-app&#xff0c;是一个跨平台应用开发引擎。 uni-app x 是一个庞…

A4-C四驱高防轮式巡检机器人

在当今数字化和智能化迅速发展的时代&#xff0c;旗晟智能带来了一款革命性的创新产品——A4-C四驱高防轮式巡检机器人。这款机器人以其卓越的性能和多功能性&#xff0c;为工业巡检领域带来了全新的解决方案。 一、产品亮点 1、四驱动力与高防护设计 四驱高防轮式巡检机器人…

el-table封装点击列筛选行数据功能,支持筛选,搜索,排序功能

数据少的话&#xff0c;可以前端实现&#xff0c;如果多的话&#xff0c;建议还是请求接口比较合理父组件&#xff1a; <template> <div class"home"> <!-- <img alt"Vue logo" src"../assets/logo.png"> <HelloWorld …

重塑通信边界,基于ZYNQ7000 FPGA驱动的多频段多协议软件无线电平台

01、产品概述 本平台是基于高性能ZYNQ-7000系列中的XC7Z045处理器构建的多频段多协议软件无线电解决方案&#xff0c;集成了AD9364芯片——一款业界领先的1x1通道RF敏捷收发器&#xff0c;为无线通信应用提供了强大支持。其存储架构包括2路高速4GB DDR3内存、1路32GB EMMC存储以…

springboot dynamic配置多数据源

pom.xml引入jar包 <dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.5.2</version> </dependency> application配置文件配置如下 需要主要必须配置…

ASUS/华硕飞行堡垒8 FX506L FX706L系列 原厂win10系统 工厂文件 带F12 ASUS Recovery恢复

华硕工厂文件恢复系统 &#xff0c;安装结束后带隐藏分区&#xff0c;一键恢复&#xff0c;以及机器所有驱动软件。 系统版本&#xff1a;Windows10 原厂系统下载网址&#xff1a;http://www.bioxt.cn 需准备一个20G以上u盘进行恢复 请注意&#xff1a;仅支持以上型号专用…

【收藏级神丹】Liae384_刘亦菲_直播可用,平衡度最高的原创神丹,独家珍稀资源

Liae384_刘亦菲_DFL神丹&#xff1a;点击下载 此丹较重&#xff0c;小卡可以使用但不能训练&#xff0c;实测复训适合24G卡8G、12G、16G卡下载练好的专丹直接使用即可384的Liae对各类杂论视频兼容比较好&#xff0c;高参也能容忍高分辨率的DST复用方式: 非必要不用删除AB&…

Docker:二、常用命令

&#x1f341;docker常用命令 官方帮助文档&#xff1a;https://docs.docker.com/reference/ &#x1f332;帮助命令&#xff08;版本信息&#xff09; docker -v # 显示docker版本 docker version # 显示docker版本信息 docker info # 显示docker系统信息 docker 命…

人工智能系列-numpy(三)

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 副本和视图 副本 副本是一个数据的完整的拷贝&#xff0c;如果我们对副本进行修改&#xff0c;它不会影响到原始数据&#xff0c;物理内存不再同一位置。副本一般发生在Pytho…