一、数组指针的概念
数组指针,简单来说,是指向数组(或其首元素)的指针。
1、数组指针的声明
数组指针的声明方式与普通指针略有不同,它需要明确指出指针所指向的数据类型是一个数组。
int a[10]; // 声明一个整型数组a
int (*p)[10]; // 声明一个指向整型数组的指针p
p = &a; // 让p指向数组a,这里&a的使用是可选的,因为数组名a本身就代表了数组首元素的地址
2、数组指针的使用
数组指针的使用主要涉及通过指针来访问和修改数组中的元素。由于数组指针指向的是整个
数组(或其首元素),因此你可以通过指针算术来遍历数组。
// 假设已经声明了数组a和数组指针p,并且p指向了a
for (int i = 0; i < 10; i++){
p[0][i] = i; // 通过数组指针访问数组元素// 或者 (*p)[i] = i; 这也是等效的
}
// 遍历并打印数组元素
void printArray2D(int (*a)[4],int rows)
{
int i,j;
for(i =0;i < rows;++i)
{
for(j = 0;j < 4;++j)
{
printf("%2d ",*(*(a + i) + j));//a[i][j] ---*(*(a + i) + j)
}
puts("");
}
}
4、注意事项
类型匹配:当你声明一个数组指针时,必须明确指定它所指向的数组的类型和大小。类型不
匹配会导致编译错误或运行时错误。
内存管理:虽然数组指针本身不直接涉及内存分配和释放,但当你通过数组指针访问动态分
配的数组时,就需要注意内存管理问题,以避免内存泄漏。
指针算术:对数组指针进行算术运算时,要注意其增量是以数组的长度为单位的
二、函数指针
为了降低函数的耦合性;函数的函数名就是函数的入口地址;
指针函数: 顾名思义,它的本质是一个函数,不过它的返回值是一个指针。其声明的形式如
下所示:
ret *func(args, ...);
int div2(int n)
{
return n % 2 ==0;
}
int div3(int n)
{
return n % 3 ==0;
}
void printArray(int *a, int rows,int (*pfn)(int))
{
int i;
for(i = 0;i < rows;++i)
{
if(pfn(a[i]))
{
printf("%d\n",a[i]);
}
}
}
int main(void)
{
int a[]= {1,2,3,4,5,6,7,8,9,10,11,12};
int len = sizeof(a) / sizeof(a[0]);
printArray(a,len,div3);
return 0;
}
三、双重指针
1.定义和声明
双重指针的声明语法如你所述:
data_type **pointer_name;
这里,data_type
是指针最终指向的数据类型,而 **pointer_name
表示 pointer_name
是一个
指向指针的指针。
2.初始化
双重指针的初始化通常涉及两个步骤:
-
创建并初始化一个指针:这个指针指向你想要通过双重指针访问的数据。
-
创建并初始化双重指针:这个双重指针指向步骤1中创建的指针。
3.示例
void sortString(char **s,int len)
{
int i,j;
for(i = 0;i < len -1;++i)
{
for(j = i + 1;j < len ;++j)
{
if(strcmp(s[i],s[j]) > 0)
{
swap(s + i,s + j);//交换指针中储存的地址
}
}
}
} //利用指向指针的指针对二维字符型数组进行排序