先决条件: 指针介绍
指向数组的指针
考虑下面的程序:
C++
#include <iostream> using namespace std; int main() { int arr[5] = { 1, 2, 3, 4, 5 }; int *ptr = arr; cout << "" << ptr; return 0; } // thus code is contributed by shivanisinghss2110 |
C
#include<stdio.h> int main() { int arr[5] = { 1, 2, 3, 4, 5 }; int *ptr = arr; printf ( "%p" , ptr); return 0; } |
在这个程序中,我们有一个指针 ptr 这指向0 th 数组的元素。类似地,我们也可以声明一个指针,它可以指向整个数组,而不是数组中的一个元素。这个指针在讨论多维数组时很有用。 语法:
data_type (*var_name)[size_of_array];
例子:
int (*ptr)[10];
在这里 ptr 是可以指向10个整数数组的指针。由于下标的优先级高于间接寻址,因此有必要将间接寻址运算符和指针名称括在括号内。这里的ptr类型是“指向10个整数数组的指针”。 注: 指向0的指针 th 数组的元素和指向整个数组的指针是完全不同的。以下程序显示了这一点:
C++
// C++ program to understand difference between // pointer to an integer and pointer to an // array of integers. #include <iostream> using namespace std; int main() { // Pointer to an integer int *p; // Pointer to an array of 5 integers int (*ptr)[5]; int arr[5]; // Points to 0th element of the arr. p = arr; // Points to the whole array arr. ptr = &arr; cout << "p =" << p << ", ptr = " << ptr<< endl; p++; ptr++; cout << "p =" << p << ", ptr = " << ptr<< endl; return 0; } // This code is contributed by SHUBHAMSINGH10 |
C
// C program to understand difference between // pointer to an integer and pointer to an // array of integers. #include<stdio.h> int main() { // Pointer to an integer int *p; // Pointer to an array of 5 integers int (*ptr)[5]; int arr[5]; // Points to 0th element of the arr. p = arr; // Points to the whole array arr. ptr = &arr; printf ( "p = %p, ptr = %p" , p, ptr); p++; ptr++; printf ( "p = %p, ptr = %p" , p, ptr); return 0; } |
输出:
p = 0x7fff4f32fd50, ptr = 0x7fff4f32fd50p = 0x7fff4f32fd54, ptr = 0x7fff4f32fd64
P :指针指向0 th 数组的元素 啊 虽然 ptr 是指向整个数组的指针 啊 .
- 基本类型 P 是int,而基类型是 ptr 是“一个由5个整数组成的数组”。
- 我们知道指针算法是相对于基大小执行的,所以如果我们写ptr++,那么指针 ptr 将向前移动20字节。
下图显示了指针p和ptr。较暗的箭头表示指向数组的指针。
在解引用指针表达式时,我们会得到该指针表达式指向的值。指向一个数组的指针指向一个数组,所以在解引用它时,我们应该得到数组,数组的名称表示基址。因此,每当指向数组的指针被解引用时,我们就得到它所指向的数组的基址。
C++
// C++ program to illustrate sizes of // pointer of array #include <bits/stdc++.h> using namespace std; int main() { int arr[] = { 3, 5, 6, 7, 9 }; int *p = arr; int (*ptr)[5] = &arr; cout << "p = " << p << ", ptr = " << ptr << endl; cout << "*p = " << *p << ", *ptr = " << *ptr << endl; cout << "sizeof(p) = " << sizeof (p) << ", sizeof(*p) = " << sizeof (*p) << endl; cout << "sizeof(ptr) = " << sizeof (ptr) << ", sizeof(*ptr) = " << sizeof (*ptr) << endl; return 0; } // This code is contributed by shubhamsingh10 |
C
// C program to illustrate sizes of // pointer of array #include<stdio.h> int main() { int arr[] = { 3, 5, 6, 7, 9 }; int *p = arr; int (*ptr)[5] = &arr; printf ( "p = %p, ptr = %p" , p, ptr); printf ( "*p = %d, *ptr = %p" , *p, *ptr); printf ( "sizeof(p) = %lu, sizeof(*p) = %lu" , sizeof (p), sizeof (*p)); printf ( "sizeof(ptr) = %lu, sizeof(*ptr) = %lu" , sizeof (ptr), sizeof (*ptr)); return 0; } |
输出:
p = 0x7ffde1ee5010, ptr = 0x7ffde1ee5010*p = 3, *ptr = 0x7ffde1ee5010sizeof(p) = 8, sizeof(*p) = 4sizeof(ptr) = 8, sizeof(*ptr) = 20
指向多维数组的指针:
- 指针和二维数组: 在二维数组中,我们可以使用两个下标来访问每个元素,其中第一个下标表示行号,第二个下标表示列号。二维数组的元素也可以通过指针符号来访问。假设arr是一个二维数组,我们可以访问任何元素 arr[i][j] 使用指针表达式创建数组的 *(*(arr+i)+j) .现在我们来看看这个表达式是如何推导出来的。 让我们看一个二维数组 arr[3][4] :
int arr[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} };
由于计算机中的内存是线性组织的,所以不可能按行和列存储二维数组。行和列的概念只是理论上的,实际上,二维数组是按行的主要顺序存储的,即行彼此相邻。下图显示了上述二维阵列将如何存储在内存中。
每一行可以被视为一个一维数组,因此二维数组可以被视为一个一维数组的集合,这些数组一个接一个地放置。换句话说,我们可以说,一个接一个的二维数组。所以这里 啊 是由3个元素组成的数组,其中每个元素是由4个整数组成的一维数组。 我们知道数组的名称是一个指向0的常量指针 th 一维数组,包含地址5000。自从 啊 是“指向4个整数数组的指针”,根据指针算法,表达式arr+1将表示地址5016,表达式arr+2将表示地址5032。 所以我们可以这么说 啊 指向0 th 一维阵列, arr+1 指向1 圣 1-D阵列和 arr+2 指向2 钕 一维阵列。
一般来说,我们可以写:
arr + i Points to ith element of arr ->Points to ith 1-D array
- 因为arr+i指向i th 元素 啊 ,在取消引用时,它将 th 元素 啊 这当然是一个一维阵列。这样的表达 *(arr+i) 给我们i的基本地址 th 一维阵列。
- 我们知道,指针表达式 *(arr+i) 相当于下标表达式 arr[i] 所以 *(arr+i) 这和 arr[i] 给我们i的基本地址 th 一维阵列。
- 要访问二维阵列中的单个元素,我们应该能够访问任何j th i元素 th 一维阵列。
- 因为 *(arr+i) 是 智力 它包含0的地址 th i元素 th 1-D数组,我们可以得到i中后续元素的地址 th 通过将整数值添加到 *(arr+i) .
- 例如 *(arr+i)+1 将代表1的地址 圣 1的元素 圣 i元素 th 1-D阵列和 *(arr+i)+2 将代表2的地址 钕 i元素 th 一维阵列。
- 类似地,*(arr+i)+j将代表j的地址 th i元素 th 一维阵列。在解引用这个表达式时,我们可以得到j th i的元素 th 一维阵列。
- 指针和三维数组 在三维数组中,我们可以使用三个下标来访问每个元素。让我们看一个三维阵列-
int arr[2][3][2] = { {{5, 10}, {6, 11}, {7, 12}}, {{20, 30}, {21, 31}, {22, 32}} };
我们可以认为三维数组是二维数组的数组,即3-D数组的每个元素都被认为是二维数组。三维阵列 啊 可以被视为一个由两个元素组成的数组,其中每个元素都是一个二维数组。数组的名称 啊 是指向0的指针 th 二维阵列。
因此,指针表达式 *(*(*(arr+i)+j)+k)相当于下标表达式arr[i][j][k]。 我们知道表达式*(arr+i)等价于arr[i],表达式*(*(arr+i)+j)等价于arr[i][j]。所以我们可以说arr[i]代表i的基址 th 二维数组和arr[i][j]表示j的基址 th 一维阵列。
C++
// C++ program to print the elements of 3-D // array using pointer notation #include <iostream> using namespace std; int main() { int arr[2][3][2] = { { {5, 10}, {6, 11}, {7, 12}, }, { {20, 30}, {21, 31}, {22, 32}, } }; int i, j, k; for (i = 0; i < 2; i++) { for (j = 0; j < 3; j++) { for (k = 0; k < 2; k++) cout << *(*(*(arr + i) + j) +k) << " " ; cout << "" ; } } return 0; } // this code is contributed by shivanisinghss2110 |
C
// C program to print the elements of 3-D // array using pointer notation #include<stdio.h> int main() { int arr[2][3][2] = { { {5, 10}, {6, 11}, {7, 12}, }, { {20, 30}, {21, 31}, {22, 32}, } }; int i, j, k; for (i = 0; i < 2; i++) { for (j = 0; j < 3; j++) { for (k = 0; k < 2; k++) printf ( "%d " , *(*(*(arr + i) + j) +k)); printf ( "" ); } } return 0; } |
输出:
5 10 6 11 7 12 20 30 21 31 22 32
下图显示了上述程序中使用的三维阵列如何存储在内存中。
指向数组的下标指针
认为 啊 是一个包含3行4列和 ptr 是指向由4个整数组成的数组的指针,并且 ptr 包含数组的基址 啊 .
int arr[3][4] = {{10, 11, 12, 13}, {20, 21, 22, 23}, {30, 31, 32, 33}};int (*ptr)[4];ptr = arr;
自从 ptr 是指向由4个整数组成的数组的指针, ptr+i 我会指给你看 th 一行关于去引用 ptr+i ,我们得到了i的基本地址 th 一行访问j的地址 th i元素 th 我们可以在指针表达式中添加j *(ptr+i) .那么指针表达式 *(ptr+i)+j 给出了j的地址 th i元素 th 行和指针表达式 *(*(ptr+i)+j) 给出了j的值 th i元素 th 一行 我们知道指针表达式*(*(ptr+i)+j)等价于下标表达式ptr[i][j]。因此,如果我们有一个包含二维数组基址的指针变量,那么我们可以通过双下标该指针变量来访问数组元素。
C++
// C++ program to print elements of a 2-D array // by scripting a pointer to an array #include <iostream> using namespace std; int main() { int arr[3][4] = { {10, 11, 12, 13}, {20, 21, 22, 23}, {30, 31, 32, 33} }; int (*ptr)[4]; ptr = arr; cout << ptr<< " " << ptr + 1<< " " << ptr + 2 << endl; cout << *ptr<< " " << *(ptr + 1)<< " " << *(ptr + 2)<< endl; cout << **ptr<< " " << *(*(ptr + 1) + 2)<< " " << *(*(ptr + 2) + 3)<< endl; cout << ptr[0][0]<< " " << ptr[1][2]<< " " << ptr[2][3]<< endl; return 0; } // This code is contributed by shivanisinghss2110 |
C
// C program to print elements of a 2-D array // by scripting a pointer to an array #include<stdio.h> int main() { int arr[3][4] = { {10, 11, 12, 13}, {20, 21, 22, 23}, {30, 31, 32, 33} }; int (*ptr)[4]; ptr = arr; printf ( "%p %p %p" , ptr, ptr + 1, ptr + 2); printf ( "%p %p %p" , *ptr, *(ptr + 1), *(ptr + 2)); printf ( "%d %d %d" , **ptr, *(*(ptr + 1) + 2), *(*(ptr + 2) + 3)); printf ( "%d %d %d" , ptr[0][0], ptr[1][2], ptr[2][3]); return 0; } |
输出:
0x7ffead967560 0x7ffead967570 0x7ffead9675800x7ffead967560 0x7ffead967570 0x7ffead96758010 22 3310 22 33
本文由 阿努伊·乔汉 .如果你喜欢GeekSforgek,并想贡献自己的力量,你也可以使用 写极客。组织 或者把你的文章寄去评论-team@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。 如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写评论。,