C语言进阶教程(再论指针和数组(2))

简介: C语言进阶教程(再论指针和数组(2))

前言

本篇文章我们继续讲解指针和数组,因为指针和数组对于刚刚学习C语言或者是学习了不久C语言的同学都会造成一些困扰,所以这里多用几篇文章来帮助大家理解。


一、指针的加1减1运算

指针的加1减1运算是指针进行后移或前移一个元素的操作。对指针进行加减操作时,指针的值会根据指针所指向的数据类型的大小进行相应的增加或减少。

具体来说,假设 ptr 是一个指向某种数据类型(如整数、字符等)的指针,那么 ptr + 1 就会将指针的值增加一个元素大小的偏移量,使其指向下一个元素。相应地,ptr - 1 将指针的值减少一个元素大小的偏移量,使其指向上一个元素。

例如,考虑一个整型指针的例子:

int arr[5] = {1, 2, 3, 4, 5};
int* ptr = arr;
printf("%p\n", ptr);       // 输出 arr 的地址
printf("%p\n", ptr + 1);   // 输出 arr 的下一个元素的地址
printf("%p\n", ptr - 1);   // 输出 arr 的上一个元素的地址

输出结果:

0x7ffeed06b3b0
0x7ffeed06b3b4
0x7ffeed06b3ac

在这个例子中,ptr 指向数组 arr 的第一个元素。通过 ptr + 1,指针的值增加了一个整型数据的大小(通常是4个字节)的偏移量,指向了 arr 的下一个元素。相反,通过 ptr - 1,指针的值减少了一个整型数据的大小的偏移量,指向了 arr 的上一个元素。

需要注意的是,指针进行加减运算时,移动的距离取决于指针所指向的数据类型的大小。这保证了指针正确地指向连续的内存位置。此外,指针运算也受限于有效的内存边界,不应越界访问或指向无效的内存位置。

二、指针的减法运算

指针的减法运算用于计算两个指针之间的偏移量(以元素个数为单位)。它可用于确定两个指针之间的元素数量或计算指针相对于基准指针的偏移量。

假设我们有两个指针 ptr1 和 ptr2,它们指向同一类型的元素。可以使用减法运算符 - 计算它们之间的差值,并得到它们之间元素的个数。

例如,考虑以下示例,其中 ptr1 和 ptr2 是指向整型数组中的不同元素的指针:

int arr[5] = {1, 2, 3, 4, 5};
int* ptr1 = &arr[2];
int* ptr2 = &arr[0];
ptrdiff_t diff = ptr1 - ptr2;
printf("Elements between ptr1 and ptr2: %td\n", diff);

输出结果:

Elements between ptr1 and ptr2: 2

在这个例子中,ptr1 指向数组 arr 的第3个元素(值为3),而 ptr2 指向数组 arr 的第1个元素(值为1)。通过 ptr1 - ptr2 计算两个指针之间的偏移量,得到结果为2,表示 ptr1 与 ptr2 之间有2个元素。

需要注意的是,减法运算的结果的类型是 ptrdiff_t,它是 stddef.h 头文件中定义的整数类型。它根据平台的位数和编译器的实现可能有所不同。因此,在打印结果时,可以使用 %td 格式说明符来匹配 ptrdiff_t 类型的值。

此外,减法运算也可用于计算指针相对于基准指针的偏移量。通过将一个指针减去另一个指针,可以获得它们之间的偏移量,以字节数为单位。这对于在数组或缓冲区中位置计算非常有用。

注意:

1.只有当两个指针指向同一个数组中的元素时,指针相减才有意义,其意义为指针所指元素下标差。

2.当两个指针指向的元素不在同一个数组中时,结果未定义。


三、指针的关系运算

指针的关系运算符用于比较指针的大小关系,判断它们在内存中的相对位置。以下是指针的关系运算符及其示例用法:

大于运算符 (>):用于比较两个指针的大小,如果左侧指针指向的地址在内存中比右侧指针的地址大,则关系表达式的结果为真。

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    int* ptr1 = arr[0];
    int* ptr2 = arr[2];
    if (ptr2 > ptr1) {
        printf("ptr2 is greater than ptr1.\n");
    } else {
        printf("ptr2 is not greater than ptr1.\n");
    }
    return 0;
}

输出结果:

ptr2 is greater than ptr1.

在这个例子中,我们定义了一个整型数组arr,并使用指针ptr1和ptr2分别指向数组的不同元素。通过使用大于运算符(>)比较ptr2和ptr1,我们可以判断ptr2指向的地址是否在ptr1指向的地址之后。

