C++ | C++ 基础知识 | 指针、数组与引用

1.指针

在 C++ 语言中存放及使用内存地址是通过指针和引用完成的。

char c  = 'a';  // 声明 c 变量,c 变量存储的是 'a' 的值。
char* p = &c;   // 声明 p 变量,p 变量存储的是 c 的指针。 & 是取地址符
char** q = &p;  // 声明 q 变量,q 变量存储的是 p 的指针。 & 是取地址符,q 存储的是指针的指针
char c2 = *p    // c2 = 'a',*符号是解引用运算符。

存储如下图:

1.1 void * 指针

void* 的含义是 ”指向未知类型对象的指针“。
void* 最主要的用途是当我们无法假定对象的类型时,想函数传递指向该对象的指针,它还用于从函数返回未知类型的对象。当使用这种未知对象时候,必须先进行显式类型转换。

用到 void* 指针的函数通常位于系统的最底层,这些函数的作用大多是操作硬件资源
eg: void * my_alloc(size_t n);

1.2 nullptr 表示空指针,即不指向任何对象的指针。

nullptr 表示空指针,不指向任何对象的指针。nullptr 只能用于指针类型。
未引入 nullptr 之前,通常用 0 表示空指针
int* x = 0
C 语言中通常使用 NULL 来表示空指针,在 C++ 中 NULL 语法是非法的。
int* x = NULL -> int* x = (void *)0

2.数组

    float a[32];  // 包含 32 个float的数组,依次是 a[0] ... a[31];
    char* a[32];  // 包含 32 个char指针的数组,依次是 a[0] ... a[31]; 

数组应注意空间分配越界问题,数组的初始化与C相同。

2.1 数组初始化

数组初始化,编译器会根据列表包含的元素数量自动计算数组大小。如果制定了数组的大小,但提供的初始化器列表元素数量过多,则程序会发生越界错误。

char v3[2] = {'a', 'b'}

2.2 大字符集

前缀是 L 的字符串由宽字符组成,类型是 const wchar_t[]
Unicode 本身至少有 3 种编码方式:UTF-8,UTF-16,UTF-32。
UTF-8 字符串的结尾是 '\0'
UTF-16 字符串的结尾是 u'\0'
UTF-32 字符串的结尾是 U'\0'

cout << "folder\\file"   << endl;   // 字符串
cout << R"(folder\file)" << endl; // 原始字符串
cout << u8"folder\\file" << endl; // UTF-8字符串
cout << u"folder\\file"  << endl;  // UTF-16字符串
cout << U"folder\\file"  << endl;  // UTF-32字符串

2.3 数组中的指针

数组名可以看成是指向数组首元素的指针。

int v[] = {1,2,3,4};
int* p1 = v;
int* p2 = &v[0]
int* p3 = v + 4;

2.4 传递数组

不能以值传递的方式直接把数组传给函数,通常传递的是指向数组首元素的指针。

2.5 多维数组

多维数组是指数组的数组。
int array[3][5];

for(int i = 0; i != 3; i++)
    for(int j = 0; j != 5; j++)
        array[i][j] = 10 * i + j;

3.引用

通过使用指针,能以很低的代价在一个范围内传递大量数据,与直接拷贝所有数据不同,只需要传递指向这些数据的指针的值。指针类型决定了我们能对指针所指的对象进行哪些操作。
引用和指针的区别主要包括:

  • 访问引用与访问对象本身从语法形式上看是一样的。
  • 引用所引的永远是一开始初始化的那个对象。
  • 不存在 "空引用",可以认为引用一定对应着某个对象。

3.1 左值引用

int  p = 1;  // p 的内存地址为:0x7ffeefbff55c
int& r{var}; // r 的内存地址为:0x7ffeefbff55c
int  q{var}; // q 的内存地址为:0x7ffeefbff54c
int x = r;   // x 的内存地址为:0x7ffeefbff55c

猜你喜欢

转载自www.cnblogs.com/corc/p/11936076.html