数组和指针的区别

  • 一、概念

    数组:数组就是存储多个相同类型数据的集合

    指针:指针相当于一个变量,但是它和变量不同,它存放的是变量在内存空间中的位置

 

  • 二、赋值、存储方式、求sizeof、初始化

      1. 赋值:同类型指针变量可以相互赋值,数组不行,只能一个一个元素的赋值或copy

      2. 存储方式

        数组:数组在内存中是连续存放的,开辟一块连续的内存空间。数组是根据数组下标进行访问的,多维数组在内存中是按照一维数组存储的,只是在逻辑上是多维的

        数组存储方式:数组的存储空间,不是在静态区就是在栈上

        指针:指针很灵活,它可以指向任意类型的数据。指针的类型说明了它所指向地址空间的内存

        指针存储方式:指针的存储空间不能确定,由于指针本身就是一个变量,再加上它所存放的也是变量,所以确定不了。

      3. 求sizeof

        数组:数组所占存储空间的内存:sizeof(数组名)、数组的大小:sizeof(数组名)/ sizeof(数据类型)

        指针:在32位平台下,无论指针的类型是什么,sizeof(指针名)都是4,在64位平台下,无论指针的类型是什么,sizeof(指针名)都是8

      4. 初始化

        数组:

1char a[] = {"Hello"}; //按字符串初始化,大小为62char b[] = {'H', 'e' , 'l' , 'l', 'o'};//按字符初始化(没有结束符),大小为53char c[] = {'H', 'e' , 'l' , 'l', 'o', '\0' };//按字符初始化,大小为6
关于数组的创建和销毁,尤其是多维数组的创建与销毁
(1)一维数组:
        int *arr = new int[n]; //创建一维数组
        delete[] arr; //销毁2)二维数组
        int **arr = new int*[row]; //相当于创建了多少行数组
        for(int i = 0; i < row; i++)
        {
            arr[i] = new int[col]; //到这里才创建好
        }
        //释放
        for(int i = 0; i < row; i++)
        {
            delete[] arr[i];
        }

        delete[] arr;

      指针:

//(1)指向对象的指针:()里面的值是初始化值
int *p = new int(0); delete p;
//(2)指向数组的指针:n表示数组的大小,值不必再编译时确定,可以在运行时确定
int *p = new int[n];
//(3)指向类的指针:若构造函数有参数,则new class后面有参数,否则调用默认构造函数,delete调用析构函数
Class *p = new Class; delete p;
//(4)指针的指针:二级指针
int **pp = new (int *)[1];
pp[0] = new int[6];
delete[] pp[0];

      这里需要区分两个重要概念:指针数组,数组指针

      指针数组:看前面形容词所修饰的,用指针来修饰数组,所以是一个数组,数组的每个元素存放的是一个指针类型的元素

int *arr[8];
//优先级问题,[]的优先级比*高
//说明arr是一个数组,而int *是数组里面的内容
//这局话的意思是:arr是一个含有8个int *的数组

      数组指针:看前面所修饰的,用数组来修饰指针,所以是一个指针,该指针指向一个数组

int (*arr)[8];
//优先级问题,() 比 [] 高,[] 比 *高,因此在写指针数组的时候需要用()将*arr给括起来
//arr和*结合,说明是一个指针变量
//这句话的意思是,指针arr指向一个大小为8个整形的数组

      三、传参

      数组

      数组在传参时会退化为指针,先来看一下什么是退化

      退化的意义:C语言只会以值拷贝的方式传递参数,参数传递时,如果只拷贝整个数组,效率会大大降低,并且参数位于栈上,太大的数组拷贝将会导致内存溢出,因此C语言将数组的传参进行了退化,将整个数组拷贝一份进入函数时,将数组名看做常量指针,传数组首元素的地址。

      一维数组的传参

//传参方式正确,用数组的方式传递参数,不需要指定参数的大小,因为在一堆数组传参时,形参不会真实的创建数组,传的只是数组首元素的地址。
void test(int arr[])
{}

//传参方式正确,不传参数是可以的,当然传递参数完全没问题
void text(int arr[10])
{}

//传参方式正确,一堆数组传参退化,用指针进行接收,传的是数组首元素的地址
void text(int *arr)
{}

//传参方式正确,int *arr[20]是指针数组,传过去的是数组名
void text2(int *arr[20])
{}

//传参方式正确,传过去的是数组的数组名,代表首元素地址,首元素是个指针向数组的指针,再取地址,就表示二级指针,用二级指针接收
void text2(int *arr)
{}

int main()
{
  int arr[10] = {0};  
  int *arr2[20] = {0};
  text(arr);
  text(arr2);
}

      二维数组的传参

//传参正确,表面二维数组的大小,三行五列
void text(int arr[3][5])
{}

//传参不正确,二维数组的两个方括号,不能全部为空,而不能第二个为空,只能第一个为空
void text(int arr[][])
{}

//传参正确,arr是一级指针,可以传给二级指针,但是不能正确读取
void text(int *arr)
{}

//传参不正确,这里的形参是指针数组,是一维的,可以传参,但是读取的数据不正确
void text(int *arr[5])
{}

//传参正确,传过去的是二维数组的数组名,即数组首元素的地址,也就是第一行的地址,第一行也是个数组,用一个数组指针接收
void text(int (*arr)[5])
{}

//传参不正确,可以传参,但是在读取的时候回有级别不同的问题
void text(int *arr)
{}

int main()
{
  int arr[3][5] = {0};
  test(arr);
}

 

posted @ 2020-09-24 16:36  青团青  阅读(3383)  评论(0编辑  收藏  举报