指针进阶知识总结

一、字符指针char *

char *pstr="hello bit';
//指针pstr变量在栈上开辟,只把字符串的首字符地址存放在pstr中
//hello bit在字符常量区
char str[]="hello bit'';
//都在栈上开辟
const char *p="abcd";//p指向的内容不能变
char const *p="abcde';//p的指向不能变

二、指针数组和数组指针
1)指针数组(储存指针的数组):是数组,数组的元素都是指针,
数组占多少个字节由数组本身决定。
2)数组指针(指向数组的指针):是指针,指向一个数组,
在32位平台下永远是4字节,
至于它指向的数组占多少个字节,不知道。

int (*p)[10]=a;//错误
//=两边的数据类型不一致
//左边的类型指向整个数组的指针
//右边的数据类型指向单个字符的指针
int(*p)[10]=&a;//正确

在这里插入图片描述
三、数组参数和指针参数
<参数分为形参和实参。形参是指声明或定义函数时的参数,
而实参是调用函数时主调函数传递过来的实际值。>
1.一维数组传参
1)无法传递一个数组,c语言中,当一维数组作为函数参数的时候,
编译器总是把它解析成一个指向其首元素首地址的指针。
2)函数的返回值也不可能是一个数组,而只能是指针。
3)函数本身是没有类型的,只有函数的返回值才有类型。
4)实际传递的数组大小与函数形参指定的数组大小没有关系。

void test(int arr[])  {}
void test(int arr[10])  {}
void test(int *arr])  {}

void test(int *arr[20])  {}
void test(int **arr)  {}

int main()
{
int arr[10]={0};
int *arr[20]={0};
test(arr);
tese2(arr2);

2.一级指针参数
1)无法把指针变量本身传递给一个函数。
2)想要改变一级指针的内容,两种方法:用return或用二级指针。
3.二维数组参数与二维指针参数
1)二维数组参数:数组的数组:char a[3][4] 指针数组 char*a[5]
2)二维指针参数:数组的指针:char (*p)[10] 指针的指针char **p
四、函数指针
函数指针就是函数的指针,是一个指针,指向一个函数。
函数名和&函数名是一样的,代表函数的地址。

char *(*pf)(char *p);//定义一个函数指针
void Function() 
{
 printf("Call Function!\n"); 
 }
int main() 
{ 
void (*p)(); //定义了一个指针变量 p,p 指向一个函数,
            //这个函数的参数和返回值都是 void。
*(int*)&p=(int)Function;//表示将函数的入口地址赋值给指 针变量 p
 (*p)();//表示对函数的调用。
 return0
 } 
 // &p 是求指针变量 p 本身的地址,这是一个 32 位的二进制常数(32 位系统)。
  (int*)&p 表示将地址强制转换成指向 int 类型数据的指针。
  (int)Function 表示将函数的入口地址强制转换成 int 类型的数据。
  *(int*)&p=(int)Function;表示将函数的入口地址赋值给指 针变量 p。
(*(void(*)())0)();

//void(*)(),是一个函数指针类型。这个函数没有参数,没有返回值。
//(void(*)())0,这是将 0 强制转换为函数指针类型,0 是一个地址,
//也就是说一 个函数存在首地址为 0 的一段区域内。
//(*(void(*)())0),这是取 0 地址开始的一段内存里面的内容,
//其内容就是保存 在首地址为 0 的一段区域内的函数。
//(*(void(*)())0)(),这是函数调用。
//上面的例子再改写改写:
(*(char**(*)(char**,char**))0)( char**,char**);

五、函数指针数组

#include <stdio.h>
#include <string.h>
char* fun1(char* p)
{
printf("%s\n",p);
return p;
}
char* fun2(char* p)
{
printf("%s\n",p);
return p;
}
char* fun3(char* p)
{
printf("%s\n",p);
return p;
}
intmain()
{
char* (*pf[3])(char* p);//定义一个函数指针数组
pf[0]= fun1; // 可以直接用函数名
pf[1]= &fun2; // 可以用函数名加上取地址符
pf[2]= &fun3;
//char(*pf[3])(char c)={fun1,fun2,fun3};初始化
pf[0]("fun1");
pf[0]("fun2");
pf[0]("fun3");
return0;
}

六、函数指针数组的指针
指向函数指针数组的指针 是一个指针,指针指向 一个数组,
数组的元素都是 函数指针

char * (*(*pf)[3])(char *p);
#include <stdio.h>
#include <string.h>
char* fun1(char* p)
{
printf("%s\n",p);
return p;
}
char* fun2(char* p)
{
printf("%s\n",p);
return p;
}
char* fun3(char* p)
{
printf("%s\n",p);
return p;
}
int main()
{
char* (*a[3])(char* p);
char* (*(*pf)[3])(char* p);
pf = &a;
a[0]= fun1;
a[1]= &fun2;
a[2]= &fun3;
pf[0][0]("fun1");
pf[0][1]("fun2");
pf[0][2]("fun3");
return 0;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值