通过指针引用数组元素
引用一个数组元素,可以用:
① 下标法:如 a[i] 形式。
② 指针法:如 *(a+i) 或者 *(p+i) 。其中a是数组名,p是指向数组元素的指针变量,其初值:p =
a;
案例
需求:有一整型数组a,有10个元素。输出数组中的全部元素。
分析:要输出各元素的值,有三种方法
下标法;通过改变下标输出所有元素
#include <stdio.h>
void main()
{
int arr[10];
int i;
// 给数组元素赋值
for(i = 0; i < 10; i++)
scanf("%d",&arr[i]);
// 遍历数组元素
for(i = 0; i < 10; i++)
printf("%-4d%",arr[i]);
printf("\n");
}
指针法(地址):通过数组名计算出数组元素的地址,找出数组元素值
#include <stdio.h>
void main()
{
int arr[10];
int i;
// 给数组元素赋值
for(i = 0; i < 10; i++)
scanf("%d",&arr[i]);
// 遍历数组元素
for(i = 0; i < 10; i++)
printf("%-4d%",*(arr+i));
printf("\n");
}
指针法(指针变量):用指针变量指向数组元素
#include <stdio.h>
void main()
{
int arr[10];
int *p,i;
// 给数组元素赋值
for(i = 0; i < 10; i++)
scanf("%d",&arr[i]);
// 遍历数组元素
for(p = arr;p < (arr + 10); p++)
printf("%-4d%",*p);
printf("\n");
}
以上3种写法比较:
第①种写法和第②种写法执行效率相同。系统是将arr[i]转换为*(arr+i)处理的,即先计算出地
址,因此比较费时。
第③种方法比第①②种方法快。用指针变量直接指向数组元素,不必每次都重新计算地址。
(p++)能大大提高执行效率。
用第①种写法比较直观,而用地址法或者指针变量的方法难以很快判断出当前处理的元素。
使用指针变量指向数组元素时(上面第③种写法),注意以下三点:
① *(p--) 相当于arr[i--],先*p,再p--
② *(++p) 相当于arr[++i],先++p,再*
③ *(--p) 相当于arr[--i],先--p,再*
数组名作函数参数
表现形式:
1. 形参和实参都是数组名
void fun(int arr[],int len){..}
void main()
{
int arr[] = {11,22,33};
fun(arr,sizeof(arr)/sizeof(arr[0]));
}
2. 实参用数组名,形参用指针变量
void fun(int *p,int len){..}
void main()
{
int arr[] = {11,22,33};
fun(arr,sizeof(arr)/sizeof(arr[0]));
}
3. 实参形参都用指针变量
void fun(int *p,int len){..}
void main()
{
int arr[] = {11,22,33};
int *p = arr;
fun(p,sizeof(arr)/sizeof(arr[0]));
}
4. 实参为指针变量,形参为数组名
void fun(int arr[],int len){..}
void main()
{
int arr[] = {11,22,33};
int *p = arr;
fun(p,sizeof(arr)/sizeof(arr[0]));
}
数组指针与指针数组
数组指针
概念:数组指针是指向数组的指针,本质上还是指针
特点:
先有数组,后有指针
它指向的是一个完整的数组
一维数组指针:
语法:数据类型 (*指针变量名)[容量];
案例:
/**
* 数组指针:指向数组的指针(这里不是指向数组元素的指针)
*/
#include <stdio.h>
int main(int argc,char *argv[])
{
// 一维数组指针
// 现有数组,再有指针
int arr[] = {100,200,300};
// 获取数组的元素个数
int len = sizeof(arr) / sizeof(arr[0]);
// 定义一个数组指针,指向arr这个数组int
(*p)[3] = &arr; // 此时p不是指向arr数组的第一个元素,而是指向arr这个数组本身
printf("%p\n",p);
// p++; // 此时p++会跳出整个数组,访问到一块未知的内存,程序中尽量避免这种写法
// printf("%p\n",p);
// 如何访问访问数组指针
printf("%d\n",(*p)[2]);// 300
// 遍历
for(int i = 0;i < len;i++)
{
printf("%d\n",(*p)[i]);
}
printf("\n");
return 0;
}
二维数组指针:
语法:数据类型 (*指针变量名)[行容量][列容量];
案例:
写法1:
#include <stdio.h>
int main(int argc,char *argv[])
{
// 创建一个普通的二维数组
int arr[][3] = {10,20,30,100,200,300,1000,2000,3000};
// 创建一个二维数组指针
// 一个二维数组本质上还是一个一维数组,只不过它的元素也是数组
int (*p)[3][3] = &arr;
printf("%d\n",(*p)[1][0]);
// 遍历
for(int i = 0; i < sizeof(arr)/sizeof(arr[0]);i++)
{
int len = sizeof(arr[i])/sizeof(int);
for(int j = 0; j < len; j++)
{
printf("%-4d",(*p)[i][j]);
}
printf("\n");
}
printf("\n");
return 0;
}
写法2:
#include <stdio.h>
int main(int argc,char *argv[])
{
// 创建一个普通的二维数组
int arr[][3] = {10,20,30,100,200,300,1000,2000,3000};
// 创建一个二维数组指针
// 一个二维数组本质上还是一个一维数组,只不过它的元素也是数组
int (*p)[3] = arr; // 取二维数组的第一个元素 {10,20,30} 数组名本身就代表数组首元素(地址)
printf("%d\n",(*p)[0]);// 10
// 获取元素2000
printf("2000-%d,%d,%d",*(*(p+2)+1),*(p[2]+1),p[2][1];// *(*(p+1)+2) 300
return 0;
}
指针和数组中符号优先级: () > [] > *
指针数组
概念:指针数组是一个数组,数组中的每一个元素都是一个指针
特点:
先有指针,后有数组
指针数组的本质是一个数组,只是数组中的元素类型为指针
语法:数据类型 *数组名[容量];
案例:
#include <stdio.h>
int main(int argc,char *argv[])
{
// 定义三个变量
int a = 10,b = 20,c = 30;
// 定义指针数组,指针数组用来存放指针的
int *arr[3] = {&a,&b,&c};
// 获取数组大小
int len = sizeof arr / sizeof arr[0];
// 遍历数组
for(int i = 0; i < len; i++)
printf("%-3d",*arr[i]);// 输出每个指针指向的值,需要解引用
printf("\n");
return(0);
}
建议:我们一般使用指针数组处理字符串