一日不见,如隔三秋。思念如水流,时间越久越长;想你的心情如潮水,波涛汹涌澎湃!

想我了吗,朋友们,今天又是学习的一天

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);

}

小白入门指针(五)----新手_传参_02



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;

}



小白入门指针(五)----新手_指针变量_03

我们来了解一下这个模拟的数组,首先我们将拿到的第一个数组的地址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;
}

小白入门指针(五)----新手_二级指针_04

或者这样打印

int main()

{
    char* p = "asdfgh";  //是常量字符串,不能修改,最好加个const

    printf("%c\n", "asdfgh"[3]);  //这里p[3]也是一样的,盆友

    return 0;
}

小白入门指针(五)----新手_指针数组_05

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;
}


小白入门指针(五)----新手_指针变量_06

这样我们就可以将“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;
}

小白入门指针(五)----新手_二级指针_07


我们可以使用这样的方式去认识,是否相同就像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]);
    }
}

小白入门指针(五)----新手_指针变量_08


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;

}


小白入门指针(五)----新手_指针数组_09

这⾥实参是⼆维数组,形参也写成⼆维数组的形式,那还有什么其他的写法吗?

⾸先我们再次理解⼀下⼆维数组,⼆维数组起始可以看做是每个元素是⼀维数组的数组,也就是⼆维 数组的每个元素是⼀个⼀维数组。那么⼆维数组的⾸元素就是第⼀⾏

所以,根据数组名是数组⾸元素的地址这个规则,⼆维数组的数组名表⽰的就是第⼀⾏的地址,是⼀

维数组的地址那就意味着⼆维数组传参本质上也是传递了地址,传递的是第⼀

⾏这个⼀维数组的地址,那么形参也是可以写成指针形式的。如下

接下来我们使用数组指针来一个

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;

}


小白入门指针(五)----新手_指针数组_10

总结:⼆维数组传参,形参的部分可以写成数组,也可以写成指针形式

拜拜~~

小白入门指针(五)----新手_指针数组_11