CPP的学习day1
1.Visual Studio的学习
安装跳过……
1.创建项目
选择创建新项目
因为是学习,选择第二个控制台应用
分配好后点击创建等一会儿就创建好了……
先修改设置:
右击选择属性然后改为如下图
2.CPP的表达式概念
表达式就是运算符和操作数的序列,指定一项计算,表达式的求值可以产生一个结果,也可能有副作用
std:命名空间
比如1 + 1是二元表达式;std::println也是一个表达式
std::println("Hello world")是调用表达式;对这个表达式的求值有副作用,副作用就是在标准输出流打印Hello world
2.1函数的声明和定义
void function() {}
这个叫做函数的实现或者是定义
这是一个最基本的函数声明+定义
1 + 1 的求值残生结果是2
+是运算符,左右两边的1为操作数
如上图,void G();
即为声明函数,出于某种不可知理由,G函数要是出现在j函数之后,那么要先声明函数G
因为名字查找会在作用域S查找名字N,找到在P之前的所有声明,详情请看C++标准 6.5 Name lookup [basic.lookup]
C++23标准 (ISO/IEC 14882:2024): 6.5 Name lookup [basic.lookup] (第44-45页)
https://eel.is/c++draft/basic.lookup#general-3
https://zh.cppreference.com/w/cpp/language/unqualified_lookup
2.2C++的函数声明语法
返回函数 函数名(参数列表) 异常说明 属性(如下图,注:这里没写属性)
noexcept就是异常说明其含义是:指定函数会或者不会抛出异常,对性能有影响
属性的话 比较常用的有[[nodiscard]]其含义是:就是说明函数的返回值不能被丢弃
如上图,调用了x,但是忽略了返回时,就会有警告
重点是你写这个函数的时候加上nodiscard,调用的时候就知道返回值不能被丢弃,如果丢弃了可能就有问题
注:属性不限个数
返回值:是合法的类型名字就可
如上图,为条件异常说明,函数说明后面的noexcept是异常说明
异常说明noexcept(xxx)括号里面要填表达式,求值为true或者false的常量表达式
在这里暂且将弄except也当做是表达式,就是判断里面的表达式会不会抛出异常
所以上图中,f是否会抛出异常就取决于g是否会抛出异常。
在类型的前面,还可以加constexpr/consteval关键词
constexpr的意思是这个函数可以在编译的时候就求值
consteval的意思是这个函数只能在编译时求值
在代码中写一个名字,基本上不是标识符就是关键字
2.3写一个constexpr函数,用于计算一个数的平方
只需要将constexpr放在返回值前,参数写在括号里就好,基本的参数和变量声明差不多,类型在前,名字在后
constexpr int square(int a) { return a * a; }
语义就是语言所表达的含义,如果你给这个函数取名function显然没有什么有用的信息,不然怎么能写出人能读懂的代码
int main() { std::println("{}", square(2)) }
这样就能输出函数square注:谨记将函数写在主函数前或者声明函数
2.3.1如果这时候想要一个其他类型怎么办?
这个时候可以使用模板,模板就是以template<>开头。尖括号里面填模板参数,用逗号隔开,可以嵌套
嵌套就还是template开头,规则就如同没有嵌套一样
template<template< typename>>
首先如果识别到template,那就是一个模板,在尖括号中识别参数,如果是typename那就是要调用者填一个参数类型,如果是template开头就相当于是递归,注:和数量没有关系
template<typename T>
是一个最基本的模板
如果要嵌套,就将typename T换成一个最简单的模板就行,这样里面又是一个模板
这其中,T是类型的名字,就像是参数一样
当然,模板中还可以填实际的参数
template<int x> constexpr int square() { return x * x; }
所以如果你要在模板里面传入一个类型的话就要用typename关键字
接下来开始写一个可以接受任意参数版本的square函数,任何类型的参数,写的过程中是不需要管实际类型是什么的
template<typename T> constexpr T square(T a) { return a * a; } int main() { std::println("{}", square<int>(4)); }
在模板中指定一个类型参数,所以外面可以传一个类型进来,你就不需要关心具体的类型是什么。不管外面传进来是什么,都是你取得名字指代,及T;就像是参数有实参和形参之分
其中的a为形式参数,叫形参,英文是parameter
而square<int>(2);中的int和2可以说是实际参数,也叫实参,英文是argument