C++ 指针数组和数组指针
- 引言
- 一、指针数组
- 1.1、数值的指针数组
- 1.2、字符的指针数组
- 1.3、二维字符数组
- 二、指针的指针
- 三、数组指针
- 3.1、数组首元素地址和数组首地址
- 3.2、数组指针的使用示例
- 3.3、二维数组和数组指针的关系
- 四、多维数组的物理存储
- 总结
引言
💡 作者简介:专注于C/C++高性能程序设计和开发,理论与代码实践结合,让世界没有难学的技术。包括C/C++、Linux、MySQL、Redis、TCP/IP、协程、网络编程等。
👉
🎖️ CSDN实力新星,社区专家博主
👉
🔔 专栏介绍:从零到c++精通的学习之路。内容包括C++基础编程、中级编程、高级编程;掌握各个知识点。
👉
🔔 专栏地址:C++从零开始到精通
👉
🔔 博客主页:https://blog.csdn.net/Long_xu
🔔 上一篇:【017】C++ 指针变量详解,理解指针变量
一、指针数组
指针数组本质上是数组,只是数组的每个元素为指针。要牢记这句话。
例如:
char *arr_ch[10];
short *arr_sh[10];
int * arr_i[10];
sizeof(arr_ch);// 40 Byte
sizeof(arr_sh);// 40 Byte
sizeof(arr_i);// 40 Byte
1.1、数值的指针数组
#include <iostream>
using namespace std;
int main(int argc,char **argv)
{
int num1=1;
int num2=2;
int num3=3;
int num4=4;
int num5=5;
int *arr[5]={&num1,&num2,&num3,&num4,&num5};
int n=sizeof(arr)/sizeof(arr[0]);
int i=0;
for(i=0;i<n;i++)
{
cout<<*arr[i]<<" ";
}
cout<<endl;
return 0;
}
输出:
1 2 3 4 5
1.2、字符的指针数组
#include <iostream>
using namespace std;
int main(int argc,char **argv)
{
char *arr[4]={"hehehehe","xixixixixi","lalalalala","hahahahaha"};
int n=sizeof(arr)/sizeof(arr[0]);
int i=0;
for(i=0;i<n;i++)
{
cout<<arr[i]<<endl;;
}
return 0;
}
1.3、二维字符数组
二维字符数组存放的是每个字符串,指针数组存放的是每个字符串的首元素的地址。要注意这个区别。
例如:
char arr[4][128]={"hehehehe","xixixixixi","lalalalala","hahahahaha"}
二、指针的指针
int num=100;
int *p=#
int **q=&p;//指针的指针
从这可以推导出,n级指针可以保存n-1级指针变量的地址。
三、数组指针
数组指针本质上是指针变量;保存的是数组的首地址。
数组指针+1跳过的是整个数组。
int arr[5]={1,2,3,4,5};
int (*p)[5]=NULL;//这个就是数组指针
cout<<sizeof(p)<<endl;// 输出4。因为是指针,在32位平台永远是4字节
cout<<"p="<<p<<endl;//输出0,因为上面把它指向NULL。
cout<<"p+1="<<p+1<<endl;//输出0x14,转换为10进制就是20,也就是20个字节。即4*5
p=&arr;//数组指针保存数组的首地址
3.1、数组首元素地址和数组首地址
假设有这样一个数组:
int arr[]={10,20,30,40,50};
(1)数组首元素地址是 &arr[0],而且arr也是代表的数组首元素地址。arr+1跳过的是一个元素。
cout<<"arr = "<<arr<<endl;
cout<<"&arr[0] = "<<&arr[0]<<endl;
cout<<"arr + 1 = "<<arr+1<<endl;
输出:
arr = 0x62fe7c
&arr[0] = 0x62fe7c
arr + 1 = 0x62fe80
可以看到arr和arr+1的地址相差4字节。
(2)数组的首地址是&arr;&arr+1跳过的是整个数组。
cout<<"&arr = "<<&arr<<endl;
cout<<"&arr + 1 = "<<&arr+1<<endl;
输出:
&arr = 0x62fe7c
&arr + 1 = 0x62fe90
(3)对数组首地址取* 得到的是数组首元素地址。
(4)数组指针一般在函数参数中使用。
3.2、数组指针的使用示例
int arr[5]={1,2,3,4,5};
int (*p)[5]=&arr;
cout<<*((int *)(p+1)-2)<<endl;//输出4,分析:首先是p+1指向了数组末尾,减2就是往后移动2个,刚好是4。
3.3、二维数组和数组指针的关系
(1)理解二维数组,二维数组的数组名表示的是第0行的行地址,对行地址取地址得到的是列地址。假设有如下的二维数组:
int arr[3][4]={
{1,2,3,4},
{5,6,7,8},
{9,10,11,12}
};
arr[1];//arr是首元素地址,所以arr[1]=(*arr+1),也就是第1行第0列的列地址。
&arr[1];//(arr+1),第一行的行地址。
*arr+1;//第0行第一列的列地址。
arr[1]+2;//*(arr+1)+2,第一行第2列的列地址。
**arr;//a[0][0]
(2)二维数组和一维数组指针的关系:一维数组指针和二维数组名是完全等价的。
小结:n维数组和n-1维的数组指针等价。
四、多维数组的物理存储
不管是几维数组在物理上都是一维存储;在逻辑上是多维的而已。
#include <iostream>
using namespace std;
int main()
{
int arr[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int row=sizeof(arr)/sizeof(arr[0]);
int col=sizeof(arr[0])/sizeof(arr[0][0]);
int *p=&arr[0][0];
for(int i=0;i<row*col;i++)
{
cout<<p[i]<<" ";
}
cout<<endl;
return 0;
}
输出:
1 2 3 4 5 6 7 8 9 10 11 12
总结
指针数组和数组指针是C++中比较常见的两种概念,它们都与数组和指针有关。
- 指针数组:指针数组是一个数组,其中每个元素都是一个指针。可以使用下标来访问该数组的各个元素,并且每个元素都可以用来存储指向不同类型对象的地址。例如:
int* ptrArr[10]; // 定义一个含有10个元素的int型指针数组
上述代码定义了一个名为ptrArr的包含10个元素的整型指针数组。可以通过下标访问这些元素,例如:
ptrArr[0] = new int(1); // 将第一个元素赋值为1
cout << *ptrArr[0] << endl; // 输出1
delete ptrArr[0]; // 释放内存
- 数组指针:数组指针是一个指向数组的指针。它本身就是一个变量,但可以通过它来访问所引用的整个数组。例如:
int arr[3][4] = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}};
int (*p)[4] = arr; // 定义名为p的二维整型数组指针并将其初始化为arr
上述代码定义了一个名为p的二维整型数组指针,并将其初始化为arr。可以通过p来访问整个数组,例如:
cout << p[0][2] << endl; // 输出3
需要注意的是,由于数组指针实际上是指向一个数组的指针,因此它的类型必须与所指向的数组类型相匹配。