C 语言指针

2025年6月29日 | 阅读11分钟

在 C 语言编程中,指针是一种用于存储另一个变量地址的变量。此变量可以是 int、char、数组、函数或任何其他指针类型。它使我们能够在不使用其变量的情况下操作存储在特定内存位置的数据。指针的大小取决于体系结构。然而,在 32 位体系结构中,指针的大小为 2 字节。地址的符号由指针 (*) 星号符号表示。

语法

它具有以下语法:

在这个语法中,

  • data_type: 它表示指针指向的数据类型。
  • var_name: 它表示指针的名称。

请看以下示例,定义一个存储整数地址的指针。

声明指针

C 语言中的指针可以使用 *(星号符号)声明。它也被称为间接指针,用于解引用指针。

访问指针的地址

在 C++ 中,使用指针访问地址是一个基本概念,它能够实现高效的内存操作和动态数据结构,例如数组、链表、树等。地址运算符 (&) 主要用于存储变量的地址。之后,可以将此地址分配给指针的变量以对其进行初始化。

解引用指针

访问指针本身只会向我们提供指针中包含的地址。例如,

示例

编译并运行

输出

Value of num using pointer: 42
New value of num after dereferencing: 28

说明

在此示例中,我们声明一个整数 num,其值为 42,以及一个包含其地址的指针 ptr。之后,它通过指针 (*ptr) 打印 num 的值,通过解引用将 num 的值更改为 28,并打印新值。

我们需要首先解引用指针以访问内存地址中包含的值。这在解引用运算符 (*) 的帮助下实现。

C 语言另一个指针示例

让我们再举一个例子来说明 C 语言中的指针。

示例

编译并运行

输出

Address of p variable is d86801c 
Value of p variable is 50

说明

在此程序中,指针 p 主要用于存储变量 number 的地址。之后,*p 解引用指针以访问存储在该地址的值。最后,它使用指针打印 number 的地址和值。

指向数组的指针

在 C 语言编程中,指向数组的指针是一种用于存储数组第一个元素地址的指针。它可以使用指针算术来访问和操作数组元素。

C 语言指向数组的指针示例

让我们举一个例子来说明 C 语言中指向数组的指针。

示例

编译并运行

输出

First element: 10
Second element: 20

说明

在此示例中,我们定义了一个整数数组和一个指向整个数组的指针 ptr。之后,它通过 (*ptr)[index] 打印和访问元素。

指向函数的指针

在 C 语言编程中,指向函数的指针用于存储函数的地址。它允许我们间接调用函数。它对于回调、动态函数调用和将函数作为参数传递非常有用。

语法

它具有以下语法:

C 语言指向函数的指针示例

让我们举一个例子来说明 C 语言中指向函数的指针。

示例

编译并运行

输出

Result: 10

说明

在此示例中,我们声明一个函数 add 并通过函数指针 functor 调用它。之后,指针存储 add 的地址,并通过指针调用函数。

指向结构的指针

在 C 语言编程中,指向结构的指针使我们能够通过动态内存访问结构成员。它主要用于动态数据结构,例如树、链表等等。

语法

它具有以下语法:

C 语言指向结构的指针示例

让我们举一个例子来说明 C 语言中指向结构的指针。

示例

编译并运行

输出

Name: Johnty
Age: 20

说明

在此示例中,我们声明一个结构 Student 和一个变量 s1。之后,指针 ptr 被赋予 s1 的地址,并通过 ptr->name 和 ptr->age 访问结构的成员以显示值。

指针的大小

C 语言中指针的长度随机器的体系结构(位系统)而变化,而不是它指向的内容。

  • 在 32 位系统上,所有指针通常使用 4 字节。
  • 在 64 位机器上,所有指针通常占用 8 字节。

即使数据类型(int*、char*、float* 等)发生变化,大小也不会改变。我们可以使用 sizeof 运算符来检查它。

空间量相同的原因是指针保存内存地址,而不管其类型如何。由于存储不同内存位置地址所占用的空间保持不变,因此一种类型指针所占用的空间将与另一种类型指针所占用的空间相同。

指针大小示例

让我们举一个例子来说明 C 语言中指针的大小。

示例

编译并运行

输出

Size of int pointer: 8 bytes
Size of float pointer: 8 bytes
Size of char pointer: 8 bytes
Size of double pointer: 8 bytes

说明

在此示例中,我们声明了各种数据类型的指针,并使用 sizeof 打印它们的大小。之后,它表明指针大小是系统相关的,无论它指向的类型如何。

地址 (&) 运算符

地址运算符 '&' 返回变量的地址。但是,我们需要使用 %u 来显示变量的地址。

C 语言地址 (&) 运算符示例

让我们举一个例子来说明 C 语言中的地址 (&) 运算符。

示例

编译并运行

输出

value of number is 50, address of number is 2617052868

特殊类型的指针

有 4 种特殊指针类型在各种上下文中被使用或提及

1) 空指针

在 C 语言编程中,未分配任何值但为 NULL 的指针被称为空指针。如果在声明时我们没有要指定的地址,我们可以分配一个 NULL 值。这将提供一种更好的方法。

语法

它具有以下语法:

在大多数库中,指针的值为 0(零)。

2) void 指针

在 C 语言编程中,void 指针是指不包含任何与之关联的数据类型的指针。它们也称为通用指针,因为它们可以用于指向任何类型并可以转换为任何类型。

