C++学习笔记二

news2024/11/25 6:56:09

一、常量

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

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

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

相关文章

小程序分包加载、独立分包、分包预加载等

一、小程序分包加载 小程序的代码通常是由许多页面、组件以及资源等组成&#xff0c;随着小程序功能的增加&#xff0c;代码量也会逐渐增加&#xff0c; 体积过大就会导致用户打开速度变慢&#xff0c;影响用户的使用体验。分包加载是一种小程序优化技术。将小程序不同功能的代…

SpringBoot整合Dubbo的快速使用教程

目录 一、什么是Dubbo? 二、SpringBoot整合Dubbo 1、父工程引入依赖 2、各个Dubbo服务子模块引入依赖 3、服务提供者 &#xff08;1&#xff09;启动类添加注解EnableDubbo &#xff08;2&#xff09;服务类添加注解DubboService &#xff08;3&#xff09;配置文件…

class类和style内联样式的绑定

这里的绑定其实就是v-bind的绑定&#xff0c;如代码所示&#xff0c;div后面的引号就是v-bind绑定&#xff0c;然后大括号将整个对象括起来&#xff0c;对象内先是属性&#xff0c;属性后接的是变量&#xff0c;这个变量是定义在script中的&#xff0c;后通过这个变量&#xff…

数据库国产化之路(一)

数据库国产化之路(一) 1、前言&#xff1a;适配海量数据库过程中的一些记录&#xff0c;备忘用 2、海量数据库基于的pg版本&#xff0c;查看PG_VERSION文件为9.2。 3、MySQL中的IF函数替代&#xff0c;一开始的方案是从网上找了个if函数&#xff0c;后来发现CASE WHEN其实能完成…

【c语言】轻松拿捏自定义类型

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;C语言 目录 前言 一、结构体 1.结构体类型的定义和使用 1.1 结构体类型声明 1.2 结构体变量的创建和初始化 1.3 结构体变量成员的访问 1.4 结构体的特殊声…

[深度学习]卷积理解

单通道卷积 看这个的可视化就很好理解了 https://github.com/vdumoulin/conv_arithmetic/blob/master/README.md 多通道卷积 当输入有多个通道时,卷积核需要拥有相同的通道数. 假设输入有c个通道,那么卷积核的每个通道分别于相应的输入数据通道进行卷积,然后将得到的特征图对…

tinyshop商城学习

1、使用badboy屏幕录制工具&#xff0c;获得服装购物业务的结果&#xff0c;生成.jmx文件 2、在JMeter中新建线程组&#xff0c;导入.jmx文件 3、完成进入商城&#xff0c;登录&#xff0c;服装页面进入&#xff0c;随机选择服装&#xff0c;添加购物车&#xff0c;开始结算&…

Qt扫盲-QRect矩形描述类

QRect矩形描述总结 一、概述二、常用函数1. 移动类2. 属性函数3. 判断4. 比较计算 三、渲染三、坐标 一、概述 QRect类使用整数精度在平面中定义一个矩形。在绘图的时候经常使用&#xff0c;作为一个二维的参数描述类。 一个矩形主要有两个重要属性&#xff0c;一个是坐标&am…

6款天花板级的国产BI大盘点

以下是六款天花板级的国产BI工具的盘点&#xff0c;包括奥威BI、帆软BI、思迈特BI、永洪BI、观远BI和亿信华辰BI。这些工具各有其独特的优点和擅长的领域。 1. 奥威BI 优点&#xff1a; 无缝对接ERP系统&#xff1a;与金蝶、用友等全版本ERP系统无缝对接&#xff0c;方便用户…

软件游戏d3dcompiler_43.dll丢失怎么办,总结几种有效的方法

在使用电脑时&#xff0c;可能会碰到找不到d3dcompiler_43.dll的问题。即在使用过程中&#xff0c;突然弹出一个提示“d3dcompiler_43.dll丢失”&#xff0c;由于此文件的缺失&#xff0c;部分程序将无法启动。为恢复正常使用&#xff0c;我们需要修复此文件。接下来&#xff0…

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

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

Spring源码十一:事件驱动

上一篇Spring源码十&#xff1a;BeanPostProcess中&#xff0c;我们介绍了BeanPostProcessor是Spring框架提供的一个强大工具&#xff0c;它允许我们开发者在Bean的生命周期中的特定点进行自定义操作。通过实现BeanPostProcessor接口&#xff0c;开发者可以插入自己的逻辑&…

ServiceImpl中的参数封装为Map到Mapper.java中查询

ServiceImpl中的参数封装为Map到Mapper.java中查询&#xff0c;可以直接从map中获取到key对应的value

吴恩达机器学习作业ex7:K 均值聚类和主成分分析(Python实现)详细注释

文章目录 1 K 均值聚类1.1 实施 K-means1.1.1 寻找最近的中心点1.1.2 计算中心点均值 1.2 示例数据集上的 K-means1.3 随机初始化1.4 用 K-means 压缩图像1.4.1 对像素进行 K 均值分析 2 主成分分析2.1 样例数据集2.3 利用 PCA 降低维度2.3.1 将数据投影到主成分上2.3.2 重建数…

满足GMSL静电防护要求的方案

什么是GMSL&#xff1f;它是做什么用的&#xff1f;它有什么优点&#xff1f;设计GMSL防静电有啥难度&#xff1f; 带着这些疑问我们先了解下什么是GMSL。 一&#xff0e;简述 GMSL GMSL&#xff08;Gigabit Multimedia Serial Link&#xff09;即千兆多媒体串行链路&#xf…

vs code 波浪线报错

这种红色波浪线的 VS code 报错&#xff0c;之前我都是直接忽略&#xff0c;因为不影响运行&#xff0c;但是我看着就很闹心想要给它去掉。 明明这个module 在啊&#xff0c;为啥一直报错 Cannot find module 今天知道原因了&#xff1a; 为了图方便&#xff0c;我 的 VS …

HPR3B-30A1-201、HPR3B-30A2-211-M4液压比例减压阀放大器

HANDOK HYDRAULIC比例减压阀HPR2P-30A1-201、HPR2P-30A1-201-M5、HPR3S-40A1-201-M3、HPR3Q-40A1-201-M2、HDPR3Q-40A1-201-M0、HPR3B-30A2-211、HPR3B-40F1-212 FOR SBS120/140、HDSV4B-A1-232、HPR3NB-30A-221、HDSV3B-A1-232-GO-PVD、HPR3B-30A1-213、HSVD3B-A1-232-GO-PSVD…

网络-calico问题分析

项目场景&#xff1a; calico-node日志提示 Failed to auto-detect host MTU - no interfaces matched the MTU interface pattern. To use auto-MTU, set mtuifacePattern to match your hosts’s interfaes. 同时&#xff0c;cali开头网卡的mtu是1440大小 原因分析&#xff…

每日复盘-20240705

今日关注&#xff1a; 20240705 六日涨幅最大: ------1--------300391--------- 长药控股 五日涨幅最大: ------1--------300391--------- 长药控股 四日涨幅最大: ------1--------300391--------- 长药控股 三日涨幅最大: ------1--------300391--------- 长药控股 二日涨幅最…

windows安装jdk21

下载 下载zip解压 设置环境变量 设置JAVA_HOME环境变量 Path环境变量添加如下值%HAVA_HOME%\bin 打开新的cmd&#xff0c;输入java --version查看效果