关于C语言中的指针与二维数组
作者:coder_7
引言
本文探讨的是如何通过指针访问二维数组中的元素,以及二维数组如何在内存中存储
指向一维数组的指针:
我们先来看下如何通过指针访问一维数组
#include <stdio.h> int main(){ int arr[] = {4, 3, 2, 1}; // 由于数组名是第一个元素的指针,对数组名进行解引用(*arr:此操作称为解引用)就能拿到第一个元素 printf("*arr=%d arr[0]=%d\n", *arr, arr[0]); // 对指针+1就能拿到第二个元素的指针,依次类推 printf("*(arr+1)=%d arr[1]=%d\n", *(arr+1), arr[1]); return 0; }
二维数组的存储形式:
c中的二维数组其实是一维数组的线性扩展,二维数组在内存中其实是以一维的形式存储。
比如:int arr[3][4] = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}}
在内存中的存储格式如下:
arr[0] | arr[1] | arr[2] |
⇓
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
指向二维数组的指针:
在c语言中我们可以把二维数组看作一维数组来处理,只不过这个数组的元素也是数组。比如:arr[3,4] 我们可以认为这个数组由三个一维子数组构成,而这三个一维数组都包含了4个元素
在一维数组中数组名就是第一个元素的指针,当我们将二维数组看作一个一维数组时,我们就可以推出:数组名是前n个元素组成的数组的指针(arr[3][4] n的值就是4)
请看下面例子:
#include <stdio.h> int main(){ int arr[3][4] = {0}; printf("sizeof(int):%d\n", sizeof(int)); //sizeof(int):4 printf("arr:%p",arr); // arr:000000000062FDE0 printf("arr+1:%p",arr+1); // arr+1:000000000062FDF0 return 0; }
地址结果相减我们可以得出10,但这是16进制的结果,转为10进制结果就是16。由于int类型占4个字节,我们可以得出arr与arr+1相差了4个元素,把二维数组的看作一维数组那么这里元素之间的跨度就是4个元素(4*4=16个字节)。由此得出 arr 指向的是第一个子数组的指针,arr+1 指向的是第二个子数组的指针 …
既然 arr 指向的是第一个子数组的指针,那么 *arr(解引用) 的值就是第一个子数组的地址,更确切的说 *arr 是第一个子数组的第一个元素的地址,只有 **arr (双重解引用)才能拿到第一个子数组的第一个元素的值。
我们看如下代码:
#include <stdio.h> int main(){ int arr[3][4] = { {1,2,3,4}, {5,6,7,8}, {9,10,11,12} }; // 打印结果发现 *arr == &arr[0][0],又一次证明arr指向“第一个子数组” printf("*arr = %p &arr[0][0] = %p\n", *arr, &arr[0][0]); printf("**arr = %d arr[0][0] = %d\n", **arr, arr[0][0]); printf("*(*arr+1) = %d arr[1][0] = %d\n", *(*arr+1), arr[0][1]); printf("**(arr+1) = %d arr[0][0] = %d\n", **(arr+1), arr[1][0]); return 0; }
这样的做法就是通过指针来拿数组中的元素,与下标获取数组元素的结果是一致的。
测试题:
int arr[3][4] = { {1,2,3,4}, {5,6,7,8}, {9,10,11,12} }; // 输出下面的结果 printf("*(*(arr+1)+1) = %d\n", *(*(arr+1)+1) ); printf("*(*(arr[2])+1) = %d \n",*(*(arr[2])+1) );
到此这篇关于关于C语言中的指针与二维数组的文章就介绍到这了,更多相关指针与二维数组内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!