C语言----关于二维数组传参的本质相关的知识点(数组指针、指针数组)

简介: C语言----关于二维数组传参的本质相关的知识点(数组指针、指针数组)
//指针数组
// 1.是数组
// 2.是存放指针的数组
// char* arr[6]---数组元素类型+数组名+[元素个数]---存放字符指针的数组
// int * arr[5]---存放整型指针的数组
// 
// 
// 数组指针
// 
// 
// 字符指针---char*pc--指向字符的,变量中存放的是字符的地址
// 整型指针---int*pi---指向整型,变量中存放的是整形数字的地址
// 
// 那么数组指针就是指向数组的指针
// *p--说明这个是指针
// [元素个数]--说明前面的p是指向后面的数组的
// (*p)添加括号,不然p会与后面的[元素个数]进行组合,p就成数组名了,所以在定义数组指针的时候要将*p括起来
// (*p)[10]
// int(*p)[10]--说明p是数组指针,数组内有10个元素,每个元素有的类型是int
// 
// 那么p的类型就是int(*)[10]
//int main()
//{
//    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
//    int(*p)[10] = &arr;//取出的是数组的地址
//    //把一个数组指针的地址取出来放到数组指针变量内
//
//    //使用p数组指针来访问arr数组的内容
//
//    for (int i = 0; i < 10; i++)
//    {
//        //printf("%d", *p);//因为p里面存放的是数组的地址,那么解引用就是拿到了整个数组的地址
//        //所以如果我们想访问这个数组的每个元素,我们需要做出改变
//
//        printf("%d", (*p)[i]);//(*p)访问了这个数组,后面加上[i],随着i的变化访问数组内的元素
//        //就相当于在打印arr[i],因为p里面存的是数组的地址,*p=arr
//    }
//    return 0;
//}
//上面的方法略显复杂,我们进行变更
//int main()
//{
//    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
//    int*p= arr;//存放数组首元素的地址,直接创建指针来存放数组首元素的地址
//
//    for (int i = 0; i < 10; i++)
//    {
//        
//        printf("%d ", p[i]);//p[i]---*(p+i)--随着i的变化访问数组内的元素
//    }
//    return 0;
//}
 
