• 【指针详解】(上)看一遍就会❗❗❗家人们冲❗


    前言

    ❤️ 铁汁们大家好,欢迎大家来到出小月的博客里, 🤗🤗🤗之前呢,我分享了C语言的小游戏“扫雷”。。。。今天呢,给大家分享指针篇,,希望大家看完我这篇文章都能够“涨芝士”,感觉小月写的还不错的话,记得👍🏻点赞加关注😘鼓励一下博主哦,不然下次可找不到我啦❗❗


    作者简介

    ❤️ 作者的gitee:出小月
    ❤️ 作者的主页:出小月的《程序员历险记》
    ❤️专栏:《C语言》,《数据结构初阶》
    😊希望大家都能够:好好学习,天天编程❗❗❗



    一、字符指针

    🐻在指针的类型中我们知道有一种指针类型为字符指针 char* ;
    字符指针是一个指针变量,它里面存放的就是一个字符的地址

    例1️⃣

    int main()
    {
    	char ch = 'w';
    	char* pch;//定义一个字符指针pch
    	pch = &ch;//指针pch里面存放的就是ch的地址
    	printf("%c", *pch);//解引用
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述
    还有一种用法:

    例2️⃣

    int main()
    {
    	char arr[] = "abcdef";
    	char* pc = arr;//数组名就是首元素的地址
    	printf("%s", arr);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述
    🐻注意:这里不是把整个字符串的地址放到指针变量pc中了,而是把字符串“abcdef”首字符的地址放到指针变量pc中。

    例3️⃣

    int main()
    {
    	char arr1[] = "chuxiaoyue";
    	char arr2[] = "chuxiaoyue";
    	char* pa1 = "chuxiaoyue";
    	char* pa2 = "chuxiaoyue";
    	if (arr1 == arr2) 
    	{
    		printf("arr1和arr2相同\n");
    	}
    	else
    	{
    		printf("arr1和arr2不同\n");
    	}
    	if (pa1 == pa2)
    	{
    		printf("pa1和pa2相同\n");
    	}
    	else
    	{
    		printf("pa1和pa2不同\n");
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    在这里插入图片描述
    🤗注意:这里的“chuxiaoyue”是一个常量字符串,当用相同的常量字符串去初始化不同的数组时,就会开辟出不同的内存块,因此arr1和arr2不同
    c或c++会把常量字符串存储到单独的一个内存区域,当几个指针,同时指向一个字符串,实际上,它们指向的是相同的内存,因此pa1和pa2相同

    二、指针数组

    🤗好孩子是孩子,那指针数组是一个数组

    int arr1[5]={0};//整形数组
    char arr2[5]={0};//字符数组
    int* arr3[5];//存放整形指针的数组=>指针数组
    char* arr4[5];//存放字符指针的数组=>指针数组
    
    int a=10;
    int b=20;
    int c=30;
    int d=40;
    int *arr[]={&a,&b,&c,&d};//arr[]就是一个指针数组,数组存放的就是地址;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    例1️⃣

    int main()
    {
    	int arr1[] = {1,2,3,4,5};
    	int arr2[] = { 1,2,3,4,5 };
    	int arr3[] = { 1,2,3,4,5 };
    	int* arr[] = { arr1,arr2,arr3 };//arr[]是一个指针数组,存放的是地址,数组名就是地址
    	int i = 0;
    	for (i = 0; i < 3; i++)
    	{
    		int j = 0;
    		for ( j = 0; j < 5; j++)
    		{
    			printf("%d ", *(*(arr+i)+j));
    		}
    		printf("\n");
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    图解如下:⬇️
    在这里插入图片描述
    注意:* (*(arr+i)+j) 这里arr是一个数组名 就是arr[]这个数组首元素的地址,即arr1的地址,arr+1就是arr2的地址,因此 *(arr+0)就是arr1,而arr1是数组arr1[]首元素的地址,因此 *(arr+0)是数组arr1[]首元素的地址, *(arr+0)+1是数组arr1[]的第二个元素的地址,所以 *( *(arr+0)+1)就是数组arr1[]的第二个元素的值。

    三、数组指针

    🐻好孩子是孩子,数组指针是指针,数组指针就是指向数组的指针

    例1️⃣

    int ( * p)[10];
    解释:p先和 * 结合,说明p是一个指针变量,然后指针指向的是一个大小为10个整型的数组。所以p是一个指针,指向一个数组,叫数组指针。
    这里要注意:[]的优先级要高于号的,所以必须加上()来保证p先和结合。

    例2️⃣

    在int a[10]中,a是首元素的地址,而&a是数组的地址,那它们两个一样吗?显然不一样

    int main()
    {
    	int arr[5] = { 0 };
    	printf("%p\n", arr);
    	printf("%p\n", &arr);
    	printf("%p\n", arr+1);
    	printf("%p\n", &arr+1);
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述
    实际上: &arr 表示的是数组的地址,而不是数组首元素的地址。
    本例中 &arr 的类型是: int(*)[10] ,是一种数组指针类型
    数组的地址+1,跳过整个数组的大小,所以 &arr+1 相对于 &arr 的差值是20.

    例3️⃣

    int main()
    {
    	int a[5] = { 1,2,3,4,5 };
    	int(*p)[5] = &a;
    	for (int i = 0; i < 5; i++)
    	{
    		printf("%d ",*(*p+i));//对p解引用就是数组名,数组名是首元素的地址
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    例4️⃣

    void print_arr2(int(*arr)[5], int row, int col)
    {
    	int i = 0;
    	for (i = 0; i < row; i++)
    	{
    		int j = 0;
    		for (j = 0; j < col; j++)
    		{
    			printf("%d ",*(*(arr+i)+j));
    		}
    		printf("\n");
    	}
    }
    int main()
    {
    	int arr[3][5] = {{1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7}};
    	print_arr2(arr, 3, 5);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    对于二维数组,我们把它想成一维数组,那么二维数组的首元素就是第一行,所以arr就是指向第一行,int( * arr)[5],是一个数组指针,指向二维数组的第一行,y可以传参。 * ((arr+i)+j), arr+i是指向第i行的指针, * (arr+i)就是第i行的首元素的地址, * ( arr+i)+j就是第i行第j个元素的地址, * ((arr+i)+j)就是第i行第j个元素的值

    总结

    🤗🤗今天的分享就到这了,感觉小月写的还不错的话,记得点赞收藏一波啊,这只是指针的一部分哦,还有指针后面❗❗❗

  • 相关阅读:
    3.通过局部刷新爬取数据案例
    golang本地缓存库之bigcache
    酷开科技丨这么好用的酷开系统,不用真的会后悔!
    软件测试经验盘点:测试人的至暗时刻&高光时刻
    MYSQL——JBDC实现增删改查
    JavaSE复习总结
    YOLO V1学习总结
    TVM 源码阅读PASS — VectorizeLoop
    【C++】string类
    java面试题及答案2020 大汇总
  • 原文地址:https://blog.csdn.net/weixin_69323265/article/details/128064016