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