C语言中数组的总结
1. 数组的定义
2. 一维数组的创建和初始化
3. 给数组元素赋值
4. 数组下标越界
5. 二维数组
6. 多维数组
7. 数组全部赋值为1指针与一维数组
8. 指针与多维数组
9. 指针,数组与函数
10. 变长数组
11. 以上全部内容
数组的定义
1. 数组:一系列相同数据类型的有序序列。
2. 声明数组:
int states[50];
char code[28];
float candy[13]; 等等……
通过声明将会告知编译器三个信息:1) 数组内含有多少元素 2) 元素的数据类型 3) 数组名
一维数组的创建和初始化
1. 数组的初始化:在数组创建时,我们要为数组初始化。
int months[12]={31,28,31,30,31,30,31,31,30,31,30,31};//数组的初始化
int months[ ]={ 31,28,31,30,31,30,31,31,30};//初始化时省略方括号中的数字,编译器会根据初始化列表中项数来确定数组的大小。(本例中数组的大小为9)
const int months[12]={31,28,31,30,31,30,31,31,30,31,30,31};//将数组设置为只读,这样程序只能从数组中检索值,不能把新值写入数组。(一旦声明为const,便不能再给他赋值)
以花括号括起来,用逗号分隔数组元素来初始化数组,逗号和值之间可以使用空格。
C const 与 C++ const
区别一:c++允许在声明数组时使用const整数变量,而c不允许。
区别二:const定义的变量未初始化时,c会使用一个变量地址上的随机的值,c++会报错未初始化的const 'y'。
区别三:const int y;
const int *p2 =&y;
int * p1;
p1 = p2;//c++不允许这么做(从'const int*'到'int*' [- fper]的无效转换),c会给出一个警告(赋值从指针目标类型中丢弃“const”限定符)
1) 失败的初始化数组
a) 未初始化数组:数组元素和未初始化的普通变量一样,编译器使用的值是内存地址上现有的值,使得数组储存的都是垃圾值。
b) 初始化列表中的值少于数组元素个数时:编译器会把剩余未初始化的数组元素都初始化为0。
c) 初始化列表中的值多于数组元素个数:编译器会将其视为警告,多余的值将会被作废。(在c++中将会将其视为错误)
d) 存储的值与数组的数据类型不同时:编译器会将数值进行自动类型转换。
2) 指定初始化器(c99):可以初始化指定的数组元素。
eg
int arr[6]={ [5] = 212}; //把arr[5]初始化为212
特性一:如果指定初始化器后面有更多的值,那么后面的值将被用于初始化指定元素后面的值。
eg
int months[12]={31, 31,30,31,[4] = 30, [1]=30,30,31,34};//数组的指定初始化
month[4]被初始化为30,其后跟着的month[5],month[6],month[7],被依次初始化31,31,30,month[1]被初始化30,month[2],month[3],month[4]被初始化30,31.
特性二:如果再次初始化指定的元素,那么最后的初始化将会取代之前的初始化。
eg
int months[12]={31, 31,30,31,[4] = 30, [1]=30,30,31,34};//数组的指定初始化
month[1]=30取代了前面的31,month[1]后面的34取代了前面的month[4]=30.
注意事项:int stuff[ ] = { 1, [6] = 23};//stuff有七个元素,不要误以为有两个元素
给数组元素赋值
方式:借助数组下标(或索引,偏移量)给数组元素赋值。
注意事项
一:不允许把数组当作为一个单元赋给另一个数组。
二:除初始化以外不允许使用花括号列表的形式赋值。
eg
int oxen[5] = {3,3,5,1}; //没问题
int yaks[5] ;
yaks =oxen; //不允许,数组不能当作另一个数组的赋值单位
yaks[5]=oxen[5]; //允许,但是数组下标越界
yaks[5]={5,3,2,8}; // 不允许,除初始化以外不允许使用花括号列表的形式赋值
2. 数组的创建:在创建数组时,我们必须定义数组的类型和大小,数组的大小不能为0,数组中的元素类型都是相同的。
eg
int arr[10];//[ ]内必须是整型常量/常量表达式(3+8),sizeof(),但是const定义的值不能用做指定数组大小的值(C++不同),不能是一个变量(x...)(c99,c11之后创建了变长数组(VLA),允许使用变量)
1) 数组的数据类型:普通变量可以使用的类型,数组元素都可以使用。
当然数组还可以使用数组本身作为自己的数据类型,即数组的数组。
2) 指定数组的大小
a)[ ]内必须是整型常量/常量表达式(3+8),sizeof(),但是const定义的值不能用做指定数组大小的值(C++不同),不能是一个变量(x...)(c99,c11之后创建了变长数组(VLA),允许使用变量) b)数组大小必须是整数且数组大小必须大于零 eg int n =5;
int m =8;
float al[5];//可以
float a2[5*2+1];//可以
float a3[sizeof(int) +1];//可以
float a4[-4];//不可以,数组大小必须大于0
float a5[0];//不可以,数组大小必须大于0
float a6[2.5];//不可以,数组大小必须为整型
float a7[(int) 2.5];//可以,强制类型转换
float a8[n];//VLA c99之前不允许
float a9[m]; //VLA c99之前不允许
数组下标越界
产生的原因:c语言信任程序员,不检查边界,c可以运行的更快。
数组越界产生的影响
示例一: 示例二:
int main(void) int main(void)
{ {
int i = 5; int i = 5;
int arr[3]={2,3,4}; int arr[3]={2,3,4};
int j =1; int j =1;
printf(“%d,”,arr[3] =1); printf(“%d\n”,i);
printf(“%d\n”,i); printf(“%d,”,arr[3] =1);
printf(“%d,”,arr[-1]=-1); printf(“%d,”,j);
printf(“%d\n”,j); printf(“%d”,arr[-1]=-1);
}
输出如下:1,1 输出如下:5,1
-1,-1 1, -1
分析:arr[3]将i的值替换成了1,arr[-1]将j的值替换成了-1.
解析:为什么会出现这种情况,源自于栈这种数据类型“先进后出”特点,首先分析以下这个程序内存分配情况:程序先定义了一个int类型的变量i,接着定义了一个int类型的数组长度为3。在编译器中,内存以栈的数据结构来分配,利用栈“先进后出”的特点,先给i分配了一个4个字节的空间,再给长度为3 的数组分配了12个字节的空间,最后给j分配了一个4个字节的空间,如下图:
栈内存分配
二维数组
数组的声明
type name[i][j];//type为数组类型,name为数组名称,i为数组的行数,j为数组的列数。
int zippo[4][2];//zippo是一个含有四个数组元素的数组,每个数组元素含有两个int类型的元素
float rains[5][12];//rains是一个含有五个数组元素的数组,每个数组元素含有十二个float类型的元素
char alpha[3][3];//char是一个含有三个数组元素的数组,每个数组元素含有两个char类型的元素
数组的初始化:将二维数组的初始化看做是多个一维数组的集合。
int zippo[3] = {1,2,3};//一维数组的初始化
int zippo[3][8] = int zippo[3][8] =
{ {
{1,2,3,4,5,6,7,8}, 1,2,3,4,5,6,7,8,
{3,4,5,6,7,8,9,10}, 3,4,5,6,7,8,9,10,
{5,6,7,8,9,10,11,12} 5,6,7,8,9,10,11,12
}; };
//声明了一个三行八列的数组,初始化使用了三行数值列表,每行列表代表数组对应的行数,列表如一维函数用花括号括起来,花括号与花括号之间用逗号隔开。
有花括号时:前面讨论的一维数组的初始化出现的问题同样适用与这里,如果某一行数值列表元素少于数组定义的元素个数,则该行的其他项将被初始化为0,如果某一行的数值列表元素多余数组定义的元素个数,编译器会将其视为警告,多余的值将会被作废。(在c++中将会将其视为错误),不影响其他行的初始化。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论