此篇博文仅仅是为了记录我在C++语言路上的脚步,填坑ing…
编译
通常来讲,gcc编译C语言的,g++编译C++的
g++编译.cpp文件过程
变量类型
类型可以划分为基本类型与复杂类型
–基本(内建)类型: C++ 语言中所支持的类型
1、数值类型
– 字符类型( char, wchar_t, char16_t, char32_t )
– 整数类型
●带符号整数类型: short, int, long, long long
●无符号整数类型: unsigned + 带符号整数类型
– 浮点类型
●float, double, long double
2、void
—复杂类型:由基本类型组合、变种所产生的类型,可能是标准库引入,或自定义类型
常量与常量表达式
常量指针与顶层常量
顶层常量:const int* ptr = &x; 表示 解引用 **ptr不能被改变,即 不能改变x的值
常量指针:int const ptr = &x;表示 **ptr是int类型,即可以改变x的值,不能改变指针ptr的值
既是常量指针,又是顶层常量:const int * const ptr;
加强限制可以,放松限制不可以
int * -->const int *
const int * -x-> int *
引用&只能绑定到一个对象上,不能绑定到一个字面值上
int& ref =x; right
int& ref =3;wrong
而常量引用可以绑定字面值,如下,是合法的。
int main()
{
int x = 3;
const int& ref = 3;
}
常量表达式
constexpr const int* ptr = nullptr;
constexpr不是类型,而是限定符/说明符,在这里是修饰ptr的,即ptr的格式是const int* const
类型别名和类型的自动推导
可以为类型引入别名,从而引入特殊的含义或便于使用(如:size_t)
两种引入类型别名的方式
– typedef int MyInt;
– using MyInt = int; (从 C++11 开始)
使用 using 引入类型别名更好
– typedef char MyCharArr[4];
– using MyCharArr = char[4];
类型别名与指针、引用的关系
– 应将指针类型别名视为一个整体,在此基础上引入常量表示指针为常量的类型
– 不能通过类型别名构造引用的引用
类型的自动推导
– 从 C++11 开始,可以通过初始化表达式自动推导对象类型
– 自动推导类型并不意味着弱化类型,对象还是强类型
– 自动推导的几种常见形式
● auto: 最常用的形式,但会产生类型退化
● const auto / constexpr auto: 推导出的是常量 / 常量表达式类型
● auto& : 推导出引用类型,避免类型退化
● decltype(exp) :返回 exp 表达式的类型(左值加引用)
● decltype(val) :返回 val 的类型
● decltype(auto) :从 c++14 开始支持,简化 decltype 使用
● concept auto :从 C++20 开始支持,表示一系列类型( std::integral auto x = 3; )
auto x = 3.5 + 15l; double+float类型
编译器自动推导对象类型,输出18.5,x为double类型
#include <iostream>
#include <type_traits>
int main()
{
int x = 3;
int& ref = x;
auto ref1 = ref;
std::out << std::is_save_v<decltype(ref1),int> <<std::endl;
}
以上,输出1。
ref作为右值使用,auto导致类型退化,ref的类型为int&,而ref1的类型为int型。
数组
将一到多个相同类型的对象串连到一起,所组成的类型
– int a → int b[10]
– 数组的初始化方式:
● 缺省初始化 int b[3];
● 聚合初始化(aggregate initialization )int b[3]={1,2,3},或int b[3]={1,2}、int b[3]={}等
缺元素的用0补齐
注意事项
– 不能使用 auto 来声明数组类型
– 数组不能复制
– 元素个数必须是一个常量表达式(编译期可计算的值)
– 字符串数组的特殊性
int a;//a的类型为int型
int b[10]; //数组b的类型为int[10]
int c[] = {1,2,3}; //数组c的类型为int[3]
数组作为右值造成类型退化
引用&不会引起类型退化
C和C++会默认为“Hello\0"
以下两个字符串数组等价
指针数组和数组的指针
int x1;
int x2;
int x3;
int* a[3] = {&x1,&x2,&x3};
x[y] → *((x) + (y))
从数组到指针
● 数组到指针的隐式转换
– 使用数组对象时,通常情况下会产生数组到指针的隐式转换
– 隐式转换会丢失一部分类型信息
– 可以通过声明引用来避免隐式转换
– 注意:不要使用extern 指针来声明数组
● Unknown Bounded Array 声明
● 获得指向数组开头与结尾的指针: std::©begin, std::©end
● 指针算数:
– 增加、减少
– 比较
– 求距离
– 解引用
– 指针索引
指向数组的首地址和尾地址方法,最好使用cbegin、cend,只读不写
● 求元素的个数
– sizeof方法
– std::size方法
– ©end - ©begin 方法
● 元素遍历
– 基于元素个数
– 基于©begin/©end
– 基于range-based for 循环
● C字符串本质上也是数组
● C语言提供了额外的函数来支持C字符串相关的操作: strlen, strcmp…
或者 char str[] = {'H','e','l','l','o','\0'};
多维数组
初始化方式:
元素不足则系统自动补全为0.
数组的遍历:
注意:&符不可丢
while循环遍历:
高维数组转化成指针,只有最高维会进行转换,其他维度的信息会被保留: