文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

一篇文章带你了解C语言指针进阶

2024-04-02 19:55

关注

1.字符指针

我们已经知道了数组名在大部分时候表示数组的地址,指针本质上也表示一个地址,那么我们能否用指针来创建一个字符串呢?


int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abcdef";
	const char* p1 = "abcdef";
	const char* p2 = "abcdef";//const可省略,默认为常量字符串
	printf("%s\n", arr1);
	printf("%s\n", arr2);
	printf("%s\n", p1);
	printf("%s\n", p2);
	return 0;
}

需要注意的是字符指针创建的字符串是常量字符串,普通的字符串只要数组名不同即使字符串内容相同,也是不同的字符串,但是不论用多少个指针创建字符串,只要字符串内容相同,所有指针指向的就是同一个字符串,因此字符指针指向的字符串不能修改,在没有const修饰的情况下也是如此。

2.指针数组

我们知道数组可以存储整形,浮点型,或自定义的结构体,那么可不可以存储指针呢?答案是:可以。元素都为指针的数组就称为指针数组,形式为:数据类型* 数组名[ ],例如:储存整形指针的指针数组创建成int*p[10],表示的就是一个包含十个指针元素的数组,利用指针数组我们可以访问指针数组内的指针进而操作变量或其他数组。


int main()//利用指针数组分别遍历三个数组
{
	int arr1[] = { 1, 2, 3, 4, 5 };
	int arr2[] = { 2, 3, 4, 5, 6 };
	int arr3[] = { 3, 4, 5, 6, 7 };
	int*parr[] = { arr1, arr2, arr3 };
	int i, j;
	int Sz = sizeof(parr) / sizeof(parr[0]);
	int sz = sizeof(arr1) / sizeof(arr1[0]);
	for (i = 0; i < Sz; i++)
	{
		for (j = 0; j < sz; j++)
		{
			printf("%d ",*(parr[i]+j) );
		}
		printf("\n");
	}
}

3.数组指针

我们知道指针可以指向整形,浮点型,或自定义的结构体,那么能不能指向数组呢?答案也是:可以。指向数组的指针称为数组指针,形式为:数据类型(*p)[ ] ,例如int(*p)[10],表示的就是一个指向包含十个元素数组的指针,这和指针数组的区别在于要将*p用小括号括起来以确保它是一个指针而非数组(无括号的情况下p先和 [ ]结合)。


int main()利用数组指针遍历数组
{
	int arr[6] = { 1, 2, 3, 4, 5, 6 };
	int(*p)[6] = &arr;
	int i;
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (i=0;i<sz;i++)
	printf("%d", (*p)[i]);
	//int*arr[5];
	//int*(*p)[5]=&arr;//int(*p[10])[5]-->p[10]是一个指针数组,剩下int(*  )[5]的是数组的类型,类型为数组指针,p是一个数组有十个元素,每个元素都是一个数组指针,指向的数组有五个int类型的元素
	return 0;
}

有了指针数组和数组指针,我们还可以进行两者的嵌套使用,例如:数组指针数组(int(*p[ ])[ ]),指针数组指针(int*(*p)[ ]),前者是一个数组里面的元素是指向另外一些数组的指针,后者是个指针指向一个元素全为另外一些指针的数组。


void print(int(*p)[5],int x,int y)//用数组指针接收数组地址
{
	int i,j;
	for (i = 0; i < x; i++)
	{
		for (j = 0; j < y; j++)
		{
			printf("%d ", *(*(p + i) + j));//arr[i]==*(arr+i)==*(p+i)==p[i]
		}
		printf("\n");
	}
}
int main()//利用数组指针遍历二维数组
{
	int arr[3][5] = { { 1, 2, 3, 4, 5 }, { 2, 3, 4, 5, 6 }, { 3, 4, 5, 6, 7 } };
	print(arr, 3, 5);//arr是首元素地址,二维数组的首元素是个第一行的一维数组
	return 0;
}

4.函数指针

我们知道指针可以指向整形,浮点型,自定义的结构体和数组,那么能不能指向一个函数呢?答案同样是:可以。函数指针的形式为:函数返回类型(*p)(参数类型,参数类型....)例如:int(*p)(int,int)表示的就是一个指向返回类型为整形,两个参数类型也是整形的函数的指针。注意:利用函数指针调用函数时有几个解引用操作符都可以没有也可以,但是括号不可或缺!


int Mul(int x, int y)
{
	return x*y;
}
int main()
{
	int a, b;
	scanf("%d%d", &a, &b);
	int(*p)(int,int) = &Mul;//函数指针,有无&都可以
	printf("%d", (p)(a, b));//用指针调用函数(*(void(*)()0))()
	printf("%d", (*p)(a, b)); 
	printf("%d", (**p)(a, b));
	printf("%d", (***p)(a, b));//任意个数的*都可以
	return 0;
}

5.数组传参

我们知道简单的一维数组的传参方式:数组名是首元素地址,我们可以直接用指针接收也可以直接用数组接收,那么指针数组和二维数组呢?指针数组传参传的也是其首元素的地址,而它的首元素是一个指针,指针的地址我们当然用二级指针接收,同样地我们也可以直接指针数组接收。二维数组传参传的是其首元素的地址,要注意的是,二维数组的首元素并不是第一个元素而是第一行元素所构成的一维数组,一维数组的地址我们当然用数组指针接收,同样地,我们也可以直接用二维数组接收。


void test1(int arr[])//直接数组接收
{
	printf("%d\n", arr[]);
}
void test2(int*arr)//指针接收首元素地址
{
	printf("%d\n", arr[]);
}
void test3(int arr[][5])//二位数组直接接收
{
	printf("%d\n", arr[][5]);
}
void test4(int(*arr)[5])//数组指针接收
{
	printf("%d\n", arr);
}
void test5(int*arr[])//直接指针数组接收
{
	printf("%d\n", arr);
}
void test6(int**arr)//二级指针接收
{
	printf("%d\n", arr);
}
int main()
{
	int arr1[5] = {1,2,3,4,5};
	int arr2[3][5] = {1,2,3,4,5};
	int* arr3[5] = {NULL};
	test1(arr1);
	test2(arr1);
	test3(arr2);
	test4(arr2);
	test5(arr3);
	test6(arr3);
	return 0;
}

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