一日不见,如隔三秋。思念如水流,时间越久越长;想你的心情如潮水,波涛汹涌澎湃!
想我了吗,朋友们,今天又是学习的一天
1,二级指针
我们知道一级指针,可以用来存放我们数据类型变量的地址,竟然我们已经有了一级指针,然后一级指针必然在空间中也有地址。
(^_−)☆我们如何去存放一级指针的地址呢?
这时候我们就要学习我们的二级指针,
我们看下面的那个代码。~(^◇^)/
#include <stdio.h>
int main()
{
int a = 0;
int* p = &a;
printf("%p\n", p);
int** pp = &p;
printf("%p\n", pp);
}
在上面的代码中p是指针变量是属于一级指针,他的类型是int*,而对于上面代码中的PP也是指针变量,但是他的类型是int **
他的对象指向是int * ~(з)-☆
同理我们也能作出三级指针
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
int a = 0;
int* p = &a;
printf("%p\n", p);
int** pp = &p;
printf("%p\n", pp);
int*** ppp = &pp;
printf("%p\n", ppp);
}
2,指针数组
理解;当我们第一次看到指针数组,是否在心中有疑问指针数组是数组还是指针,举个例子整形数组是整型还是数组,毫无疑问是数组,所以指针数组是数组,
int arr[10]
上面的是整形数组,存放的每个元素是整形
char arr[10]
上面的是字符数组,存放的每个元素是整形,字符有AISS表,他们是有对应的数字的
int* arr4[3] = { arr,arr2,arr3 }; //整形指针数组
所以指针数组里面都是指针,帅哥美女明白了吗?像int * arr[]
接下来我们去实现模拟二维数组来认识一下组指数组(模仿的是效果)
二维数组;每行是一个一维数组
#include<stdio.h>
int main()
{
int arr[] = { 1,2,3,4,5 };
int arr2[] = { 2,3,4,5,6 };
int arr3[] = { 3,4,5,6,7 };
int* arr4[3] = { arr,arr2,arr3 };
int i = 0;
for (i = 0; i < 3; i++)
{
int j = 0;
for (j = 0; j < 5; j++)
{
printf("%d ", arr4[i][j]);
}
printf("\n");
}
return 0;
}
我们来了解一下这个模拟的数组,首先我们将拿到的第一个数组的地址arr[0],
在int * arr4[]={arr,arr2,arr3}中其实arr4是数组,所以数组是有下标的当我们拿到下标是0的元素时,我们就拿到了arrd的数组的内容也就是,arr数组的首元素的地址,我们将他打印下来;
arr4[0][j] int arr -------------------> (这里地址)1,2,3,4,5
arr4[1][j] int arr2 -------------------> (这里地址)2,3,4,5,6
arr4[2][j] int arr3 -------------------> (这里地址)3,4,5,6,7
像上次的组指文章中我介绍过arr[i]==*(arr+i),所以这里arr4[i][j]==*(*(arr+i)+j);
3,字符指针变量
在指针的类型中我们知道有⼀种指针类型为字符指针 char*
int main()
{
char ch = 'w';
char *pc = &ch;
*pc = 'w';
return 0;
}
还有⼀种使⽤⽅式如下:
int main()
{
const char* pstr = "hello";//这⾥是把⼀个字符串放到pstr指针变量⾥了吗?
printf("%s\n", pstr);
return 0;
}
代码 const char* pstr = "hello"; 特别容易让我们以为是把字符串 hello放到字符指针 pstr ⾥了,但是本质是把字符串 hello,⾸字符的地址放到了pstr中。上⾯代码的意思是把⼀个常量字符串的⾸字符 h 的地址存放到指针变量 pstr 中。
关于上面的代码我们可以使用有趣的方式去了解例如
int main()
{
char* p = "asdfgh";
printf("%c\n", *p);
return 0;
}
或者这样打印
int main()
{
char* p = "asdfgh"; //是常量字符串,不能修改,最好加个const
printf("%c\n", "asdfgh"[3]); //这里p[3]也是一样的,盆友
return 0;
}
y也可以全部打印
int main()
{
char* p = "asdfgh";
int i = 0;
for (i = 0; i <= 6; i++)
{
// printf("%c\n", "asdfgh"[i]);
printf("%c\n", *(p+i));
}
return 0;
}
这样我们就可以将“asdfgh”像想成一个数组,这样只是用来理解的不要将“asdfgh”当成有个数组
接下来我们来见识一下一道笔试题目
#include <stdio.h>
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;
}
我们可以使用这样的方式去认识,是否相同就像str1和str2是数组,数组是可以修改的
常量字符串是不能修改的。
4,数组指针变量
之前我们学习了指针数组,指针数组是⼀种数组,数组中存放的是地址(指针)。
数组指针变量是指针变量?还是数组? 答案是:指针变量。 我们已经熟悉:
• 整形指针变量: int * pint; 存放的是整形变量的地址,能够指向整形数据的指针。
• 浮点型指针变量: float * pf; 存放浮点型变量的地址,能够指向浮点型数据的指针。
那数组指针变量应该是:存放的应该是数组的地址,能够指向数组的指针变量
我们可以看一下代码
int main()
{
int a = 10;
int* pa = &a;
char b = 'w';
char pb = &b;
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int(*parr)[10] //这个是数组指针
return 0;
}
我们来判断一下下⾯代码哪个是数组指针变量?
int *p1[10];
int (*p2)[10];
先看p1;首先当我们的p1与【】在一起时先和【】结合,所以p1[10]是数组,然后加上*就构成了我们的指针数组
其这次p2;为了防止p2与【】在一起时先和【】结合,我们将使用()将p2和【】隔开;所以p2不是指针数组
P1是数组,数组有10个元素,每个元素的类型是int*
P2是指针,指针指向的是数组,数组有10个元素,每个元素的类型是int,p2是数组指针
int (*p) [10] = &arr;
| | |
| | |
| | p指向数组的元素个数
| p是数组指针变量名
p指向的数组的元素类型
我们可以所以数组指针去打印数组的内容,但是在这里我们要说不建议这样去完成;
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int se = sizeof(arr) / sizeof(arr[0]);
int i = 0;
int(*p)[10] = &arr;
for (i = 0; i < se; i++)
{
printf("%d ", (*p)[i]);
}
}
5,⼆维数组传参的本质
有了数组指针的理解,我们就能够讲⼀下⼆维数组传参的本质了。
过去我们有⼀个⼆维数组的需要传参给⼀个函数的时候,我们是这样写的:
先来个⼆维数组的传参(平常)
void print(int arr[3][5], int x, int y)
{
int i = 0;
for (i = 0; i < x; i++)
{
int j = 0;
for (j = 0; j < y; 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(arr,3,5);
return 0;
}
这⾥实参是⼆维数组,形参也写成⼆维数组的形式,那还有什么其他的写法吗?
⾸先我们再次理解⼀下⼆维数组,⼆维数组起始可以看做是每个元素是⼀维数组的数组,也就是⼆维 数组的每个元素是⼀个⼀维数组。那么⼆维数组的⾸元素就是第⼀⾏
所以,根据数组名是数组⾸元素的地址这个规则,⼆维数组的数组名表⽰的就是第⼀⾏的地址,是⼀
维数组的地址那就意味着⼆维数组传参本质上也是传递了地址,传递的是第⼀
⾏这个⼀维数组的地址,那么形参也是可以写成指针形式的。如下
接下来我们使用数组指针来一个
void print(int (*arr)[5], int x, int y)
{
int i = 0;
for (i = 0; i < x; i++)
{
int j = 0;
for (j = 0; j < ; 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(arr,3,5);
return 0;
}
总结:⼆维数组传参,形参的部分可以写成数组,也可以写成指针形式