ZoyaPatel

二维指针/数组该如何进行访问

SohaniSharma
二维指针/数组该如何进行访问对于二维指针 (int **ptr 或类似类型),你需要进行两次解引用才能访问到最终指向的数据。这是因为它指向的是一个指针的指针。

让我们通过不同的场景来解释如何访问二维指针所指向的数据:

场景 1:ptr 指向一个指针数组

在这种情况下,ptr 指向一个数组,该数组的每个元素都是一个指向一维数组的指针 (int *)。

 int arr1[] = {1, 2, 3};
 int arr2[] = {4, 5};
 int arr3[] = {6, 7, 8, 9};
 
 int *ptr_arr[] = {arr1, arr2, arr3};
 int **ptr = ptr_arr;
 
 // 访问 arr1 的第一个元素 (值为 1)
 int value1 = *ptr[0];     // ptr[0] 得到 arr1 的地址 (int *),再用 * 解引用
 int value1_alt = **ptr;   // ptr 是 ptr_arr 的地址,*ptr 得到 ptr_arr[0] (arr1 的地址),再用 ** 解引用
 int value1_index = ptr[0][0]; // ptr[0] 得到 arr1 的地址,然后像访问数组一样使用下标
 
 // 访问 arr2 的第二个元素 (值为 5)
 int value2 = *(ptr[1] + 1); // ptr[1] 得到 arr2 的地址,+1 移动到第二个元素,再用 * 解引用
 int value2_index = ptr[1][1];
 
 // 访问 arr3 的第三个元素 (值为 8)
 int value3 = *(ptr[2] + 2);
 int value3_index = ptr[2][2];

解释:

  • ptr[i] 这会访问 ptr 指向的指针数组的第 i 个元素。该元素本身是一个 int * 类型的指针,指向一个一维整型数组的首地址。

  • *ptr[i]**ptr (当 i 为 0 时): 这会对 ptr[i] 得到的 int * 指针进行解引用,从而访问到该一维数组的第一个元素 (ptr[i][0] 的值)。

  • ptr[i][j] 这是一种更简洁的访问方式。ptr[i] 得到第 i 个一维数组的地址,然后 [j] 就像访问普通数组一样,访问该数组的第 j 个元素。这实际上等价于 (ptr[i] + j)

场景 2:ptr 指向动态分配的连续内存块(模拟二维数组)

在这种情况下,你可能先分配了一个指针数组,然后为每一行分配了内存,并让指针数组的每个元素指向对应行的起始地址。

 int rows = 3;
 int cols = 4;
 int **ptr = (int **)malloc(rows * sizeof(int *));
 for (int i = 0; i < rows; i++) {
     ptr[i] = (int *)malloc(cols * sizeof(int));
 }
 
 // 假设已经为 ptr 指向的内存填充了数据
 
 // 访问第 i 行第 j 列的元素
 int value = ptr[i][j];  // 最常用的访问方式
 int value_alt = *(*(ptr + i) + j);
 
 // 释放动态分配的内存 (重要!)
 for (int i = 0; i < rows; i++) {
     free(ptr[i]);
 }
 free(ptr);

解释:

  • ptr[i] 访问指针数组的第 i 个元素,得到指向第 i 行首地址的 int * 指针。

  • ptr[i][j]ptr[i] 得到的地址进行偏移 j * sizeof(int) 并解引用,访问第 i 行第 j 列的元素。

  •  (*(ptr + i) + j)

    这种方式更显式地展示了指针运算和解引用的过程:

    • ptr + i: 将 ptr (指向指针数组的指针) 移动 iint * 的位置,得到 ptr[i] 的地址。

    • (ptr + i): 解引用上面的地址,得到 ptr[i] 的值,即第 i 行的首地址 (int *)。

    • (ptr + i) + j: 将第 i 行的首地址移动 jint 的位置。

    • (*(ptr + i) + j): 解引用最终的地址,得到第 i 行第 j 列的 int 值。

总结:

访问二维指针通常使用以下方式:

  1. ptr[i][j] 这是最常用且直观的方式,它模拟了二维数组的访问语法。

  2. (ptr[i] + j) 更明确地展示了对第 i 个指针所指向的内存进行偏移和解引用。

  3. (\*(ptr + i) + j) 最底层的方式,清晰地展示了对指针的指针进行运算和两次解引用的过程。

记住,对于二维指针,底层的内存布局不一定是连续的,你需要根据 ptr 的具体指向来理解如何正确地访问数据。并且,如果二维指针指向的是动态分配的内存,务必记得在使用完毕后释放内存以避免内存泄漏。


Ahmedabad
Kolkata
Hyderabad
后一页 Bangalore 前一页

Random Manga

Ads

نموذج الاتصال