IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 指针篇(高) -> 正文阅读

[C++知识库]指针篇(高)

1.字符指针

字符指针是一个指向字符串的指针,它存储着一个字符地址,指向一个常量字符串,并且字符串不可修改。

以下是定义:

const char* ch="abcd";//"abcd"称为常量字符串

因为ch指针指向的字符串不能被修改,而且被修改了程序会奔溃,因此可以加上const
ch储存着常量字符串的首元素地址,也就是’a’的地址,"abcd"是常量字符串,不能被修改,被储存在只读数据区,当被引用时返回首字符地址。

这里我讲讲被常量字符串被调用返回的情况:

const char ch1 ="abcd";
const char ch2 ="abcd";
printf("%p\n",ch1);
printf("%p\n",ch2);

上面的结果是ch1和ch2的值是相同的,因为相同的常量字符串在只读数据区中储存的空间是相同的。

2.指针数组

指针数组是一个数组,只是用来存放指针的一个数组*

char* arr1[10];//存放一级字符指针的数组
int* arr1[10];//存放一级整形指针的数据
int** arr2[10];//存放二级整形指针的数据

3.数组指针

3.1 数组指针的定义

指针数组不是指针,只是一个存放指针的数组
而数组指针则是一个指向数组的指针

定义:

char arr1[10]; //指针数组
char (*arr2)[10];//数组指针
char *(*arr3)[10];//数组指针

’ [] ‘操作符的优先级比’ * ‘操作符的优先级高,所以arr1会先和’ [] '结合,形成数组,然后剩下的char就是数组存储数据的类型

arr2在括号的影响下先和’ * '结合,所以arr2代表的是一个数组指针,而剩下的char 变量名 [10] ;是代表指向数组的类型

同理:arr3也是一个数组指针,指向的是一个类型为char* [10] 的数组

3.2 &数组名VS数组名

我们在前面的学习也可以知道,数组名带表的是首元素地址,而&数组名又是什么呢?

int arr[10]={0};
printf("%p\n",arr);
printf("%p\n",&arr);

当我们得到上面的打印的结果可以发现,arr和&arr的值是一样的,
我们可以再尝试打一串代码

int arr[10]={0};
printf("%p\n",arr);
printf("%p\n",arr+1);
printf("%p\n",&arr+1);

当我们得到结果可以发现,arr+1的值相比arr大了4,而&arr+1比arr大了40,到这里应该就可以明白&arr和arr的不同了,&arr得到的地址代表整个数组,而arr只代表首元素地址。

3.3 数组指针的使用

由3.2可以知道,&数组名得到的是整个数组,所以数组指针指向的是整个数组。

int arr[10]={1,2,3,4,5,6,7,8,9,10};
int (*parr)[10]=&ch;
//使用
//先对pch解引用,在使用[]操作符进行访问空间
(*arr2)[0];

还有一种对数组指针的巧用,在定义数组指针的时候,arr(*pch)[10]中的[10]其实pch指针变量的一种权限

例如:

int arr[10]={1,2,3,4,5,6,7,8,9,10};
int (*parr)[5]=&ch;
//如果我们向打印7
printf("%d",*(*(parr+1)+1));
//或者
printf("%d",parr[1][1]);

从上面的例子可以看出,其实数组指针权限为几,就代表加一跳过几个元素(一个数组)。

4. 数组参数,指针参数

4.1 一维数组传参

一维数组传参大多数都是直接将数组名传过去,也可以传&数组名

void test(int arr[],size_t size);
void test(int* arr,size_t size);

int main()
{
	int arr[10] = { 0 };
	test(arr);
	return 0;
}

其中,两种函数的形参接受都一样的,int arr[]等于int* arr,都只是将数组的首元素地址传过去,因为数组的储存在空间中是连续的,所以得到了首元素地址,那么后面的元素也可以访问的到,size是数组元素个数

void test(int(*arr)[10]);

int main()
{
	int arr[10] = { 0 };
	test(&arr);
	return 0;
}

第二种就是将整个数组传过去

4.2二维数组传参

二维数组的传参和一维类似

第一种传参方法:

void test(int** arr);
void test(int(*arr)[10]);
void test(int arr[][10]);
void test(int arr[10][10]);

int main()
{
	int arr[10][10] = { 0 };
	test(arr);
	return 0;
}

或者将整个二维数组传过去:

void test(int(*arr)[10][10]);

int main()
{
	int arr[10][10] = { 0 };
	test(&arr);
	return 0;
}

5. 函数指针

函数指针,跟其他指针类似,函数指针其实就是指向函数的指针,和数组名一样,函数名也代表函数指针,但是与数组名不同的是,&函数名跟函数名代表的意义是一样的。

定义:


void test1();
int test2(int a);
char test3(char a,int* b);

int main()
{
   	  void(*p1)() = test1;
	//void(*p1)() = &test1;
	
	  int (*p2)(int) = test2;
	//int (*p2)(int) = &test2;
	
	  char(*p3)(char,int*)=test3;
	//char(*p3)(char,int*)=&test3;
	return 0;
}

在定义函数指针的时候,指针变量前的是返回类型,后面括号里的参数的类型和数量要保持和函数一致

6. 函数指针数组

函数指针数组就是一个数组,每个元素都是函数指针

定义:

int (*pfArr[4])(int,int);

[] 操作符的优先级比 * 高,pfArr先和 [] 结合,代表它是个数组,之后再和 * 结合,代表它的数组类型是函数指针

7. 函数指针数组指针

函数指针数组指针就是一个指向函数指针数组的指针

定义:

int (*(*pfArr)[4])(int, int);

,pfArr先和 * 结合,代表它是个指针,之后再和 [] 结合,代表它是个指向数组的指针,之后再和 * 结合,代表它指向的数组的元素类型是指针类型,剩下的代表它是个函数指针数组指针

8. 回调函数

回调函数是指 使用者自己定义一个函数,实现这个函数的程序内容,然后把这个函数(入口地址)作为参数传入别人(或系统)的函数中,由别人(或系统)的函数在运行时来调用的函数。函数是你实现的,但由别人(或系统)的函数在运行时通过参数传递的方式调用,这就是所谓的回调函数。简单来说,就是由别人的函数运行期间来回调你实现的函数。

使用:

void Print()
{
	printf("Hello Wrold\n");
}

void test(void Print())
{
	Print();
}

int main()
{
	test(Print);
	return 0;
}

具体的使用可以参考qsort函数的实现
链接:qsort函数的原理

9. 一些奇怪的例子

一:

(*(void(*)())0)();

上面的意思是将0强转为一个无返回类型无参数的函数指针并且调用

首先得到 (void( * )( )) 0,这里是将0强转为函数指针,然后( * ( void( * )( ) ) 0),加上是对指针=解引用,最后((void(*)())0)(),后面加上(),()是函数调用操作符。

二:

void( *signal( int, void(*)(int) ) ) (int);

首先,signal是一个函数,它的返回类型是void( * )(int),函数参数有int类型和void(*)(int) ;

signal先和()结合,代表它是一个函数,然后括号里面是函数的参数,剩余的就是signal的一个返回类型

三:
typedef定义函数指针类型

typedef  void(* pfun_t)(int);
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章           查看所有文章
加:2022-04-06 23:08:36  更:2022-04-06 23:08:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 23:58:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码