数组的概念及注意事项

目录

数组

数组的创造格式

一维数组

一维数组的初始化

一维数组在内存中的分配

一维数组的应用

二维数组

二维数组的引用

二维数组初始化

二维数组在内存中的存储

多维数组

越界数组

数组名到底是什么?

字符数组

字符数组的输入和输出


数组

定义:一组具有 相同数据类型 的(有序)的数据集合。

数组的创造格式

1,定义一个数组并给定数组大小

int arry1[10];//未初始化的名为arry1的整形数组大小是10

2,定义一个常量并给定数组大小为这个常量

const int a=5;//定义一个常量a=5

int arry5[a];//未初始化的名为arry5的整形数组大小是5

3,数组大小为常量表达式

int arry5[5+6];//未初始化的名为arry5的整形数组大小是11

4,空数组

int arry5[];//未初始化的名为arry5的整形数组大小未知

一维数组

是用于储存一维数列中数据的集合。

定义方式:类型声明符  数组名[常量表达式]

注意:1.“数组名”就是这个数组型变量的名称,命名规则与变量名一致,

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

2.数组中储存的数据类型可以是任意的数据类型(整型、实型、字符型等)

3.“常量表达式”定义了数组中存放的数据源元素的个数,即数组长度。

例:a[5],5代表数组中有5个元素,下标从0开始,到4结束。

4.数组的下标从0开始到元素的个数减1结束

例:在数组a[5]中只能使用a[0]到a[4],而不能使用a[5],若使用a[5]会出现下标越界的错误。

5.a[i]中的 i 指向数组中的第 i+1 个元素

一维数组的初始化

数组[array]必须先定义在使用。

数组的初始化是指,在创建数组的同时给数组的内容一些合理初始值。

初始化分为完全初始化和不完全初始化。

完全初始化:表示对数组的每一个元素进行赋值。

不完全初始化:表示对数组的部分元素进行赋值,没有被赋值的元素设为0。

1.数据类型[] 数组名称 = new 数据类型[数组长度];

例:定义一个数组a[8],并给数组赋值0、1、2、3、4、5、6、7,然后隔位输出数组中的元素。


2.在对全部数组元素赋初值时,可以不指定数组长度。例如:下列代码。

一维数组在内存中的分配

当我们定义了一个数组,就在内存中开辟了一块连续的空间用于存储某一类数据类型的数据

一维数组的输入和输出

一维数组的输入和输出常犯的错误

1.如果抄袭字符串的形式来输出数组的全部内容,可能会写出如下的错误程序

这个程序本身是对的,问题是他输出的内容不符合要求。字符串可以使用printf函数一次性输出,但数值数组只能一次一个地输出。上述程序中使用的printf语句格式输出的不是数组的内容,而是数组储存的首地址。a的内容必须一个一个输出,即printf("%d",a[0]);...

或者可以用循环:

for(i=0;i<3;i++)        printf("%d",a[i]);

2.  下面程序输出的是数组的内容吗?

这个程序输出不是输出数组的内容。&a[i]表示数组各个元素的地址。i=0时,&a[0]和a一样,均表示数组a的首地址。

正确格式:把&删除。

3.数组没有赋值运算符"=",必须一个一个元素的赋值。

4.

程序中对数组a的赋值不对,i=0时,语句scanf("%d",&a);为第一个元素a[0]赋值。当i=1时,"&a+1"的含义是"&a"的地址值加1,而不是第2个元素a[1]的地址。a[1]的地址应该是"&a[1]",使用语句scanf("%d",&a[i+1]);才是正确的写法,就是用地址循环。因为数组名就是数组储存的首地址,所以a+1代表的是首地址移动到第2个元素储存的首地址,也就是第2个元素的数组名。注意到:a,&a和&a[0]的含义是一样的,都是第1个元素a[0]的地址。"a+1"就代表a[1]的地址,与"&a[1]"等效,所以如下两条语句都是正确的。

scanf("%d",&a[i]);                scanf("%d",a+i);

scanf要求的是储存元素的首地址,所以上述两条语句是等效的。

修改后的程序如下:

一维数组的应用

例:有一程序,定义一个一维数组,顺序打印和逆序打印出这个数组。

二维数组

定义方式为:类型声明符        数组名[常量表达式1][常量表达式2];

其中,“常量表达式1”表达第一维下标的长度,“常量表达式2”标示第二维下标的长度。

例如:int a[2][4];

说明了一个2行4列的数组,数组名为a,其下标变量的类型为整型。该数组的下标共有2*4个即:

a[0][0],a[0][1],a[0][2],a[0][3]

a[1][0].a[1][1],a[1][2],a[1][3]

在C语言中,二维数组是按行排列的。即按行顺序存放,先存放a[0]行,再存放a[1]行:每行中有四个元素,也是依次存放的。

二维数组的引用

数组名[下标][下标]

如果a为2行4列的数组,其行下标的最大值为1,列的最大值为3.

int a[2][4];

...

a[2][4]

所以a[2][4]超过了数组的范围,下标越界。

