浅谈数组-_-

浅谈数组

 

  1. 一维数组的创建和初始化。
    1. 数组的创建

数组是一组相同类型元素的集合。

数组的创建方式:

type_t   arr_name   [const_n];

//type_t 是指数组的元素类型

//const_n 是一个常量表达式,用来指定数组的大小

数组创建的实例:

//代码1 int arr1[10];

//代码2 int count = 10; int arr2[count];//数组时候可以正常创建?

 //代码3 char arr3[10];

float arr4[1];

double arr5[20];

注:数组创建,在C99标准之前, [] 中要给一个常量才可以,不能使用变量。在C99标准支持了变常数组的概念。

目前vs2019不支持变常量

如果变常数组可以实现,也要注意变常数组是不能初始化的

    1. 数组的初始化

数组的初始化是指,在创建数组的同时给数组的内容一些合理初始值(初始化)。 看代码:

int arr1[10] = {1,2,3};//不完全初始化,其他几位自动补成0

int arr2[] = {1,2,3,4};

int arr3[5] = {1,2,3,4,5};

char arr4[3] = {'a',98, 'c'};

char arr5[] = {'a','b','c'};

char arr6[] = "abcdef";

值放多了会报错,告诉你初始化的值太多了

数组在创建的时候如果想不指定数组的确定的大小就得初始化。数组的元素个数根据初始化的内容来确定

但是对于下面的代码要区分,内存中如何分配。

char arr1[] = "abc";//a b c \0(4个字符)

char arr2[3] = {'a','b','c'};// a b c(三个字符)

这里如果写成

Char arr2[3]={‘a’,98,’c’};也一样,这里的98是ascc码值会自己转换成b(98);

如果这样设置 int arr[10];这时候这里的是十个数就是随机值;包括你赋值的数 int a;

这里的a也是随机值;如果一个全局变量不初始化,那么它不是随机值,它是0;

包括静态变量 static。

当我们在写代码的时候,c语言其实有三个区域,一个叫栈区(局部变量,形式参数),一个叫堆区,还有一个叫静态区(全局变量,静态变量);静态区上面数据的特点是,不初始化的话它的值默认为0,栈区上数据的特点是不初始化它的值的话就是随机值;

如果是 char arr【5】=“abc”//这里本来是abc\0。

1.3 一维数组的使用

对于数组的使用我们之前介绍了一个操作符: [ ] ,下标引用操作符。它其实就数组访问的操作符。

  1. 数组是使用下标来访问的,下标是从0开始。

Int arr[100]={1,2,3,4,5,6};

           0 1 2 3 4 5

Printf(“%d”,arr[4]);

这时候就会出现5,因为这里用了下标引用操作符[ ],(有两个操作数arr  4)

我们可以通过下标访问数组

int main()

{

    int arr[100] = {0};

    for (int i = 0; i <= 99; i++)

    {

         arr[i] = i+1;

    }

    for (int i = 0; i <= 99; i++)

    {

         printf("%d ", arr[i]);

    }

    return 0;

}

因为这里有100个元素,每个元素是整型所以结果是400

所以就是sizeof(arr)/sizeof(arr[0])可以得到数组里面的元素个数

    1. 一维数组在内存中的存储

通过地址我们可以发现,每两个数组之间的地址差4个字节,因为一个整型的大小是4个字节,同时我们发现一维数组在内存中连续存放的!随着数组下标的增长,地址是由低到高变化的,数组名是什么,是数组首元素的地址。

%p---打印地址(16进制)

%d---打印整数(10进制)

  1. 二维数组的创建和初始化

2.1 二维数组的创建

int arr[3][4];

char arr[3][5];

double arr[2][4];

二维数组不完全初始化的时候;

如果想在某一行放入自己想放的值可以这里设置

这样可以看出第一行是1,2;第二行是3,4在这一行未设置的部分自动转化成0了

不用行也行。

int main()

{

    int arr[3][5] = { {1,2},{4,5},{5,6} };//把二维数组第一行看成一个数组,第二行跟第三行也分别看成一个数组

    int i = 0;                            //总大小除以第一行的大小等于行数

    for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)

    {

         int j = 0;

         for (j = 0; j < sizeof(arr[0]) / sizeof(arr[0][0]); j++)//第一行的大小除以第一行第一列的大小

         {

             printf("%d ", arr[i][j]);

         }

         printf("\n");

    }

    return 0;

}

打印数组每个元素的地址

我们发现二维数组这么多数之间还是差是个字节,说明他们都是连续的

可以把二维数组想象成几个一维数组

           Arr【0】            arr【1】                   arr【2】

            访问任意一个数组

           Arr【0】【j】        arr【1】【j】                arr【2】【j】

