指针数组与数组指针---傻傻分不清楚?
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
目录
1.指针数组
什么是指针数组呢
我们通过以前学过的数组进行类比
- 整形数组是存放整形的数组
- 字符数组是存放字符的数组
- 所以指针数组是存放指针(地址)的数组
整形数组的书写形式是int arr[10]
字符指针书写形式是char arr[10]
所以字符指针的书写形式是int *arr[10] char* arr[10]
接下来创建一个字符指针数组
int main()
{
char a = 'a';
char b = 'b';
char c = 'c';
char d = 'd';
char* arr[4] = {&a,&b,&c,&d};
return 0;
}
创建了四个
char
类型变量将他们取地址放到字符指针数组里这是最基本的应用
还可以将字符串放到字符指针数组里字符串本质上是数组数组名是数组首元素地址所以将四个字符串名放到字符指针数组里即可
int main()
{
char str1[] = "hello";
char str2[] = "world";
char str3[] = "byebye";
char str4[] = "world";
char* arr[4] = {str1,str2,str3,str4};
return 0;
}
还可以用一维指针数组模拟二维数组
#include <stdio.h>
int main()
{
int arr1[5] = { 1,2,3,4,5 };
int arr2[5] = { 2,3,4,5,6 };
int arr3[5] = { 3,4,5,6,7 };
int arr4[5] = { 5,6,7,8,9 };
int arr5[5] = { 0,1,0,2,0 };
int* arr[5] = { arr1,arr2,arr3,arr4 ,arr5};
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
printf("%d ", *(*(arr + i) + j));
}
printf("\n");
}
return 0;
}
前面说过对于一个指针
p
,*(p+i)
与p[i]
等价
所以上述程序中的*(*(arr + i) + j)
也可以写成arr[i][j]
,也就是如二维数组一样的写法
这个指针数组的结构
2.数组指针
对于数组指针还是类比其他类型指针
- 整形指针是一个指向整形变量的指针
- 字符变量是一个指向字符变量的指针
- 所以数组变量就是一个指向数组的指针
- 整形指针的类型是
int*
,字符指针的类型是char*
所以数组指针的类型就是int(*)[10]
char ch = 'w';
char *pc = &ch;
int num = 10;
int* pi = #
int arr[10];
int(*pa)[10] = &arr;
在这个整形数组指针*
先与pa
结合(*pa)
所以int(*pa)[10]
是一个指针
在这里赋给数组指针的是数组名取地址那么数组名和数组名取地址有什么区别呢请点击跳转另一篇文章数组与地址数组名到底是什么
数组指针到底怎么用呢
之前如果要输出一个整形数组我们可以使用指针这里的指针通常是数组元素首地址
但是如果非要用数组指针输出数组中的元素也是可以的
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int(*p)[10] = &arr;
for (int i = 0; i < 10; i++)
{
printf("%d ", (*p)[i]);
}
return 0;
}
这里的p
是一个数组指针先将解引用*p
得到数组然后通过下标访问(*p)[i])
就可以得到数组元素了
但是这样做是很别扭的不如直接用整形指针输出
其实 数组指针在一位数组中用的不多在二维数组中会用到
在以往的对于二维数组的传参定义函数时在参数列表中最简单的写法是直接以二维数组的形式传形参
void print(int arr[3][4], int x, int y) //直接以二维数组的形式写是最简单的
{
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
int main()
{
int arr[3][4] = { {1,2,3,4},{2,3,4,5},{3,4,5,6} };
print(arr, 3, 4);
}
但是对于一位数组int arr[10]
如果在函数中想要接受它不但可以以数组的形式接受用一个一级指针接受也是可以的
void printf(int arr[10],int x,int y) //可以用数组的形式接收
{
;
}
void printf(int *arr,int x,int y) //也可以用指针的形式接收
{
;
}
int main()
{
int arr[10] = { {1,2,3,4},{2,3,4,5},{3,4,5,6} };
print(arr, 3, 4);
}
如果也想要用一个指针去接受二维指针就略有不同了
函数实参传一个二维数组名过去数组名是数组首元素地址所以二维数组数组名就是一个一维数组的地址这个二维数组名其实就是一个数组指针所以在函数中要用一个数组指针去接收
void print(int(*arr)[4],int x,int y) //用一个数组指针去接收
{
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y;j++)
{
printf("%d ", (*(arr+i))[j]);
}
printf("\n");
}
}
int main()
{
int arr[3][4] = { {1,2,3,4},{2,3,4,5},{3,4,5,6} };
print(arr, 3, 4);
}
学过了数组指针和指针数组看看下面这些都是什么
int arr[5];
int *parr1[10];
int (*parr2)[10];
int (*parr3[10])[5];
int arr[5]
是一个长度为5的整形数组int *parr1[10]
是一个整形指针数组长度为10里面存放整形指针int (*parr2)[10]
是一个数组指针parr2
指向一个长度为10的整形指针int (*parr3[10])[5]
这个比较复杂一步一步分析首先看名称parr3
先与[10]
结合所以这是一个数组长度为10然后剩下int(*)[5]
所以在数组parr3
中存放的是类型为int(*)[5]
的数组指针它指向一个长度为5的整形数组。