C++中的Type Alias 和 Primitive Arrays 和 Primitive C-string
在C++中,我们通常使用typedef来实现type alias. 比如:
#include <cstdint> //C standard int typedef uint32_t points_t; //points_t is alias of uint32_t typedef uint64_t rank_t; //rank_t is alias of uint64_t struct score { points_t p {}; rank_t r {}; }
现在更modern的方式是, 是 using 来进行type alias, 请看:
#include <cstdint> //C standard int using points_t = uint32_t; //points_t is alias of uint32_t using rank_t = uint64_t; //rank_t is alias of uint64_t struct score { points_t p {}; rank_t r {}; }
接下来,我们来说一说C++中的primitive array, C++中的primitive array 又称为C-array, 因为它是从C语言继承过来的. 同时,也和C++中的STL class中的array区分开来(有一个叫array的STL Class)
array 是一种 fixed size container, 它里面的每一个元素都是同一种类型。例子:
int ia[5] {}; //定义了一个整形数组,数组大小为5, 一旦定义,数组大小不能再变。通过{}把它里面的值初始化为5个0
*ia = 1; // 数组可以用指针进行访问,*ia指向数组的第一个元素(代表数组的第一个元素).这一行代码等价于 ia[0] = 1;
int *ip = ia; // 这里,我们也可以定义一个新的整形指针 *ip, 然后把数组ia的地址赋给这个新指针。 注意这里你不需要写成 int *ip = &ia;(你也可以这样写),因为an array may be accessed as if it were a pointer. (该表达式和等同于 int* ip = ia 或者 int* ip = &ia);
*ip = 2; //给数组的第一个元素赋值为2
++ip; //指针往前移动一位,现在指向数组的第二个元素
*ip = 3; //给数组的第二个元素赋值为3
*(++ip) = 4; //也可以这样写,给数组的第三个元素赋值为4
也可以这样初始数组
int ib[] {1,2,3,4,5}; //系统会自动推断数组长度为5
for(const int& i : ib) //定义一个引用i,是个整形引用,const代表它不能更改. The reference means we don't make a copy of the value, const qualify means we can not change the value in the array
{
cout<< i <<end1;
}
C++中的primitive string又称为C-string,是从C语言中继承的string(其实就是以null结尾的字符数组,因为C语言中其实并没有字符串string这个数据类型). 它区别于C++的STL中的String class
#特别注意# 只有以null结尾的字符数组才是C字符串. 否则就只是一个一般的C字符数组 => C语言中C-string和C字符数组的区别
C语言中字符数组follwed by a zero value or a null terminator =》 C-string. 在C语言中,Null和0都是一样的,但是为了目的和用途以及容易识别的原因, Null通常用于指针和对象,而0用于数值
#include <format>
#include <iostream>
using std::format;
using std::cout;
int main()
{
/*
const char s[] {"string"} => const string, a constant string is actually a C String
但是,更通常的做法是, we declare a string with a pointer and a constant string,所以,我们通常这样写C-String
const char* s {"string"};
*/
const char s[] {"string"}; // const string, a const string is actually a C String
const char* s {"string"}; //most common 最通常的写法
const char s[] {'s','t','r','i','n','g',0}; // => 最后一个是0. 以0结尾的字符数组
//上面2行效果是一样的,都是定义一个C-string
我们通常这样访问它
for(const auto& c : s)
{
cout << format("{}\n",c); //这里会输出
}
/*
在用for循环访问Array/C-String时,更常用的写法是使用pointer,因为Array can be used as if it were pointer
指针指向数组Array(C-String)的首地址,然后依次递增指向后面的地址
for(const auto* p = s; *p; ++p)
这里面,第一句 const auto* p = s; 是把Array/C-string的地址赋给常量指针p, 通常我们应该写成const auto* p = &s;但是因为是Array/C-string,我们可以直接写成const auto* p = s; s在这里就是代表这个array/c-string的地址 -> Remember that the array symbol itself represents the address of the array
第二句 *p => 因为C-String的最后一位是0,而0在C++中代表false,其他值为true.所以它会一直执行到为false,也就是C-String的最后一位
第三句 ++p => 就是正常的指针指向的地址加一位
*/
for(const auto* p = s; *p; p++)
{
cout << format{"{}\n",*p}; //*p这里是dereference pointer, 获取它指向的值
}
}
所以,上面的C-sting有7个元素,最后一个元素是0