// 上面的使用数组指针访问数组有点麻烦,远不及其他的方法
//那么数组指针到底在什么地方能用上呢?
// 
// 二维数组传参
//常规方式:
//void print(int arr[3][5], int r, int c)//传过来的数组就创建一个数组来接收数组
//{
//    //两层循环遍历数组,第一层解决行,第二层解决列
//    for (int i = 0; i < r; i++)
//    {
//        for (int j = 0; j < c; 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);//借助函数将数组打印出来,将数组名传过去,3行5列也传过去
//
//    return 0;
//}
//
//一维数组的数组名是数组首元素的地址
// 二维数组的数组名也是数组首元素的地址
// 对于上面的这个二维数组,可以理解为存放3个一维数组的数组
// 二维数组的每一行可以理解为每一行就是一维数组
// 
// 那么二维数组的数组名是首元素的地址,所以二维数组的地址就是第一行的地址
// 
//
void print(int (*arr)[5], int r, int c)//传过来的数组就创建一个数组来接收数组
{//传过来的是第一行的一维数组的地址,我么用数组指针接收
    //这个数组指针指向的是第一行的一维数组的5个元素
    // 每个元素的返回类型就是int  
    // 所以我们用int (*arr)[5]这个数组指针来接收
    // 
    //两层循环遍历数组,第一层解决行,第二层解决列
    for (int i = 0; i < r; i++)
    {
        for (int j = 0; j < c; 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);//arr是数组首元素的地址,就是第一行的一维数组地址,不是这个一维数组首元素的地址
    //这里传过去的是第一行一位数组的的地址,就是第一行一维数组的地址
    //数组的地址传过去了,我们要用数组指针来接受
    return 0;
}
//形参是传的是数组首元素的地址,那么我们就创建数组指针来接收
//对于这个数组来说
//
// 
// 第一行1 2 3 4 5
// 第二行2 3 4 5 6
// 第三行3 4 5 6 7
// 
// arr指向的是第一行的,当我们想指向第二行,我们就需要arr+1,
// 因为是指向数组的指针,所以+1就是直接跳过一个数组
// 那么想找到第三行的时候就直接arr+2
//
// 那么在上面的循环里,打印这个二维数组我们就能这么写
// *(arr+i)
// arr+i就是这个二维数组内三个一维数组的地址,那么我们对其进行解引
// 用就能访问这三个数组的内容了
// 
// *(arr+i)就是想当与拿到这一行
// 
// 那我们已经拿到了这一行,我们该如何访问每一个元素呢?
// 我们 还是得通过下标访问数组内的每个元素
//
// 
// 因为这个函数有两个循环,那么第二个循环就是我们访问这三个一维数组内的每个元素了
// 那我们就在后面添加[j]访问每个元素,
// 前面的(*(arr+i))就是把访问这个二维数组内的三个一维数组
// 那么在后面加上[j]就能访问到每个元素了
// (*(arr+i))[j]------第一种写法
// 
// 
// *((*(arr+i)+j))--第二种写法
// 解释:
 
// 因为实参传过来的是arr是二维数组的数组名,那么我们是用一个数组指针进行接收的
// ,所以arr是一个数组指针
// 这里的arr是指针啊,数组指针
// arr数组内存放的是这个二维数组里面的第一个一维数组的地址
//*(arr+i)得到的是第i行的数组的首地址,也是指向第i行第一个元素的指针
//为什么解引用得到的是地址呢?
// 
// 因为arr+i里面存放就是第i行的地址 
// 对其进行解引用得到的就是第i行的地址
// *(arr+i)得到的是第i行的地址,
// 同样,arr+i里面存的是一维数组首元素的地址,对其进行解引用得到的是地址,是数组首元素的地址
// *(arr+i)得到的是一维数组首元素的地址
//那么*(arr+i)+j得到的就是这一下标为j的地址
// 对整体再次进行解引用就得到了i行j列的元素了
// 
//记住,这里的arr是一个数组指针

末尾涉及到(*(arr+i))[j]和 *((*(arr+i)+j))的区别

尽管二者相同但有些知识点十分复杂

关键点,这里的arr是一个数组指针,存放的是这个二维数组内的一个一维数组的地址(二维数组的首元素就是这个一维数组)

在这个函数里面arr仅仅只是一个指针

相关文章
|
1天前
|
C语言
指针进阶(C语言终)
指针进阶(C语言终)
|
1天前
|
编译器 C语言
指针进阶(数组指针 )(C语言)
指针进阶(数组指针 )(C语言)
|
3天前
|
C语言
【C语言】:详解函数指针变量,函数指针数组及转移表
【C语言】:详解函数指针变量,函数指针数组及转移表
9 2
|
3天前
|
C语言
【C语言】:详解指针数组,数组指针及(二维)数组传参(2)
【C语言】:详解指针数组,数组指针及(二维)数组传参(2)
6 1
|
3天前
|
Serverless C语言
【C语言】:对(一维)数组与指针的深入理解(1)
【C语言】:对(一维)数组与指针的深入理解(1)
6 1
|
13天前
|
安全 程序员 编译器
【C语言基础】:深入理解指针(二)
【C语言基础】:深入理解指针(二)
【C语言基础】:深入理解指针(二)
|
1天前
|
C语言
指针进阶(回调函数)(C语言)
指针进阶(回调函数)(C语言)
|
1天前
|
存储 C语言 C++
指针进阶(函数指针)(C语言)
指针进阶(函数指针)(C语言)
|
3天前
|
存储 C语言
C语言的函数返回值和指针
C|函数返回值(区分各类值)和指针(区分各类存储空间)的细节
|
6天前
|
C语言
C语言----深入理解指针(5)(一)
C语言----深入理解指针(5)
12 2