小于运算符 (<):用于比较两个指针的大小,如果左侧指针指向的地址在内存中比右侧指针的地址小,则关系表达式的结果为真。针对上述示例进行修改:

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    int* ptr1 = arr[2];
    int* ptr2 = arr[4];
    if (ptr1 < ptr2) {
        printf("ptr1 is less than ptr2.\n");
    } else {
        printf("ptr1 is not less than ptr2.\n");
    }
    return 0;
}

输出结果:

ptr1 is less than ptr2.

在这个例子中,我们修改了指针ptr1和ptr2分别指向了数组arr的不同元素。通过使用小于运算符(<)比较ptr1和ptr2,我们可以判断ptr1指向的地址是否在ptr2指向的地址之前。

需要注意的是,指针的关系运算符只能用于两个指针之间的比较,不能用于指针和其他类型的变量之间的比较。此外,比较时需要确保两个指针指向相同的数组或在相同的内存块中,否则结果可能是未定义的。


四、指针比较运算

指针的比较运算可以用于判断两个指针是否指向同一个对象或确定它们在内存中的相对位置。以下是一个示例,展示了指针比较运算的用法:

#include <stdio.h>
int main() {
    int var1 = 5;
    int var2 = 10;
    int* ptr1 = &var1;
    int* ptr2 = &var2;
    int* ptr3 = &var1;
    // 比较ptr1和ptr2
    if (ptr1 == ptr2) {
        printf("ptr1 and ptr2 point to the same location.\n");
    } else {
        printf("ptr1 and ptr2 point to different locations.\n");
    }
    // 比较ptr1和ptr3
    if (ptr1 == ptr3) {
        printf("ptr1 and ptr3 point to the same location.\n");
    } else {
        printf("ptr1 and ptr3 point to different locations.\n");
    }
    return 0;
}

输出结果:

ptr1 and ptr2 point to different locations.
ptr1 and ptr3 point to the same location.

在这个例子中,我们定义了两个整数变量var1和var2,并使用指针ptr1、ptr2和ptr3分别指向它们。通过使用相等运算符==来比较指针,我们可以判断指针是否指向相同的内存位置。

在第一个比较中,ptr1和ptr2指向不同的变量var1和var2,因此输出是"ptr1 and ptr2 point to different locations."。

在第二个比较中,ptr1和ptr3都指向同一个变量var1,因此输出是"ptr1 and ptr3 point to the same location."。

需要注意的是,指针比较运算只比较指针的值,即它们所指向的内存地址。它们并不比较指针所指向的对象的值。如果需要比较指针所指向对象的值,应该使用间接引用运算符*来获取指针所指向的对象的值,并进行比较。


总结

本篇文章我们主要就是讲解了指针的运算,这些大家必须牢牢掌握。


相关文章
|
22天前
|
存储 NoSQL 编译器
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
指针是一个变量,它存储另一个变量的内存地址。换句话说,指针“指向”存储在内存中的某个数据。
74 3
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
|
22天前
|
存储 编译器 C语言
【C语言】指针大小知多少 ?一场探寻C语言深处的冒险 !
在C语言中,指针的大小(即指针变量占用的内存大小)是由计算机的体系结构(例如32位还是64位)和编译器决定的。
47 9
|
22天前
|
安全 程序员 C语言
【C语言】指针的爱恨纠葛:常量指针vs指向常量的指针
在C语言中,“常量指针”和“指向常量的指针”是两个重要的指针概念。它们在控制指针的行为和数据的可修改性方面发挥着关键作用。理解这两个概念有助于编写更安全、有效的代码。本文将深入探讨这两个概念,包括定义、语法、实际应用、复杂示例、最佳实践以及常见问题。
41 7
|
22天前
|
传感器 算法 安全
【C语言】两个数组比较详解
比较两个数组在C语言中有多种实现方法,选择合适的方法取决于具体的应用场景和性能要求。从逐元素比较到使用`memcmp`函数,再到指针优化,每种方法都有其优点和适用范围。在嵌入式系统中,考虑性能和资源限制尤为重要。通过合理选择和优化,可以有效提高程序的运行效率和可靠性。
70 6
|
25天前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
49 5
|
25天前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
25天前
|
算法 C语言
C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项
本文深入讲解了C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项,通过实例演示了文件操作的基本流程,帮助读者掌握这一重要技能,提升程序开发能力。
86 3
|
26天前
|
存储 算法 程序员
C 语言指针详解 —— 内存操控的魔法棒
《C 语言指针详解》深入浅出地讲解了指针的概念、使用方法及其在内存操作中的重要作用,被誉为程序员手中的“内存操控魔法棒”。本书适合C语言初学者及希望深化理解指针机制的开发者阅读。
|
25天前
|
程序员 C语言
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门。本文深入探讨了指针的基本概念、声明方式、动态内存分配、函数参数传递、指针运算及与数组和函数的关系,强调了正确使用指针的重要性,并鼓励读者通过实践掌握这一关键技能。
36 1
|
29天前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。