C++基础

复合类型

引用

声明方式

int a;
int &p = a;
int &b; // 报错,引用必须被初始化

引用必须与具体对象绑定,不可以绑定到字面值或表达式的计算结果上,并且类型必须严格匹配。

int &a = 10; // error
double b = 21.3;
int &c = b; // error

指针

int a = 1;
int *p = &a;
double *e = &a; //error

指针的类型需要匹配
初始化空指针

int *p = nullptr;
int *p = 0;
int *p = NULL;

最好使用nullptr

指针的size:取决于机器是32位的还是64位的,因为指针存的是地址,所以32位大小是4B,64位是8B

void*

void*是一种特殊指针,它可以存放任意类型的地址,不必拘泥于类型。但是不可以直接对void*的对象进行操作(因为不知道它的类型)。

int a = 10;
double b = 1.5;
void* p = &a;
double* k = &b;
p = k;
// cout<<*p<<endl; // error,因为不可以直接操作void指针
*(double*)p = 2.5; // 使用强制类型转换
cout<<b<<endl; // 2.5

定义多个复合变量

int *p;的基本数据类型是int,* 修饰的p。
int *p, q中,p是指针,q是int
int *p, *q是两个指针

指向指针的指针

int a = 10;
int *p = &a;
int **q = &p;

从右往左读,指向指针的引用

#include<iostream>
#include"swap.h"
using namespace std;
int main() {
	int a = 10;
	int c = 3;
	int *p = &a;
	int*& r = p; // r 是指向p的引用
	*r = 1;
	printf("a = %d, c = %d\n", a, c);
	// a = 1, c = 3
	r = &c; // r和p都指向c了
	*p = 2;
	printf("a = %d, c = %d\n", a, c);
	// a = 1, c = 2
	return 0;
}
}

认识r

int *p = nullptr;
int *&r = p;

在这里,从右往左读。离r最近的是&,所以r是一个引用,&的左边是一个*,所以r引用的是指针, 再左边是int,所以r引用的一个int型的指针。

const限定符

const的对象创建之后就不可以改变,必须在创建时初始化。

默认状态下,const仅在文件内有效。
编译器对const做的其实是将所有声明的词做替换,如const int a = 1;,那么编译器就在本文件内找到所有的a,将其换为1.
extern关键字的说明
多文件共享const,不在声明时定义,在某文件定义
多文件共享const,不在声明时定义,在某文件定义

对const的引用

又称常量引用

const int a = 1;
const int &r = a;
r = 2; // error
int &r2 = a; // error

初始化常量引用

int i = 1;
const int a = i;
const int b = 1;
const int c = 2 * i;
int& c = a;

当使用常量引用的适合,可以对不同类型的对象赋值。

double a = 3.14;
const int &r = a;
int &r2 = a; // error

因为在赋值时,进行了如下操作

const int temp = a;
const int &r = temp;

因为r是引用常量,所以不会对a的值进行改变,所以允许赋值。但是r2不是常量,可能会改变a的值,所以不允许赋值。

举例说明,对const的引用的作用

int a = 3;
const int r1 = a;
const int& r2 = a;
a = 0;
cout << a << " " << r1 << " " << r2;
// 0 3 0

使用常量引用可以获得一个值会随着原对象改变的引用变量,直接使用const,那么r1的值就是在赋值那一刻确定了,后续a改变,r1的值也不会改变。

const与指针

const对仅对指针限制,对原对象不限制。上面的引用也是同理

指向常量的指针,不能通过该指针修改变量的值,但是可以通过其他途径修改
const指针,不能修改指针指向的对象

int a = 3;
const int *p = &a;
int const *p1 = &a;
int* const p2 = &a;
const int* const P = &a;
int b = 2;
p = &b;
p1 = &b;
// *p1 = 1; // error
*p2 = 1;
// p2 = &b; // error
// P = &b; // error
// *P = 1; // error

const int *pint const *p等价,都不可以通过p修改值(const int==int const
int * const p不可以修改p指向的对象
const int const *p双重限制

顶层/底层const

在这里插入图片描述
在这里插入图片描述

constexpr

常量表达式 是指值不会改变且在编译过程中就可以得到计算结果的表达式

const int a = 1;
const int b = a + 1;
const int c = getValue(); //  false
int d = 1; // false

constexpr和const的区别
constexpr表示在编译期就可以算出来(它所依赖的东西也是在编译期可以算出来的)。const只保证了运行时不直接被修改(但这个东西仍然可能是个动态变量)。

constexpr 指针

constexpr修饰指针时,做顶层const,仅对指针有效,对指针所指的对象无效。

int i = 3;
constexpr int* p = &i; // 常量指针
const int* q = &i; // 指向常量的指针
*p = 2;
cout << i; // 2
constexpr const int p = &i;

处理类型

类型别名

typedef和using

typedef double D;
using I = int;

在这里插入图片描述

auto

由编译器自动推断数据类型,可以一行声明多个变量,但是其类型要一致。

int i = 3;
auto a1 = 0, &r1 = i, *p1 = &i; // 正确,int型数、引用、指针
auto a2 = i, a3 = 3.5; // error

在这里插入图片描述

decltype

当希望从表达式的类型推断出当前定义变量的类型,但是不希望用该表达式来为其赋值时,使用decltype

int a = 1, *p = &a, &r = a;
decltype(a) c = 10; // type is int, value is 10;
decltype(p) pp; // 指针
decltype(r) q; // error,q是引用,必须初始化

decltype和引用

在这里插入图片描述

在这里插入图片描述
如上节的例子,
decltype(*p) t是错误的,因为*p解引用得到的是一个指针的对象,还可以修改该对象,所以decltype(*p)的结果是int&, 所以必须初始化t。
decltype(r + 0) t是正确的,因为引用+0后得到的值是int

自定义数据结构

不要忘了分号

struct Name{
/*---*/
};

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值