C语言教程-C语言中的指针运算

指针算术在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,指针将开始指向前一个位置。指针的自减公式如下:
- 新地址 = 当前地址 - 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)
我们可以将一个值加到指针变量上。指针加法的公式如下:
- 新地址 = 当前地址 + (数字 * 数据类型的大小)
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)
与指针加法类似,我们可以从指针变量中减去一个值。从指针中减去任意数字将得到一个地址。指针减法的公式如下:
- 新地址 = 当前地址 - (数字 * 数据类型的大小)
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)。
然而,我们也可以从一个地址(指针)中减去另一个地址(指针)。这将得到一个数字,而不是简单的算术操作,但是它遵循以下规则。
如果两个指针具有相同的类型,
- 地址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
函数相同类型的函数。我们使用&addition
将ptr
指向addition
函数的地址。然后,我们通过在ptr
前加上*
来调用addition
函数,并将其结果存储在result
变量中。最后,我们使用printf
语句打印出结果。