指针算术在C语言中允许对指针进行算术操作,如加法、减法等。然而,由于指针存储的是地址,如果与整数类型进行算术操作,那么操作的结果也将是一个指针。在指针减去指针的运算中,结果将是一个整数值。在C语言中,可以对指针执行以下算术操作:

  • 自增(Increment)
  • 自减(Decrement)
  • 加法(Addition)
  • 减法(Subtraction)
  • 比较(Comparison)

指针的自增(Incrementing Pointer)

如果将指针增加1,指针将开始指向下一个位置。这与一般的算术运算有些不同,因为指针的值将增加指针所指向的数据类型的大小。

我们可以通过在循环中使用指针的自增操作来遍历数组,使指针依次指向数组的每个元素,对其执行一些操作,并在循环中更新指针。

指针自增的规则如下:

新地址 = 当前地址 + i * 数据类型的大小

其中,i是指针增加的数量。

32位系统

对于32位整数变量,指针会增加2个字节。

64位系统

对于64位整数变量,指针会增加4个字节。

让我们看一个在64位系统上增加指针变量的示例。

cCopy code
#include <stdio.h>

int main(){
    int number = 50;
    int *p; // 指向int的指针
    p = &number; // 存储number变量的地址
    printf("p变量的地址为%u \n", p);
    p = p + 1;
    printf("自增后:p变量的地址为%u \n", p); // 在我们的例子中,p的地址将增加4个字节。
    return 0;
}

输出结果

cssCopy code
p变量的地址为3214864300 
自增后:p变量的地址为3214864304 

通过指针遍历数组

cCopy code
#include <stdio.h>

void main () {
   int arr[5] = {1, 2, 3, 4, 5};
   int *p = arr;
   int i;
   printf("打印数组元素...\n");
   for(i = 0; i < 5; i++) {
      printf("%d ", *(p + i));
   }
}

输出结果

Copy code
打印数组元素...
1  2  3  4  5

指针的自减(Decrementing Pointer)

与自增类似,我们也可以对指针进行自减操作。如果将指针减小1,指针将开始指向前一个位置。指针的自减公式如下:

  1. 新地址 = 当前地址 - i * 数据类型的大小

32位系统

对于32位整数变量,指针会减小2个字节。

64位系统

对于64位整数变量,指针会减小4个字节。

让我们看一个在64位操作系统上减小指针变量的示例。

cCopy code
#include <stdio.h>

void main() {
    int number = 50;
    int *p; // 指向int的指针
    p = &number; // 存储number变量的地址
    printf("p变量的地址为%u \n", p);
    p = p - 1;
    printf("自减后:p变量的地址为%u \n", p); // p现在指向了前一个位置。
}

输出结果

cssCopy code
p变量的地址为3214864300 
自减后:p变量的地址为3214864296 

C语言中的指针加法(Pointer Addition)

我们可以将一个值加到指针变量上。指针加法的公式如下:

  1. 新地址 = 当前地址 + (数字 * 数据类型的大小)

32位系统

对于32位整数变量,将增加2 * 数字。

64位系统

对于64位整数变量,将增加4 * 数字。

让我们看一个在64位架构上将值添加到指针变量的示例。

cCopy code
#include <stdio.h>

int main(){
    int number = 50;
    int *p; // 指向int的指针
    p = &number; // 存储number变量的地址
    printf("p变量的地址为%u \n", p);
    p = p + 3; // 将3添加到指针变量中
    printf("添加3后:p变量的地址为%u \n", p);
    return 0;
}

输出结果

cssCopy code
p变量的地址为3214864300 
添加3后:p变量的地址为3214864312

正如你可以看到的,p的地址是3214864300。但是在将3添加到p变量后,它变为3214864312,即增加了12个字节(4 3)。因为我们使用的是64位架构,所以增加了12个字节。但是,如果我们使用32位架构,它只会增加到6,即2 3 = 6。因为在32位操作系统中,整数值占用2个字节的内存。

C语言中的指针减法(Pointer Subtraction)

与指针加法类似,我们可以从指针变量中减去一个值。从指针中减去任意数字将得到一个地址。指针减法的公式如下:

  1. 新地址 = 当前地址 - (数字 * 数据类型的大小)

32位系统

对于32位整数变量,将减去2 * 数字。

64位系统

对于64位整数变量,将减去4 * 数字。

让我们看一个在64位架构上从指针变量中减去一个值的示例。

cCopy code
#include <stdio.h>

int main(){
    int number = 50;
    int *p; // 指向int的指针
    p = &number; // 存储number变量的地址
    printf("p变量的地址为%u \n", p);
    p = p - 3; // 从指针变量中减去3
    printf("减去3后:p变量的地址为%u \n", p);
    return 0;
}

输出结果

cssCopy code
p变量的地址为3214864300 
减去3后:p变量的地址为3214864288

你可以看到从指针变量中减去3后,它比之前的地址值小了12(4 * 3)。

然而,我们也可以从一个地址(指针)中减去另一个地址(指针)。这将得到一个数字,而不是简单的算术操作,但是它遵循以下规则。

如果两个指针具有相同的类型,

  1. 地址2 - 地址1 = (两个地址的差)/指针指向的数据类型的大小

考虑以下示例来减去一个指针从另一个指针。

cCopy code
#include <stdio.h>

void main () {
    int i = 100;
    int *p = &i;
    int *temp;
    temp = p;
    p = p + 3;
    printf("指针减法:%d - %d = %d", p, temp, p-temp);
}

输出结果

Copy code
指针减法:1030585080 - 1030585068 = 3

非法的指针运算

有一些无法对指针执行的操作。由于指针存储地址,因此我们必须忽略可能导致非法地址的操作,例如加法和乘法。以下是此类操作的列表。

  • 地址 + 地址 = 非法
  • 地址 * 地址 = 非法
  • 地址 % 地址 = 非法
  • 地址 / 地址 = 非法
  • 地址 & 地址 = 非法
  • 地址 ^ 地址 = 非法
  • 地址 | 地址 = 非法
  • ~地址 = 非法

C语言中的函数指针(Pointer to Function)

正如我们在之前的章节中讨论的,指针可以指向C语言中的函数。但是,指针变量的声明必须与函数相同。考虑以下示例,使指针指向函数。

cCopy code
#include <stdio.h>

int addition();
int main() {
    int result;
    int (*ptr)();
    ptr = &addition;
    result = (*ptr)();
    printf("和为 %d", result);
}
int addition() {
    int a, b;
    printf("输入两个数字?");
    scanf("%d %d", &a, &b);
    return a + b;
}

输出结果

Copy code
输入两个数字?3 5
和为 8

在上面的示例中,我们声明了一个名为addition的函数。然后,我们声明了一个指针变量ptr,它指向与addition函数相同类型的函数。我们使用&additionptr指向addition函数的地址。然后,我们通过在ptr前加上*来调用addition函数,并将其结果存储在result变量中。最后,我们使用printf语句打印出结果。

标签: c语言, c语言教程, c语言技术, c语言学习, c语言学习教程, c语言下载, c语言开发, c语言入门教程, c语言进阶教程, c语言高级教程, c语言面试题, c语言笔试题, c语言编程思想