同时可以了解三维数组可以看成三个二维数组arr【3】【4】【5】;

  1. 数组越界

数组的下标是有范围限制的。 数组的下规定是从0开始的,如果数组有n个元素,最后一个元素的下标就是n-1。 所以数组的下标如果小于0,或者大于n-1,就是数组越界访问了,超出了数组合法空间的访问。 C语言本身是不做数组下标的越界检查,编译器也不一定报错,但是编译器不报错,并不意味着程序就 是正确的,所以程序员写代码时,最好自己做越界的检查。

二维数组的行和列也可能存在越界。

  1. 数组作为函数参数

往往我们在写代码的时候,会将数组作为参数传个函数,比如:我要实现一个冒泡排序(这里要讲算法 思想)函数 将一个整形数组排序。那我们将会这样使用该函数:

冒泡排序

数组中两个相邻的元素进行比较,如果不满足顺序就交换

例如我们将arr【】={9,8,77,6,5,4,3,2,1,0};进行升序排列

9 8 7 6 5 4 3 2 1 0           8 7 6 5 4 3 2 1 0 9

8 9 7 6 5 4 3 2 1 0           7 8 6 5 4 3 2 1 0 9

8 7 9 6 5 4 3 2 1 0           7 6 8 5 4 3 2 1 0 9

…………………………             …………………………

8 7 6 5 4 3 2 1 0 9           7 6 5 4 3 2 1 0 8 9

这是一趟冒泡排序           这是第二趟冒泡排序

十个数要经过九趟冒牌排序

第一趟有九次比较,第二趟有八次比较,趟数跟元素个数有关系

void bubble_sort(int arr[])

{

    int sz = sizeof(arr) / sizeof(arr[0]);

    //趟数

    int i=0;

    for (i = 0; i < sz-1; i++)

    {

         //每一趟冒泡排序的过程

         int j = 0;

         for (j = 0; j < sz - 1-i; j++)

         {

             if (arr[j] > arr[j + 1])

             {

                  //交换

                  int tmp = arr[j];

                  arr[j] = arr[j + 1];

                  arr[j + 1] = tmp;

             }

         }

    }

}

int main()

{

    int arr[] = { 9,8,7,6,5,4,3,2,1,0 };

    //写一个冒泡排序

    bubble_sort(arr);

    int i = 0;

    int sz = sizeof(arr) / sizeof(arr[0]);

    for (i = 0; i < sz; i++)

    {

         printf("%d ", arr[i]);

    }

    return 0;

}

我们按照逻辑设计完冒泡排序

发现没有进行排序

通过调试我们发现这里的sz=1;正常情况下sz=10;这里出现了bug

借此我们引出来一个新的问题

数组名是什么?

数组名就是数组首元素地址

有两个例外

printf("%p\n", sizeof(arr));数组名不是首元素地址,表示整个数组

&数组名,数组名不是首元素地址,数组名表示整个数组。取出的是整个数组的地址

三个值一样

给它们三个值加一

前两个加一的效果都是一样的,地址都差4

下面那个加了一个40

数组的每个元素都有地址

&arr+1从10以后开始

数组里面的2其实是arr+1或者&arr[0]+1

之后我们再看冒泡数组的问题

Main函数中的int arr【】={9,8,7,6,5,4,3,2,1,0}

Arr-表示首元素的地址其实就是&arr【0】的地址

本质上void bubble—sort(int arr【】)实际上是int*arr是一个指针

Int sz=sizeof(arr)/sizeof(arr【0】)

因为我们在传参的时候是传递的一个数组名,数组名其实是首元素地址,传过去是要有指针接收,他是一个整型指针

整形指针sizeof(arr)就是 4,sizeof(arr【0】)也是4,4/4=1;

这里的arr【】可以写成这样也可以写成*arr

void bubble_sort(int arr[],int sz)

{

   

    //趟数

    int i=0;

    for (i = 0; i < sz-1; i++)

    {

         //每一趟冒泡排序的过程

         int j = 0;

         for (j = 0; j < sz - 1-i; j++)

         {

             if (arr[j] > arr[j + 1])

             {

                  //交换

                  int tmp = arr[j];

                  arr[j] = arr[j + 1];

                  arr[j + 1] = tmp;

             }

         }

    }

}



int main()

{

    int arr[] = { 9,8,7,6,5,4,3,2,1,0 };

    //写一个冒泡排序

    int sz = sizeof(arr) / sizeof(arr[0]);

    bubble_sort(arr,sz);

    int i = 0;

    for (i = 0; i < sz; i++)

    {

         printf("%d ", arr[i]);

    }

    return 0;

}

应该将sz在外面求好作为一个参数才能解决问题

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-Taco-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值