例:
声明方式:int *ptr[3]; ptr数组的元素都是指向int类型的数据
#include
int main() {
int *ptr[3];//数组元素类型为 整形指针
int A1=1,A2=2,A3=3;
ptr[0] = &A1; //存储整型变量的地址
ptr[1] = &A2;
ptr[2] = &A3;
for(int i=0; i<3; i++)
printf("Value: %d \r\n", *ptr[i]); //对数组内存储的指针进行解引用,取出地址中的数据
return 0;
}
进阶用法1:指针数组保存二维数组的第一维首地址
#include
int main() {
char c[][5] = { "abcd", "efgh", "ijkl" };
char *pc[3];
int i;
for ( i = 0; i < 3; i++ ) {
pc[i] = c[i];
}
for ( i = 0; i < 3; i++ ) {
printf("%s\n", pc[i]);
}
return 0;
}
进阶用法2: 函数指针数组
#include
void f1(void){
printf("Value1");
}
void f2(void){
printf("Value2");
}
void f3(void){
printf("Value3");
}
int main() {
void (*ptr[3])(); //类型为函数指针的指针数组
ptr[0]=f1;
ptr[1]=f2;
ptr[2]=f3;
for(int i=0; i<3; i++)
ptr[i](); //调用函数指针数组内的函数
return 0;
}
分析: [ ] 的优先级比*的优先级要高,加上括号之后就是先执行()内的动作, 因为有括号,所以pb先和*结合,表示pb是一个指针,再和[]结合,表示pb是一个指向类型为char,大小为5的数组的指针。
#include
int main() {
char b[][5] = { "abcd", "efgh", "ijkl" };
char (*ptr)[5]; //数组指针
ptr=b;
printf("%s\r\n",*ptr);
return 0;
}
指针函数的声明如上,用法和普通函数一样,只是它的返回值是一个指针而已(或者说是一个地址)。 指针函数我们经常见到,比如strcpy函数等等。
分析:()的优先级高于*,所以function先和()结合,function是一个函数,再和*结合,表示函数的返回值是一个指针,
类型是char,返回值是一个指向char类型的指针。这种函数其实叫做指针函数。
#include
#include
#include
char *str_var(char *s) {
char *str = (char *)malloc(sizeof(char) * strlen(s) + 1);
strcpy(str, s);
return str;
}
int main() {
//char *str = "Hellow world"; //这样子的声明,该字符串会被定义为只读,不可修改其内容
char *str = str_var("Hellow world");/*该函数则是通过申请一块内存来存放这些字符串,这样就可以修改其数据*/
printf("%s\n",str);
return 0;
}
函数指针的声明方式如下:
char (*fun)(void);
分析:由于括号的存在,fun先和*结合,fun是一个指针,再和右边的()结合,表示一个函数,函数返回类型为char。
fun是一个指向返回类型为char的函数。是的,指针可以指向一个函数的指针。
严格来说指针只能指向地址,因为函数名本质上代表的是一个地址(函数的首地址),所以指针可以指向函数。
用法如下:
#include
typedef void(*Func)(char);//重命名函数类型
void f1(char a){
printf("Value1=%d\r\n", a);
}
void f2(char a){
printf("Value2=%d\r\n",a);
}
void f3(char a){
printf("Value3=%d\r\n",a);
}
int main() {
//void (*ptr[3])(); //类型为函数指针的指针数组
Func ptr[3];
ptr[0]=f1;
ptr[1]=f2;
ptr[2]=f3;
for(char i=0; i<3; i++)
ptr[i](i); //调用函数指针数组内的函数
return 0;
}