前言
❤️ 铁汁们大家好,欢迎大家来到出小月的博客里, 🤗🤗🤗之前呢,我分享了C语言的小游戏“扫雷”。。。。今天呢,给大家分享指针篇,,希望大家看完我这篇文章都能够“涨芝士”,感觉小月写的还不错的话,记得👍🏻点赞加关注😘鼓励一下博主哦,不然下次可找不到我啦❗❗
作者简介
❤️ 作者的gitee:出小月;
❤️ 作者的主页:出小月的《程序员历险记》
❤️专栏:《C语言》,《数据结构初阶》
😊希望大家都能够:好好学习,天天编程❗❗❗
一、字符指针
🐻在指针的类型中我们知道有一种指针类型为字符指针 char* ;
字符指针是一个指针变量,它里面存放的就是一个字符的地址
例1️⃣
int main()
{
char ch = 'w';
char* pch;//定义一个字符指针pch
pch = &ch;//指针pch里面存放的就是ch的地址
printf("%c", *pch);//解引用
return 0;
}
还有一种用法:
例2️⃣
int main()
{
char arr[] = "abcdef";
char* pc = arr;//数组名就是首元素的地址
printf("%s", arr);
return 0;
}
🐻注意:这里不是把整个字符串的地址放到指针变量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;
}
🤗注意:这里的“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️⃣
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;
}
图解如下:⬇️
注意:* (*(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;
}
实际上: &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;
}
例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;
}
对于二维数组,我们把它想成一维数组,那么二维数组的首元素就是第一行,所以arr就是指向第一行,int( * arr)[5],是一个数组指针,指向二维数组的第一行,y可以传参。 * ((arr+i)+j), arr+i是指向第i行的指针, * (arr+i)就是第i行的首元素的地址, * ( arr+i)+j就是第i行第j个元素的地址, * ((arr+i)+j)就是第i行第j个元素的值
总结
🤗🤗今天的分享就到这了,感觉小月写的还不错的话,记得点赞收藏一波啊,这只是指针的一部分哦,还有指针后面❗❗❗