C 语言 void 指针示例

让我们举一个例子来说明 C 语言中的 void 指针。

示例

编译并运行

输出

Value of a using void pointer: 21
Value of b using void pointer: 3.74

说明

在此示例中,我们使用 void 指针 ptr 存储一个整数的地址,然后存储一个浮点数的地址,然后将指针转换为适当的类型以解引用并打印 a 和 b 的值。

3) 野指针

在 C 语言编程中,野指针是指那些尚未初始化或分配任何值的指针。这些类型的 C 语言指针会使我们的程序变得困难,并最终导致程序崩溃。如果值通过野指针更改,它们可能会导致数据中止或数据损坏。

4) 悬空指针

在 C 语言编程中,引用已释放(或空闲)内存位置的指针被称为悬空指针。这种情况可能导致未定义的程序行为,也可能是 C 程序中错误的原因。

C 语言悬空指针示例

让我们举一个例子来说明 C 语言中的悬空指针。

示例

编译并运行

输出

Value: 50
Memory has been freed

说明

在此示例中,我们为整数动态分配内存,为其赋值,打印该值,然后释放内存。释放后,它还将指针设置为 NULL,使其不再是悬空指针。

如何使用指针进行动态内存分配

C 语言中指针最强大的应用之一是动态内存分配。它使我们能够在运行时而不是在编译期间分配内存。

我们使用 malloc 函数动态分配内存,它返回指向已分配内存的指针。例如

示例

编译并运行

输出

Enter the number of elements: 33 
Enter 3 integers:
95
32
16
The integers are:
95 32 16 

说明

在此示例中,我们通过指针和 malloc() 函数为整数数组动态分配内存空间。之后,它接受用户输入,打印用户输入的值,最后使用 free() 释放内存空间以防止内存泄漏。

C 语言指针算术

可以对指针进行的算术运算称为指针算术。它们与我们通常用于数学计算的运算不同,因为对指针可以进行的运算是有限的。这些运算包括

  • 增量/减量
  • 整数的加/减
  • 两个相同类型指针的相减
  • 比较/赋值两个相同类型指针
  • 与 NULL 比较/赋值

多级指针

在 C 语言中,我们可以创建任意数量级别的多级指针,例如 - ***ptr3、****ptr4、******ptr5 等。其中双指针(指向指针的指针)最常用。它存储另一个指针的内存地址。它们指向另一个指针,而不是指向数据值。

C 语言多级指针示例

让我们举一个例子来说明 C 语言中的多级指针。

示例

编译并运行

输出

Value of num: 100
Value using ptr1: 100
Value using ptr2: 100

说明

在此示例中,我们使用指针 ptr1 存储 num 的位置,并使用另一个指针 ptr2 存储 ptr1 的地址。之后,它直接打印 num 的值,通过 ptr1 间接打印,并通过双重解引用通过 ptr2 间接打印。

常量指针

在常量指针中,存储在指针中的内存地址是常量,并且在声明后无法更改。它将始终保存相同的内存地址。

C 语言常量指针示例

让我们举一个例子来说明 C 语言中的常量指针。

示例

编译并运行

输出

Value: 10
Updated Value: 15

说明

在此示例中,我们定义了一个指向整数 a 的常量指针 ptr。之后,它打印指向的值,使用 *ptr 更改该值,并输出新值。该指针不能重定向到另一个变量,例如 b,因此它将始终指向同一位置。

指针的优点

C 语言编程中有几个指针的优点。其中一些如下:

  • 在 C 语言编程中,指针减少了代码并提高了性能。它用于检索字符串、树等,并与数组、结构和函数一起使用。
  • 我们可以使用指针从函数返回多个值。
  • 它允许我们访问计算机内存中的任何内存位置。

指针程序在不使用第三个变量的情况下交换两个数字

让我们举一个例子,在 C 语言中不使用第三个变量来交换两个数字。

示例

编译并运行

输出

Before swap: *p1=10 *p2=20
After swap: *p1=20 *p2=10

指针的使用

C 语言中指针有许多应用。其中一些如下:

  • 动态内存分配: 在 C 语言中,我们可以使用 malloc() 和 calloc() 函数动态分配内存,其中使用了指针。
  • 数组、函数和结构: 指针广泛用于数组、函数和结构中。它减少了代码并提高了性能。

指针的问题

指针容易出错,并且存在以下缺点:

  • 如果将错误的值传递给指针,内存可能会损坏。
  • 指针学习起来稍微困难一些。
  • 指针是 C 语言中内存泄漏的主要原因。
  • 在 C 语言中,使用指针进行访问比使用变量相对较慢。
  • 未初始化的指针可能导致分段错误。

C 语言指针常见问题

1. C 语言中的指针是什么?

它是一个变量,保存另一个变量的内存位置。

2. 我们如何在 C 语言中声明和初始化指针?

int *ptr; 声明一个指向整数的指针。它用以下方式初始化:

3. * 运算符在指针中有什么作用?

它是解引用运算符,用于访问指针指向的地址处的值。

4. C 语言中 *ptr 和 &ptr 有什么区别?

*ptr 返回地址处的值,&ptr 返回指针的地址。

5. 指针可以指向另一个指针吗?

是的,它被称为指向指针的指针。

示例