深入理解C语言指针,让你不再迷路~

本文详细探讨了C语言中的指针,包括字符指针、指针数组、数组指针、数组参数与指针参数、函数指针以及回调函数的使用。通过实例解析了各种指针类型的定义、用法及它们之间的区别,帮助读者深入理解C语言中的指针概念。
摘要由CSDN通过智能技术生成

目录

1. 字符指针

2. 指针数组

2.1 指针数组的定义

2.2 指针数组的使用

3.数组指针

3.1数组指针的定义

3.1.1指针的类型 

3.1.2指针所指向的类型

3.2 &数组名VS数组名 

3.3 数组指针的使用

3.3.1 在一维数组中的使用

3.3.2 在二维数组中的使用

4. 数组参数、指针参数

4.1 一维数组传参

4.2 二维数组传参

4.3 一级指针传参

4.4 二级指针传参

5. 函数指针

5.1函数指针的定义与类型

5.2函数指针的使用 

6. 函数指针数组

6.1函数指针数组的定义

6.2函数指针数组的使用

7. 指向函数指针数组的指针

7.1指向函数指针数组指针的定义

7.2指向函数指针数组指针的使用

8. 回调函数

8.1回调函数的定义

 8.2回调函数的使用

qsort函数

qsort函数的使用

 qsort函数的模拟实现:


1. 字符指针

int* pa;   int型指针,指针指向的类型为int型

short* pa;   short型指针,指针指向的类型为short型

float* pa;   float型指针,指针指向的类型为float型

⭐ char型指针,指针指向的类型为字符类型

通常情况下我们会这样使用他

int main()
{
char ch = 'w';
char *pc = &ch;
*pc = 'w';
return 0;
}

还有一种使用方式

int main()
{
const char* pstr = "hello bit.";这里是把一个字符串放到pstr指针变量里了吗?
printf("%s\n", pstr);
return 0;
}

我们肯定首先想到的是将“hello bit.”这个字符串放到了pstr中,但实际情况是将字符串“hello bite.”的首元素地址放到了pstr中

上面代码的意思是把一个常量字符串的首字符 h 的地址存放到指针变量 pstr 中。
 

可以发现字符指针和数组非常相似

以 %s 来打印,从起始地址开始,遇到  \0  停止

但是也有不同的地方,下面分析这段代码,判断一下他的打印结果

int main()
{
	char str1[] = "hello bit.";
	char str2[] = "hello bit.";

	const char* str3 = "hello bit.";
	const char* str4 = "hello bit.";
	if (str1 == str2)
		printf("str1 and str2 are same\n");
	else
		printf("str1 and str2 are not same\n");

	if (str3 == str4)
		printf("str3 and str4 are same\n");
	else
		printf("str3 and str4 are not same\n");
	return 0;
}

打印结果如下

 下面来做一个分析

1.内存会为str1[]与str2[]开辟两块空间,这就意味着他们的地址是不相同的,只不过他们存放的内容都是“hello bite.”

2.这里str3和str4指向的是一个同一个常量字符串。C/C++会把常量字符串存储到单独的一个内存区域(称为常量区),当几个指针。指向同一个字符串的时候,他们实际会指向同一块内存。因为针对常量区相同的内容,没必要在其中开辟多份空间

 3.注意 

⭐ 常量区的值顾名思义为常量,无法被修改,否则编译器会报错

 


2. 指针数组

指针数组是什么?

我们先来看看其他类型的数组

int pa[10];   整形数组
char pb[10];  字符型数组
float pc[5];  浮点型数组

以char型数组为例 

整形数组是存放整形的数组,浮点型数组是存放浮点型数据的数组。

由此我们也不难推断出,指针数组是存放指针类型的数组


2.1 指针数组的定义

int* pa[10];   整形指针 数组
char* pb[10];  字符型指针 数组
float* pc[5];  浮点型指针 数组


2.2 指针数组的使用

下面以整形指针数组为例:

int main()
{
	int arr1[] = { 1,2,3,10 };
	int arr2[] = { 4,5,6,10 };
	int arr3[] = { 7,8,9,10 };

	int* pa[] = { arr1,arr2,arr3 };
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 4; j++)
		{
			//1
			printf("%d ", pa[i][j]);
			//2
			printf("%d ", (*(pa+i))[j]);
			//3
			printf("%d ", *(*(pa + i)+j));
			printf(" ");
		}
		printf("\n");
	}
	return 0;
}

运行结果如下:

 

🔈:因为我们这里用了三种访问数组中元素的方法,每个元素都打印了三遍  

pa[ i ][ j ]
(*(pa+i ) )[ j ]
*(*(pa + i )+ j )

以上三种方法都可以访问到数组中的元素,下面我们来逐一分析一下

1. pa[i][j]

当i=0时,pa[0]就访问到指针数组中的第一个元素,即arr1

arr1[j]就访问到arr1数组中下标为j的元素

2. (*(pa+i))[j]

pa+i找到pa指针数组中数组下标为 i 的地址。i为0时,找到arr1的地址,*(pa+i)就找到了arr1,然后通过arr1[j]就访问到arr1数组中下标为j的元素

3.*(*(pa + i)+j)

pa+i找到pa指针数组中数组下标为 i 的地址。i为1时,找到arr2的地址,*(pa+i)就找到了arr2,此时*(*(pa+1)+j)=*(arr2+j),arr2+j找到arr2数组中下标为j元素的地址,再通过 * 就访问到了其所对应的元素,即arr2数组中下标为j的元素

4.由此我们可以得到


3.数组指针

3.1数组指针的定义

前面我们已经说过

int* pa;   int型指针,指针指向的类型为int型

char* pa;   char型指针,指针指向的类型为char型

⭐ 由此可以推测,数组指针就是指向数组的指针

那么数组指针又是怎么定义的呢?

int *p1[10];
int (*p2)[10];
//p1, p2分别是什么?

1. 在这里运算符主要有三种,他们有优先级是:

*  < [ ] < ( )

2. 变量类型先与那个运算符结合就决定了他的本质。

如果先与 * 结合,那么他是指针;如果先与[ ]结合,那么他是数组

分析:

int* p1[10]

p1先与[ ]结合,说明p1是一个数组变量,数组中有十个元素,所以p1是一个数组,每个元素都是 int*型,所以p1叫做指针数组

int (*p2)[10]

p2先和 * 结合,说明p2是一个指针变量,然后指针指向的是一个拥有10个整型的数组。所以p是一个指针,指向一个数组,叫数组指针
 


3.1.1指针的类型 

🔈  将指针的名字忽略就是指针的类型

int* arr1;   // arr1 的类型是 int*

char* arr2;   // arr2 指针的类型是 char*

  • 12
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值