二维数组初始化

1.分行给二维数组赋初值。例如:int a[2][3]={{1,2,3},{4,5,6}};

第一个花括号内的元素赋给第一行的元素,第二个赋给第二行的元素。

2.可将所有的数据写在一个花括号内,按数组排列的顺序对各个元素赋初值。

例如:

3.可以对部分元素赋初值,未赋初值的元素其自动为0。

4.如果对全部元素都赋初值,则定义数组时对第一维的长度可以不指定,但第二维的长度不能省略。

二维数组在内存中的存储

例:定义一个二维数组并初始化该数组,打印出各个元素所占的地址:

从中也能发现:二维数组在内存中的地址也是连续的。

从侧面说明了二维数组也是一个一维数组,只不过定义的时候把它定义成了二维数组。如一个arry[12]定义成arry[3][4]。或者这样理解由三个一维数组组成的一个二维数组。

多维数组

多维数组的声明和二维数组相同,只是下标更多。

越界数组

数组的下标是有范围限制的,设数组有n个元素,数组的下标规定从0开始的,最后一个元素的下标是n-1。如果数组的下标小于0或者大于n-1,此时数据就越界访问了,超出了定义数组时数组的合法空间。这就是为什么我们经常打印出一堆乱码。最后C语言本身是不做数组下标的越界检查,编译器也不一定报错,不报错不代表程序就是正确的。所以我们一定要认真调试代码。
例:

数组名到底是什么?

第一个printf输出的是1的地址,就是首元素的地址。

第二个printf输出的是a数组名的地址,同时输出的也是首元素的地址,可见数组名就是首元素的地址。

第三个printf输出的是对a数组名的地址的解引用,输出1说明了数组名就是一个地址且是数组首元素的地址。

以上三个例子都说明了,数组名等同于数组首元素地址。也就是以后我们可以通过数组名来进行操作数组。

 但是有两个例外:

sizeof(数组名),这里的sizeof取的是整个数组的大小。
&数组名,这里的数组名表示整个数组,&数组名取出的是整个数组的地址。

字符数组

字符数组的定义:char数组名[常量表达式]

例:char  array[5]

array[0]='h';        array[1]='e';        array[2]='l';        array[3]='l';        array[4]='o';

注:1.当给字符数组赋初值时,如果提供的初值个数大于数组长度,则按语法错误处理。

2.如果初值个数与预定的数组长度相同,在定义时可以忽略数组长度,系统会自动根据初值个数确定数组长度。例:

3.在C语言中,使用字符串数组保存字符串,也就是使用一个一维数组保存字符串中的每一个字符串。此时系统会自动为其添加‘\0’作为结束符。所以用字符串方式赋值比用字符型多占一个字节。

4.利用字符串给字符数组赋初值。通常用一个字符数组来存放一个字符串。字符串总是以'\0'作为串的结束符。因此当把一个字符串存入一个数组时,也把'\0'存入数组,并以此作为该字符串是否结束的标志

5.如果在一个字符数组中先后存放多个不同长度的字符串,则应使数组长度始终大于最长字符串的长度。

用字符串的方式对数组进行初始化赋值如下:

char str[]={'h','e','l','l','o',' ','w','o','r','l','d'};

1.用字符数组存放一个字符串:

char str[]={"hello world"};                 或去掉啊{}写成        char str[]="hello world";

2.用字符指针指向一个字符串:

char*str="hello world";

  对于第二种表示方法,有人认为str 是一个字符串变量,以为定义时把字符串常量"hello world"直接赋给该字符串变量,这是不对的。C 语言对字符串常量是按字符数组处理的,在内存中开辟了一个字符数组用来存放字符串常量,程序在定义字符串指针变量str 时只是把字符串首地址(即存放字符串的字符数组的首地址)赋给str。

char* a="I love China";
等价于:
char* a;
a="I love China";

字符数组的输入和输出

字符数组的输入输出有两种方法

1.用%c

字符数组中的字符逐个输出:

字符逐个输入到字符数组中在输出:

printf("%c",array[i]);实现了字符数组中的元素的逐个输出。

2.用%s

字符串输出/输入

输入:scanf("%s",array)

注意:这里的array是字符数组名,前面没有’&‘,C语言中规定数组名代表该数组的起始地址。不能加&。用%s格式输出字符串时printf函数中的输出项是字符数组名,而不是数组元素名

scanf语句的读入是以空格结束的,所以它只取第一个连续字串符作为输入。要想得到正确结果,就要放弃scanf函数而改用其他函数,例如:gets函数。下面是一个正确程序

常见错误:

编译能通过,但结果不正确。第1条语句中st代表字符串的首地址,所以能输出字符串的内容。

第2条语句的st[5]代表第6个元素y的地址,所以能正确输出"y"。第3条语句是错误的,因为%s是输出字符串,要求字符串的首地址。正确写法是&st[5]。其实,也可以简单地写成语句4。

改正后结果:

有参考过:https://blog.csdn.net/weixin_64916311/article/details/127702181

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值