C++ 指针详讲、指针与数组联系与区别

简介: 介绍指针概念之前,需要了解在计算机程序存储数据时必须跟踪的三基本属性:

介绍指针概念之前,需要了解在计算机程序存储数据时必须跟踪的三基本属性:

  • 信息存储在何处,也就是地址;
  • 存储的值为多少,简称值;
  • 存储的信息是什么类型,简称类型;


1,地址运算符&

在常规变量定义时,寻找变量的 类型 很方便,如果想知道存储变量的 地址(也就是内存区),这时就需要用到地址运算符 &

int main()
{
  int a = 3;
  int b = 4;
  cout << "变量 a 的地址为 " << (&a) << endl;
  cout << "变量 b 的地址为 " << (&b) << endl;
  return 0;
}

这里定义了两个 整形变量a、b,;后面加上 & 地址运算符,在调试台打分别印出变量 a,b 变量的存储地址;

由上面结果可知,显示地址时用的是十六进制表示法,变量 a 和 b 之间相差 4 (即四个字节),是由于 a,b 同为 int 类型;


2,指针的定义和用法

指针是一种特殊类型的变量,用于存储值的地址,指针名即为地址, *****运算符被称为间接值或接触引用运算符,该运算符应用于指针上,就得到该地址处存储的值;

在下面例子中,我用 int* 声明了一个指针变量 p 和一个 int 变量 b(复制为 4) ;并将 p 指向了 b

  • 变量地址可用两种方式表示,p 和 &b;


  • 变量值也同样由两种方式表示,*p 和 b;


int main()
{
  int* p;//定义一个指针p 类型为 int;
  int b = 4;
  p = &b;//将 p 指向 b;
  cout << "变量 b 的地址为 " << p << endl;
  cout << "变量 b 的地址为 " << (&b) << endl;
  cout << "变量 b 的值为" << b << endl;
  cout << "变量 b 的值为" << *p << endl; // *p 表示指针p中存储的值;
  return 0;
}

结果如下:


声明指针方式如下,这里的 typename 可替换为 int、char、double,表示指针指向的类型

typename* p;// typename 表示类型,p表示变量;


也可以在声明的同时进行初始化,需要注意的是,被初始化的是指针,而不是指针指向的值;

int a =4;
int *pt =&a;

使用指针时与使用常规变量有一个很大的不同点:使用常规变量时 ,值是指定的量,而地址是派生量。而在指针策略中,地址是指定量,而值为派生量;


指针的错误用法


在 C++ 创建指针时,计算机将会分配用来存储地址的内存,但不会分配用来存储指针所指向的数据的内存 ,为数据分配空间是一个独立的空间,不可省略,如下

int *pt;//定义一个指向 int 类型的指针 pt;
*pt = 23;// 错误,指针 pt 未指向任何地址,

在上面例子中,想把指针 pt 指向的值赋值为 23 ,但是这里的 pt 没有初始化,没有指向任何值,也就是说我们不知道 pt 指向哪里;如果直接把 23 赋给 *pt ,可能会造成一些最隐秘,难以跟踪的 bug;


所以需要谨记一点,在对指针应用解除引用运算符(*) 之前,将指针初始化为一个确定的,适当的地址


3,指针和数组


在 C 和 C++ 中,指针和数组基本等价,原因是在于指针算术和C++ 内部处理数组的方式;


正常整数变量加 1,则值加 1;


指针变量加 1 则即等于原来的地址值加指向对象所占用的总字节数(比如 double 类型加一需要增加 8 个字节),根据指向指向地址的变化,*p(指针指向的值) 也同样发生变化


指针与数组的关系


将一个数组名 arr 赋给一个指针 p 时 int *p = arr(类型是一致的) ,则代表指针 p 指向该数组第一个元素所在的地址 arr[0] p = arr[0]


当指针加1时,而指针指向的值为数组原来索引加 1 后所在的值 *(p+1) == arr[n+1],

例子如下,指针 p,q 初始化时分别指向 数组 arr[0] 和 arr;当 p,q 同时加 1 时,它们指向的值也未发生改变;

int main()
{
  int* p;//定义一个指针p 类型为 int;
  int *q;
  int b[2] = {3,4};
  p = &b[0];//将 p 指向 b;
  q = b;// 指针 q 指向数组 b 的第一个元素
  cout << "变量 p 的地址为 " << p << endl;
  cout << "指针变量 p 指向的值为 " << *p << endl;
  cout << endl;
  cout << "指针变量 q 指向的值为 " << *q << endl;
  cout << endl;
  cout << endl;
  cout << "变量 p+1 的地址为" << p+1 << endl;
  cout << "指针变量 p+1 指向的值为" << *(p+1) << endl; // *p 表示指针p中存储的值;
  cout << endl;
  cout << "指针变量 q+1 指向的值为" << *(q + 1) << endl; // *p 表示指针p中存储的值;
  return 0;
}


当 array 表示数组时,sizeof(array)可以测试出 array 数组大小,单位 字节;

array 为数组时,array + n 表示的是一个指向数组索引为 n-1 的指针,用 sizeof(array +n)指向指针类型大小;

int main()
{
  int* p;//定义一个指针p 类型为 int;
  int *q;
  int b[4] = {3,4,5,6};
  p = &b[0];//将 p 指向 b;
  q = b;// 指针 q 指向数组 b 的第一个元素
  cout << "数组 b 的大小为 " << sizeof(b) << endl;
  cout << "指针 b[1] 的大小 " << sizeof(b+1) << endl;
  cout << "指针 p+1 的大小 " << sizeof(p+1) << endl;
  return 0;
}

运行结果如下

相关文章
|
1月前
使用指针访问数组元素
【10月更文挑战第30天】使用指针访问数组元素。
34 3
|
17天前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。
|
17天前
|
容器
在使用指针数组进行动态内存分配时,如何避免内存泄漏
在使用指针数组进行动态内存分配时,避免内存泄漏的关键在于确保每个分配的内存块都能被正确释放。具体做法包括:1. 分配后立即检查是否成功;2. 使用完成后及时释放内存;3. 避免重复释放同一内存地址;4. 尽量使用智能指针或容器类管理内存。
|
20天前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
43 4
|
28天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
66 4
|
1月前
使用指针访问数组元素
【10月更文挑战第31天】使用指针访问数组元素。
38 2
|
2月前
|
存储 安全 编译器
在 C++中,引用和指针的区别
在C++中,引用和指针都是用于间接访问对象的工具,但它们有显著区别。引用是对象的别名,必须在定义时初始化且不可重新绑定;指针是一个变量,可以指向不同对象,也可为空。引用更安全,指针更灵活。
|
1月前
|
算法 索引
单链表题+数组题(快慢指针和左右指针)
单链表题+数组题(快慢指针和左右指针)
37 1
|
20天前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
81 12
|
2月前
|
C语言
无头链表二级指针方式实现(C语言描述)
本文介绍了如何在C语言中使用二级指针实现无头链表,并提供了创建节点、插入、删除、查找、销毁链表等操作的函数实现,以及一个示例程序来演示这些操作。
32 0