c语言的指针(基础解释)

一、前言

​ C语言可以说是变成重要的一个语言,本人机械专业,因为电子方面的学习(单片机)接触C语言。刚开始我只是通过学习51单片机的方式来学C语言,但是学的云里雾里。所以决定系统的全方位的重新学习,现在只能说略微理解,所以本篇文章多有不足之处,可以反馈到我个人微信公众号上(夙夜凌风碎碎念),进行交流学习。

二、基础篇

1、指针的定义

​ 在计算机编程中,尤其是像C、C++这样的语言中,指针是一种特殊的变量,它的值是另一个变量的内存地址。这个内存地址指向了存储在内存中的数据。更具体地说,一个指针变量能够存储并提供对其他变量或对象的间接访问。指针声明的一般形式如下:

datatype *pointer_name;

这里的 datatype 表示指针所指向的数据类型,* 是指针运算符,它表明这是一个指针变量,而不是普通变量,而 pointer_name 是你为指针变量指定的名称。

2、指针的用途

2.1、动态内存分配

通过使用指针和malloc(), calloc(), realloc()以及free()等函数,程序员可以在程序运行时动态地申请和释放内存空间。这对于创建不确定大小的数据结构(如链表、树、图等)或者处理大数据量尤为关键。

2.2、数据访问和修改

指针可以用来间接访问和修改变量的值。例如,在数组中,可以通过指针遍历元素并进行操作,无需知道数组的确切下标。另外,函数可以通过指针参数修改调用者提供的变量值,实现“传址”调用。

2.3、提高效率

在某些情况下,直接使用指针比复制大块数据更高效。特别是在处理大型数据结构时,传递指向数据的指针要比复制整个数据结构节省时间和空间。

2.4、函数间数据共享

指针常用于实现场景如回调函数、函数指针表等,使得多个函数能够共享同一份数据或执行代码。

2.5、高级抽象

在C++等语言中,指针是实现许多高级特性(如面向对象编程中的虚函数、继承、多态)的基础。

2.6、系统级编程和硬件交互

在底层编程、设备驱动开发等领域,指针常被用于直接操作内存地址和硬件寄存器,实现对硬件资源的直接控制。

3、个人理解

​ 我个人理解指针其实就是内存的表现形式,在编程中,指针是一种变量,其值存储的是内存地址。这个内存地址指向了计算机内存中的某个数据对象(如变量、数组元素、结构体等)。通过操作这个内存地址,程序可以直接访问和修改内存中对应位置的数据。

​ 当我们说“指针就是内存地址”时,我们强调的是指针变量所存储的内容——一个能够指示内存中特定位置的地址。

​ 例如:

#include <iostream>

// 定义一个函数,它接收一个整型指针参数并修改其指向的数组内容
void modifyArray(int* arr, int size) {
for (int i = 0; i < size; ++i) {
arr[i] *= 2; // 将数组中的每个元素都翻倍
}
}

int main() {
// 动态分配一个包含5个整数的数组
int size = 5;
int* dynamicArray = new int[size];

// 初始化数组
for (int i = 0; i < size; ++i) {
dynamicArray[i] = i + 1; // 假设为1到5的序列
std::cout << "dynamicArray[" << i << "] = " << dynamicArray[i] << std::endl;
}

// 使用指针将数组传递给函数进行修改
modifyArray(dynamicArray, size);

// 输出修改后的数组
std::cout << "\nAfter modifying through the function:\n";
for (int i = 0; i < size; ++i) {
std::cout << "dynamicArray[" << i << "] = " << dynamicArray[i] << std::endl;
}

// 释放动态分配的内存
delete[] dynamicArray;

return 0;
}

在这个例子中:

​ 在这个例子中:

  • dynamicArray 是一个指针,它存储了新分配的内存区域的地址。
  • new int[size] 用于动态分配一个整型数组,并返回该数组首元素的地址。
  • modifyArray 函数接收一个整型指针和数组大小作为参数,它直接操作指针指向的内存,而无需拷贝数组内容。
  • 在主函数中,我们通过指针修改了数组的内容,然后输出结果验证修改成功。
  • 最后,使用 delete[] dynamicArray 删除先前分配的内存,防止内存泄漏

​ 这个例子有点迷离(书上抄的),我以下面的代码解释

int*()

这个指针(这个是俺自己写的)

int main() {
int a = 5; // 创建并初始化一个整数变量a
int *p = &a; // 创建一个指向整数的指针p,并将其初始化为变量a的地址

// 在内存中的表示形式(非实际截图)
+--------+ +-------+
| a | --> | 5 |
+--------+ +-------+
^
|
+--------v-------+
| p |
+----------------+
|
+-- (例如: 0x1234) -- 地址值

​ 首先,变量 a 存储了整数值5,在内存中分配了一个空间用于存储这个值。然后,指针变量 p 存储的是变量 a 的内存地址,而不是其内容。再然后图中箭头表示了从指针到它所指向的实际数据的引用关系。所以当执行 *p 这样的操作时,编译器会解引用指针 p 并返回它所指向的内存地址处的内容,即变量 a 的值5。而 & 符号则是取地址运算符,用于获取变量的内存地址。

三、尾声

​ 作为一名机电专业的学生,我深刻认识到在当今科技日新月异的时代,掌握编程技能对于拓宽专业视野、提升创新能力的重要性。因此,尽管身处非计算机科学的专业领域,我正积极投入时间和精力去学习编程知识,并力求将其与机电专业知识相结合,以期在未来能够实现更高效、智能化的系统设计与应用。

​ 在这个求知的过程中,我不断深入探究C、C++等编程语言的核心概念和实践技巧,如指针的使用、数据结构的理解以及内存管理等关键环节。然而,面对编程世界的广阔无垠,深知自己的知识体系尚待完善,亟需得到资深专家及同行大牛的点拨指导,以便更好地梳理和完善个人的知识架构。

​ 出于对知识的渴望,我在此写下这篇博客,旨在分享我的学习历程与思考,同时也期待能与志同道合的朋友进行交流探讨,共享彼此的经验与心得。在编程的道路上,“路漫漫其修远兮,吾将上下而求索”,我将持续不懈地追求进步,砥砺前行,怀揣着探索未知的热情,共同在这条充满挑战又富有机遇的学习之旅中携手并进。