C语言指针运算



C语言中的指针变量存储另一个变量的地址。地址始终是整数。那么,我们能否对指针执行加法和减法等算术运算呢?本章将解释C语言中哪些算术运算符使用指针作为操作数,以及哪些运算未定义用于指针。

**C语言指针算术运算**与一般的算术运算不同。以下是C语言中一些重要的指针算术运算

  • 指针的自增和自减
  • 对指针加减整数
  • 指针相减
  • 指针的比较

让我们借助示例详细讨论所有这些指针算术运算。

指针的自增和自减

我们知道,“++”和“--”用作C语言中的自增和自减运算符。它们是一元运算符,以前缀或后缀方式与数字变量操作数一起使用,它们将变量的值增加或减少一。

假设在内存地址1000处创建一个整数变量“x”,其值为10。然后,“x++”将“x”的值设为11。

int x = 10;   // created at address 1000

x++;          // x becomes 11

如果我们将“y”声明为指向“x”的指针并将“y”增加1(使用“y++”)会发生什么?假设“y”本身的地址是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”变量的大小。

这是因为,如果“x”的地址是1000,则它占用4个字节:1000、1001、1002和1003。因此,下一个整数只能放在1004而不是之前。因此,当“y”(指向“x”的指针)增加时,“y”变为1004。

指针自增的示例

以下示例显示如何增加指针:

#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);
}

输出

运行代码并检查其输出:

Value of y before increment: 6422036
Value of y after increment: 6422040

您可以看到值增加了4。类似地,“--”运算符将值减少数据类型的大小。

指针自减的示例

让我们将“x”和“y”的类型更改为“double”和“float”,并查看自减运算符的效果。

#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

声明数组时,元素存储在相邻的内存位置。对于“int”数组,每个数组下标相隔4个字节,如下图所示:

Memory Locations

因此,如果一个变量存储数组第0个元素的地址,则“自增”将其指向第1个元素。

通过增加指针遍历数组的示例

以下示例显示如何通过连续增加指针来遍历数组:

#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;
}

输出

运行代码并检查其输出:

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

对指针加减整数

可以向指针添加和减去整数值。当向指针添加整数时,指针指向下一个内存地址。类似地,当从指针中减去整数时,指针指向前面的内存位置。

对指针加减整数不会直接将该值加到或减去指针,而是会将该值乘以数据类型的大小后加到或减去指针。

例如,有一个整数指针变量ptr,它指向地址123400,如果将1加到ptr(ptr+1),它将指向地址123404(整数大小为4)。

让我们评估一下:

ptr = 123400 
ptr = ptr + 1
ptr = ptr + sizeof(int)*1
ptr = 123400 + 4
ptr = 123404

向指针添加值的示例

在下面的示例中,我们声明一个数组和指向数组的指针。用数组的第一个元素初始化指针,然后向指针添加一个整数值(2)以获取数组的第三个元素。

#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

从指针减去值的示例

在下面的示例中,我们声明一个数组和指向数组的指针。用数组的最后一个元素初始化指针,然后从指针减去一个整数值(2)以获取数组的第三个元素。

#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

指针相减

我们熟悉“+”和“”运算符在用作常规数字操作数时的用法。但是,当您将这些运算符与指针一起使用时,它们的行为略有不同。

由于指针是相当大的整数(尤其是在现代64位系统中),因此两个指针的加法没有意义。当我们将1加到指针时,它指向下一个可能存储整数的位置。显然,当我们添加一个指针(它本身是一个很大的整数)时,它指向的位置可能不在内存布局中。

但是,两个指针的减法是现实的。它返回可以容纳在两个指针中的数据类型数量。

两个指针相减的示例

让我们以前面示例中的数组为例,执行a[0]和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);

}

输出

运行代码并检查其输出:

Add of a[0]: 140729162482768 add of a[9]: 140729162482804
Subtraction of two pointers: 9

可以看出,这两个整数之间的数值差是36;这表明减法结果是9,因为在两个指针之间可以容纳9个整数。

指针的比较

可以使用关系运算符(例如“==”、“<”和“>”)来比较指针。如果“p1”和“p2”指向彼此相关的变量(例如同一数组的元素),则可以有意义地比较“p1”和“p2”。

比较指针的示例

在下面的示例中,我们声明两个指针,并分别用数组的第一个和最后一个元素初始化它们。我们将不断增加第一个变量指针,只要它指向的地址小于或等于数组最后一个元素的地址,“&var[MAX − 1]”(即第二个指针)。

#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;
}

输出

运行代码并检查其输出:

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
广告