C++ 语法基础(三)(一)

简介: C++ 语法基础(三)(一)

指针

知识点


指针的概念


指针保存了一个内存地址,对指针的操作就是对地址的操作。


可以将内存理解为一个“大数组”,指针相当于存储了一个数组下标,它指向下标对应位置的变量。


image.png


指针的声明


用以下代码声明指针。其中,&运算符被称为取地址运算符,它返回变量在内存中的地址。


void指针可以指向任意类型的值。


nt a;
int *ptrToA = &a;
double b;
double *ptrToB = &b;
void *voidPtrToA = &a;
void *voidPtrToB = &b;

指针的声明


用以下代码声明指针。其中,&运算符被称为取地址运算符,它返回变量在内存中的地址。


void指针可以指向任意类型的值。

int a;
int *ptrToA = &a;
double b;
double *ptrToB = &b;
void *voidPtrToA = &a;
void *voidPtrToB = &b;

取地址运算符不能作用于常量或表达式,如 int *ptr = &2; 或者 int *ptr = &(a + b); 。因为他们在内存中并没有固定的地址。


空指针


空指针的值可以用 NULL (C和C++98的风格)或者 nullptr (C++11新标准)表示。他们的值都是0x0,表示指针不指向任何对象。


空指针不可以解引用,对其解引用会出现运行时错误(Runtime Error)。


NULL的定义:


//cite from <stddef.h>
#ifndef __cplusplus
#define NULL ((void *)0) // C语言
#else
#define NULL 0 // C++
#endif

可以发现,C语言的NULL保证为 void* 类型,但C++的NULL仅为常量 0。在C++中使用NULL宏可能会导致函数重载错误。相比之下, C++11引入的 nullptr 始终保证其为指针类型。


在C++代码中,建议使用 nullptr。


image.png


知识点


指针赋值


使用指针时,假设 ptr 为一个指针。


ptr 的值为指针本身的值,是一个十六进制地址;

同类型的指针之间可以赋值,如 ptr1 = ptr2,赋值相当于改变了指针指向的对象。

间接访问


为了访问指针指向的值,我们使用 * 符号,这被称为解引用运算符:


*ptr 的值为指针指向的变量的值;

对 *ptr 的修改会作用到原对象上。

注意声明int *ptr = &a; 中的 * 并不是解引用运算符,它是类型声明的一部分。(非常非常非常重要的一句话,让我搞错了好长时间)


void类型


void* 指针可以指向任何类型的值。


void* 类型不可以解引用。


事实上,使用 void* 代表着你放弃了所有类型检查和类型安全性。因此,除非必要,不建议在C++代码中使用 void* 类型。此后我们会学到处理任意类型更强大、安全的工具:模板。


我们看一下以下代码的运行结果,加深一下理解:


int a = 233;
int *ptrToA = &a;
void *voidPtrToA = &a;
cout << *ptrToA << endl; // 233
cout << ptrToA << endl; //一个十六进制数,表示内存中的位置。例如0x7ffd99314e64
*ptrToA = 466;
cout << a << endl; // 466
*voidPtrToA = 699; // Compile Error: ‘void*’ is not a pointer-to-object type
int c = 1, *ptrToC = &c;
ptrToA = ptrToC; // 现在ptrToA指向了变量c
reinterpret_cast


对于一个指向类型 A 的指针,我们可以将其转换成一个指向类型 B 的指针。此时,指针指向的位置没有变,只是对于内存中数据的解释方式变了。


转换的方式便是 B *ptr2 = reinterpret_cast<B *> ptr1;。


如以下代码,表示用一个 float 指针解释一个内存中的 int 变量:


int x = 1;

float *fp = reinterpret_cast<float *> &x;

要注意的是转换后的类型,它的有效长度不能比原来的类型更长。比如说 int 类型为 4 byte,double 类型为 8 byte。将一个指向 int 类型的指针转换成指向 double 类型的指针,这在语法上没有问题,但是如果解引用得到的指针,double 多出的 4 byte 的数据是无意义的。



image.png



image.png

image.png


相关文章
|
1月前
|
编译器 C++
C++ 双冒号::开头的语法,::变量名,获取全局作用域变量
C++ 双冒号::开头的语法,::变量名,获取全局作用域变量
17 0
|
1月前
|
存储 编译器 Shell
【C++基础语法 枚举】解析 C/C++ 中枚举类型大小值
【C++基础语法 枚举】解析 C/C++ 中枚举类型大小值
14 0
|
1月前
|
编译器 C++
c++基本语法
c++基本语法
19 1
|
1月前
|
编译器 C++
|
1月前
|
安全 算法 编译器
【C++基础语法 枚举】C/C++ 中enum枚举量的介绍:介绍enum枚举量在C/C中的作用和使用方法
【C++基础语法 枚举】C/C++ 中enum枚举量的介绍:介绍enum枚举量在C/C中的作用和使用方法
32 2
|
4月前
|
存储 编译器 C语言
C++入门第二篇---类和对象【1】&&C++语法细节补充
C++入门第二篇---类和对象【1】&&C++语法细节补充
41 0
|
5月前
|
Linux C++
63 C++ - 异常语法
63 C++ - 异常语法
23 0
|
6月前
|
C++
C++语言学习基本语法应用案例
C++语言学习基本语法应用案例
|
6月前
|
编译器 C++
C++ 基础篇之基本语法解析
C++ 基础篇之基本语法解析
|
1月前
|
编译器 测试技术 C++
【Python 基础教程 01 全面介绍】 Python编程基础全攻略:一文掌握Python语法精髓,从C/C++ 角度学习Python的差异
【Python 基础教程 01 全面介绍】 Python编程基础全攻略:一文掌握Python语法精髓,从C/C++ 角度学习Python的差异
164 0

热门文章

最新文章