指向数组的指针|数组指针

先决条件: 指针介绍

null

指向数组的指针

考虑下面的程序:

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。较暗的箭头表示指向数组的指针。

图片[1]-指向数组的指针|数组指针-yiteyi-C++库

在解引用指针表达式时,我们会得到该指针表达式指向的值。指向一个数组的指针指向一个数组,所以在解引用它时,我们应该得到数组,数组的名称表示基址。因此,每当指向数组的指针被解引用时,我们就得到它所指向的数组的基址。

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} };

图片[2]-指向数组的指针|数组指针-yiteyi-C++库

由于计算机中的内存是线性组织的,所以不可能按行和列存储二维数组。行和列的概念只是理论上的,实际上,二维数组是按行的主要顺序存储的,即行彼此相邻。下图显示了上述二维阵列将如何存储在内存中。

图片[3]-指向数组的指针|数组指针-yiteyi-C++库

每一行可以被视为一个一维数组,因此二维数组可以被视为一个一维数组的集合,这些数组一个接一个地放置。换句话说,我们可以说,一个接一个的二维数组。所以这里 是由3个元素组成的数组,其中每个元素是由4个整数组成的一维数组。 我们知道数组的名称是一个指向0的常量指针 th 一维数组,包含地址5000。自从 是“指向4个整数数组的指针”,根据指针算法,表达式arr+1将表示地址5016,表达式arr+2将表示地址5032。 所以我们可以这么说 指向0 th 一维阵列, arr+1 指向1 1-D阵列和 arr+2 指向2 一维阵列。

图片[4]-指向数组的指针|数组指针-yiteyi-C++库 图片[5]-指向数组的指针|数组指针-yiteyi-C++库

一般来说,我们可以写:

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 二维阵列。

图片[6]-指向数组的指针|数组指针-yiteyi-C++库

因此,指针表达式 *(*(*(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

下图显示了上述程序中使用的三维阵列如何存储在内存中。

图片[7]-指向数组的指针|数组指针-yiteyi-C++库

指向数组的下标指针

认为 是一个包含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;

图片[8]-指向数组的指针|数组指针-yiteyi-C++库

自从 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主页上,并帮助其他极客。 如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写评论。,

© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享