指针是C语言程序开发中一个非常重要的东西,今天学习以下指针,我将从以下几个小点去描述几种指针。
1. 字符指针
2. 数组指针/指针数组
3. 数组传参和指针传参
4. 函数指针
5. 函数指针数组
1.字符指针
在指针的类别中我们知道有一种指针类型为字符指针char * ;
表示方式有两种:
int main()
{
char ch = 'w';
char *pc = &ch;
*pc = 'w';
return 0;
}
int main()
{
const char* str = "hello bit.";//这里的ste表示字符串中‘a'的首地址
printf("%s\n", pstr);
return 0;
}
2.指针数组 /数组指针
指针数组:是存放指针的数组,将指针作为数组的元素存放在数组里面,数组的每个元素的类型是指针类型,他实际上是个数组;
数组指针:是将数组的地址存放在指针里面,他实际上是个指针;
指针数组示例:
int* arr1[10]; //整形指针的数组
char *arr2[10]; //一级字符指针的数组
char **arr3[10];//二级字符指针的数组
数组指针示例:
int (*p1)[10] //p先和 * 结合说明p是指针,然后指向大小为10个整形的数组
char (*p2)[10]
数组指针的使用:
void print_arr(int (*arr)[5], int row, int col)
{
int i = 0;
for(i=0; i<row; i++)
{
for(j=0; j<col; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
int main()
{
int arr[3][5] = {1,2,3,4,5,6,7,8,9,10};//数组名arr,表示首元素的地址,
//二维数组的首元素是二维数组的第一行
//这里传递的arr,其实相当于第一行的地址,是一维数组的地址
//可以数组指针来接收
print_arr2(arr, 3, 5);
return 0;
}
比较指针数组与数组指针:
int arr[5]; //普通数组
int *parr1[10]; //指针数组
int (*parr2)[10]; //数组指针
int (*parr3[10])[5]; //数组指针
3.数组参数,指针参数
数组传参,形参是可以写成数组形式的。数组传参的本质是传递了数组首元素的地址。数组传参,形式也可以是指针。
一维数组传参:
void test(int arr[])
{}
void test(int arr[10])
{}
void test(int *arr)
{}
void test2(int *arr[20])
{}
void test2(int **arr)
{}
二维数组传参:
void test(int arr[3][5])
{}
void test(int arr[][5])
{}
void test(int (*arr)[5])
{}
二维数组传参,函数形参的设计只能省略第一个[]的数字。因为对一个二维数组,可以不知道有多少行,但是必须知道一行多少元素。这样才方便运算。
一级指针传参:
#include <stdio.h>
void print(int *p, int sz)
{
int i = 0;
for(i=0; i<sz; i++)
{
printf("%d\n", *(p+i));
}
}
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9};
int *p = arr;
int sz = sizeof(arr)/sizeof(arr[0]);
print(p, sz); //一级指针p 传给函数
return 0;
}
二级指针传参:
#include <stdio.h>
void test(int** ptr)
{
printf("num = %d\n", **ptr);
}
int main()
{
int n = 10;
int*p = &n;
int **pp = &p;
test(pp);
test(&p);
return 0;
}
4.函数指针
函数指针就是用指针储存函数的首地址。例如:
void test()
{
printf("hehe\n");
}
void (*pfun1)();
5.函数指针数组
函数指针数组的作用是把函数的地址存到一个数组当中。
示例:
int (*parr1[10])();
parr1表示数组,*parr1[10]表示数组指针,parro1数组里面存放着10个指针。
整体表示有10个指针存放在数组parr1中,每个指针指向一个函数的地址。