可以对指针进行引用,但是不存在引用的引用
int a;
int *p = &a;
int* & rp = p;//此时rp是一个地址,要改变p的值要么*rp = XXX;
//要么rp = &XXX;
int & ra = a;
int & & rra = ra;//这是不对的
int & rra = ra;//也不能叫作引用的引用,因为rra也是a的引用
可以对指针再取指针,但是不能对引用取指针
int a;
int & ra = a;
int *p = &a;
int **xp = &p;//legal
int & * rra = &ra;//illegal
可以有数组的指针,指针数组和数组的引用,但是不能存在引用数组
int a[] = {1,2,3};
int * p = a;//此处的p是a数组首地址;a具有双重身份,既可以当数组首地址也可以当整个数组,具体看 //语境
int * pa[] = {&x,&y,&z};//数组里面存的数据都是int *这种指针类型的
int & ra = {ra,rb,rc};//illegal,对于数组ra而言,ra可以当作首地址,那么ra类型就为int & *,
//这是不合法的
int (&rra)[3] = ra;//legal,Cpp允许对指定大小的数组进行引用,因为ra数组名本身就既包含首地址 //又包含大小,此时ra数组还有一个名字为rra
int (&rra)[] = ra;//illegal,大小位置无法引用
int & rra[3] = ra;//illegal,int与&不能相见,不然数组类型就是int &,那数组成了引用的数组了
cout输出格式控制<iomanip>
cout << dec << i << endl;//十进制
cout << hex << i << endl;//十六进制
cout << oct << i << endl;//八进制
cout << setbase(x) << i << endl;//x进制
常引用
-
const类型的数据必须使用const类型的引用去绑定,但是非const类型的可以使用const类型的引用
-
const引用可以使用常量、非同类型变量、表达式去初始化
int a = 10;
int &ra = a;
const double &rd = a;//legal,本质是产生了const double d = a;这个中间变量,再const //double &rd = d;
const int &rx = 200 + a;//legal,原理相同
函数多使用const 类引用,可以防止无意修改数据的错误,可以接收const与非const变量,还可以正确生成并使用临时变量(如果传入非本类型的参数或者常数、表达式都可以进行处理,保证程序的健壮性)
引用需要声明以后就初始化,而且不能修改指向,本质是由int * const来实现的
new 和 delete
//单变量
int *q = new int;
int *p = new int(200);
string *ps = string("people");
*ps = "yes";
struct Stu
{
int id;
string name;
};
Stu *stu = new Stu{2,"jeson"};
//多变量
int *p = new int[4];
char *q = new char[40];
strcpy(q,"china");
char* *str = new char*[40];
str[0] = new char[10]{"hello"};
str[1] = new char[15]{",world"};
int (*prr)[4] = new int [3][4];
//delete
int *p = new int;
delete p;
int *q = new int[3];
delete []q;
int (*x)[3][5] = new int[3][3][5];
delete []x;
q:三维数组为什么是int (*x)3 = new int3[5];?
a: int (*p)3 = new int10[5]; 写法是正确的,因为存在隐式转换。 前面是一个指向二维数组的指针。 后面是一个三维数组的首地址。 因为标准c++内存是连续的。现实做开发,很少用到三维数组。对于二维数组的创建也是一样的,前面是一个指向一维数组的指针,然后后面是一个二维数组的首地址,同样由于连续存储所以这样写也是可以的
q:那这个括号是怎么理解的?他为什么要加这个括号不加就是错的呢?
a:
-
int *p[5]
含义: [](数组下标运算符)的优先级高于 (指针运算符)。 因此,p 首先与 [5] 结合,表示 p 是一个包含 5 个元素的数组。 然后, 与 int 结合,表示数组中的每个元素都是一个指向 int 类型的指针。 所以,int *p[5] 声明了一个包含 5 个指向 int 类型的指针的数组。 用途: 常用于存储多个指向不同 int 变量或 int 数组的指针。
-
int (*p)[5]
含义: ()(括号运算符)的优先级最高,因此 p 首先结合。 这表示 p 是一个指针。 然后,[5] 与 int 结合,表示 p 指向一个包含 5 个 int 元素的数组。 所以,int (p)[5] 声明了一个指向包含 5 个 int 元素的数组的指针。 用途: 常用于处理二维数组,或者需要将整个数组作为参数传递给函数的情况。 例如,可以把二维数组的每一行,当成一个有五个int元素的数组,然后用这个指针指向这个行。
int p[5]:数组,包含 5 个指向 int 的指针。 int (p)[5]:指针,指向包含 5 个 int 的数组。
inline是编译器的一种建议
内联函数会直接进行替换、减少调用时间和出入栈开销
短小的、且被频繁调用函数才能使用inline
类型强转
//static_cast(可以进行隐式转换)
int a = 5;
double b = 5.6;
int change_a = static_cast<int> (b);
double change_b = static_cast<double> (a);
//reinterpret_cast(双方无法进行隐式转换)
char *p;int *q;
p = reinterpret_cast<char *>(q);
//const_cast(只能应用于指针和引用)
const int a = 10;
int &ra = const_cast<int &>(a);
ra = 200;//此时a为10,ra为200//不要使用