Cprogramming 简明教程
Pointer Arithmetics in C
C 中的 pointer 变量存储另一个变量的地址。地址始终是整数。那么,我们可以在指针上执行加法和减法等算数运算吗?在本章中,我们将解释哪些算数运算符在 C 中使用指针作为操作数,以及哪些运算没有定义可在指针上执行。
A pointer variable in C stores the address of another variable. The address is always an integer. So, can we perform arithmetic operations such as addition and subtraction on the pointers? In this chapter, we will explain which arithmetic operators use pointers in C as operands, and which operations are not defined to be performed with pointers.
C pointers arithmetic operations 不同于一般的算术运算。以下是在 C 中的一些重要的指针算数运算:
C pointers arithmetic operations are different from the general arithmetic operations. The following are some of the important pointer arithmetic operations in C:
-
Increment and Decrement of a Pointer
-
Addition and Subtraction of Integer to Pointer
-
Subtraction of Pointers
-
Comparison of Pointers
让我们借助示例详细讨论所有这些指针算术运算。
Let us discuss all these pointer arithmetic operations in detail with the help of examples.
Increment and Decrement of a Pointer
我们知道"++"和"--"用作 increment and decrement operators in C 。它们是一元运算符,以前缀或后缀方式与数字 variable 操作数一起使用,它们将变量的值增加或减少一。
We know that "++" and "--" are used as the increment and decrement operators in C. They are unary operators, used in prefix or postfix manner with numeric variable operands, and they increment or decrement the value of the variable by one.
假设在内存中地址为1000处创建了一个整数变量"x",其值为10。那么,"x++"会使"x"的值变为11。
Assume that an integer variable "x" is created at address 1000 in the memory, with 10 as its value. Then, "x++" makes the value of "x" as 11.
int x = 10; // created at address 1000
x++; // x becomes 11
如果我们声明"y"为"x"的指针,并将"y"按1 (使用"y++")增加,会发生什么?假定"y"本身的地址为2000。
What happens if we declare "y" as pointer to "x" and increment "y" by 1 (with "y++")? Assume that the address of "y" itself is 2000.
int x = 10; // created at address 1000
// "y" is created at address 2000
// it holds 1000 (address of "x")
int *y = &x ;
y++; // y becomes 1004
由于变量"y"存储1000("x"的地址),因此我们希望因"++"运算符而变为1001,但它却增加了4,这是"int"变量的大小。
Since the variable "y" stores 1000 (the address of "x"), we expect it to become 1001 because of the "++" operator, but it increments by 4, which is the size of "int" variable.
之所以出现这种情况,是因为如果"x"的地址为1000,那么它将占据4个字节:1000、1001、1002和1003。因此,下一个整数只能放在1004中,不能放在它之前。因此,当"y"("x"的指针)增加时变为1004。
The is why because, if the address of "x" is 1000, then it occupies 4 bytes: 1000, 1001, 1002 and 1003. Hence, the next integer can be put only in 1004 and not before it. Hence "y" (the pointer to "x") becomes 1004 when incremented.
Example of Incrementing a Pointer
以下示例显示了如何增加一个指针的值 −
The following example shows how you can increment a pointer −
#include <stdio.h>
int main(){
int x = 10;
int *y = &x;
printf("Value of y before increment: %d\n", y);
y++;
printf("Value of y after increment: %d", y);
}
运行代码并检查其输出:
Run the code and check its output −
Value of y before increment: 6422036
Value of y after increment: 6422040
可以看到,该值增加了4。同样,"--"运算符将值减小数据类型的字节数。
You can see that the value has increased by 4. Similarly, the "--" operator decrements the value by the size of the data type.
Example of Decrementing a Pointer
让我们将"x"和"y"的类型更改为"double"和"float",看看减号运算符的效果。
Let us change the types of "x" and "y" to "double" and "float" and see the effect of decrement operator.
#include <stdio.h>
int main(){
double x = 10;
double *y = &x;
printf("value of y before decrement: %ld\n", y);
y--;
printf("value of y after decrement: %ld", y);
}
Value of y before decrement: 6422032
Value of y after decrement: 6422024
声明一个 array 时,元素存储在相邻的内存位置中。在"int"数组的情况下,每个数组下标都相隔4个字节,如下图所示 −
When an array is declared, the elements are stored in adjacent memory locations. In case of "int" array, each array subscript is placed apart by 4 bytes, as the following figure shows −
因此,如果一个变量存储数组第0个元素的地址,那么"增量"会将其移至第1个元素。
Hence, if a variable stores the address of 0th element of the array, then the "increment" takes it to the 1st element.
Example of Traversing an Array by Incrementing Pointer
以下示例显示了如何通过连续增加指针的值来遍历数组 −
The following example shows how you can traverse an array by incrementing a pointer successively −
#include <stdio.h>
int main(){
int a[]= {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
int len = sizeof(a)/sizeof(int);
int *x = a;
int i = 0;
for(i = 0; i < len; i++){
printf("Address of subscript %d = %d Value = %d\n", i, x, *x);
x++;
}
return 0;
}
运行代码并检查其输出:
Run the code and check its output −
Address of subscript 0 = 6421984 Value = 10
Address of subscript 1 = 6421988 Value = 20
Address of subscript 2 = 6421992 Value = 30
Address of subscript 3 = 6421996 Value = 40
Address of subscript 4 = 6422000 Value = 50
Address of subscript 5 = 6422004 Value = 60
Address of subscript 6 = 6422008 Value = 70
Address of subscript 7 = 6422012 Value = 80
Address of subscript 8 = 6422016 Value = 90
Address of subscript 9 = 6422020 Value = 100
Addition and Subtraction of Integer to Pointer
可以对指针进行整数加减运算。当将一个整数添加到指针时,指针将指向下一个内存地址。同样,当从指针中减去一个整数时,指针将指向前一个内存位置。
An integer value can be added and subtracted to a pointer. When an integer is added to a pointer, the pointer points to the next memory address. Similarly, when an integer is subtracted from a pointer, the pointer points to the previous memory location.
将一个整数加减到指针中不会将该值加减到指针中,而是将与数据类型的大小相乘的值加减到指针中。
Addition and subtraction of an integer to a pointer does not add and subtract that value to the pointer, multiplication with the size of the data type is added or subtracted to the pointer.
例如,有一个整数指针变量ptr,它指向地址123400,如果向ptr添加1 (ptr+1),它将指向地址123404(整数的大小为4)。
For example, there is an integer pointer variable ptr and it is pointing to an address 123400, if you add 1 to the ptr (ptr+1), it will point to the address 123404 (size of an integer is 4).
让我们计算一下,
Let’s evaluate it,
ptr = 123400
ptr = ptr + 1
ptr = ptr + sizeof(int)*1
ptr = 123400 + 4
ptr = 123404
Example of Adding Value to a Pointer
在以下示例中,我们正在声明一个数组和 pointer to an array 。使用数组的第一个元素初始化指针,然后向指针中添加一个整数值(2)以获得数组的第三个元素。
In the following example, we are declaring an array and pointer to an array. Initializing the pointer with the first element of the array and then adding an integer value (2) to the pointer to get the third element of the array.
#include <stdio.h>
int main() {
int int_arr[] = {12, 23, 45, 67, 89};
int *ptrArr = int_arr;
printf("Value at ptrArr: %d\n", *ptrArr);
// Adding 2 in ptrArr
ptrArr = ptrArr + 2;
printf("Value at ptrArr after adding 2: %d\n", *ptrArr);
return 0;
}
Value at ptrArr: 12
Value at ptrArr after adding 2: 45
Example of Subtracting Value to a Pointer
在以下示例中,我们声明了一个数组和一个指向数组的指针。用数组的最后一个元素初始化指针,然后从指针中减去一个整数值 (2) 以获取数组的第三个元素。
In the following example, we are declaring an array and pointer to an array. Initializing the pointer with the last element of the array and then subtracting an integer value (2) from the pointer to get the third element of the array.
#include <stdio.h>
int main() {
int int_arr[] = {12, 23, 45, 67, 89};
int *ptrArr = &int_arr[4]; // points to last element
printf("Value at ptrArr: %d\n", *ptrArr);
// Subtracting 2 in ptrArr
ptrArr = ptrArr - 2;
printf("Value at ptrArr after adding 2: %d\n", *ptrArr);
return 0;
}
Value at ptrArr: 89
Value at ptrArr after adding 2: 45
Subtraction of Pointers
当 + 和 "−" 运算符与常规数字操作数一起使用时,我们很熟悉它们。但是,当您将这些运算符与指针一起使用时,它们的行为会稍有不同。
We are familiar with the "+" and "−" operators when they are used with regular numeric operands. However, when you use these operators with pointers, they behave in a little different way.
由于指针是相当大的整数(尤其是在现代 64 位系统中),因此两个指针的加法是毫无意义的。当我们向指针添加 1,它指向可能存储整数的下一个位置。显然,当我们添加一个指针(本身是一个大整数)时,它指向的位置可能不在内存布局中。
Since pointers are fairly large integers (especially in modern 64-bit systems), addition of two pointers is meaningless. When we add a 1 to a pointer, it points to the next location where an integer may be stored. Obviously, when we add a pointer (itself a large integer), the location it points may not be in the memory layout.
但是,两个指针的减法是切合实际的。它返回可以放入两个指针中的数据类型的数量。
However, subtraction of two pointers is realistic. It returns the number of data types that can fit in the two pointers.
Example of Subtracting Two Pointers
让我们取前面示例中的数组,并对 a[0] 和 a[9] 的指针执行减法
Let us take the array in the previous example and perform the subtraction of pointers of a[0] and a[9]
#include <stdio.h>
int main(){
int a[]= {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
int *x = &a[0]; // zeroth element
int *y = &a[9]; // last element
printf("Add of a[0]: %ld add of a[9]: %ld\n", x, y);
printf("Subtraction of two pointers: %ld", y-x);
}
运行代码并检查其输出:
Run the code and check its output −
Add of a[0]: 140729162482768 add of a[9]: 140729162482804
Subtraction of two pointers: 9
可以看到两个整数之间的数值差为 36;它表明减法为 9,因为它可以在两个指针之间容纳 9 个整数。
It can be seen that the numerical difference between the two integers is 36; it suggests that the subtraction is 9, because it can accommodate 9 integers between the two pointers.
Comparison of Pointers
指针可以使用 relational operators (例如 "==", "<" 和 ">") 进行比较。如果 "p1" 和 "p2" 指向彼此相关的变量(例如同一数组的元素),那么可以对 "p1" 和 "p2" 进行有意义的比较。
Pointers may be compared by using relational operators such as "==", "<", and ">". If "p1" and "p2" point to variables that are related to each other (such as elements of the same array), then "p1" and "p2" can be meaningfully compared.
Example of Comparing Pointers
在以下示例中,我们声明了两个指针,并分别用数组的第一个元素和最后一个元素对它们进行初始化。只要它指向的地址小于或等于最后一个数组元素的地址 &var[MAX − 1] (即第二个指针),我们将继续递增第一个变量指针。
In the following example, we are declaring two pointers and initializing them with the first and last elements of the array respectively. We will keep incrementing the first variable pointer as long as the address to which it points is either less than or equal to the address of the last element of the array, which is "&var[MAX − 1]" (i.e., the second pointer).
#include <stdio.h>
const int MAX = 3;
int main() {
int var[] = {10, 100, 200};
int i, *ptr1, *ptr2;
// Initializing pointers
ptr1 = var;
ptr2 = &var[MAX - 1];
while (ptr1 <= ptr2) {
printf("Address of var[%d] = %p\n", i, ptr1);
printf("Value of var[%d] = %d\n", i, *ptr1);
/* point to the previous location */
ptr1++;
i++;
}
return 0;
}
运行代码并检查其输出:
Run the code and check its output −
Address of var[0] = 0x7ffe7101498c
Value of var[0] = 10
Address of var[1] = 0x7ffe71014990
Value of var[1] = 100
Address of var[2] = 0x7ffe71014994
Value of var[2] = 200