网站建设中,中国大陆地区请使用VPN访问,欢迎提建议,关注LSKR Mastodon

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

对于二维数组如何使用指针访问,通过两种数据结构来解释访问方式。
二维指针/数组该如何进行访问对于二维指针 (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 的具体指向来理解如何正确地访问数据。并且,如果二维指针指向的是动态分配的内存,务必记得在使用完毕后释放内存以避免内存泄漏。


发表评论

Cookie Consent
我们使用 Cookie 来了解您如何使用我们的网站并提升您的体验。这包括个性化内容和广告。
Oops!
It seems there is something wrong with your internet connection. Please connect to the internet and start browsing again.
AdBlock Detected!
We have detected that you are using adblocking plugin in your browser.
The revenue we earn by the advertisements is used to manage this website, we request you to whitelist our website in your adblocking plugin.
Site is Blocked
Sorry! This site is not available in your country.