我们之前的内容算是把C语言最基础的部分讲解了一下,接下来是C语言中最常用的一个重点来了,他就是数组,这一篇我们先了解一下一维数组。
一维数组的基本使用
通过我们之前的知识,我们可以完成存储一些简单的数据到变量中,但是如果我们遇到要存储一个几百人公司员工的名称的问题我们要怎么解决?定义几百个变量吗,也不是很现实,这个时候数组就可以很好的为我们解决问题。
一维数组的定义
数组的定义语法:
数据类型 数组名[数组长度] 。例如:
int arrTem[10];
说明:
1.数组名的命名规则和变量相同,遵循标识符命名规则
2.数组名侯姐一个或多个方括号,用以指定数组的维数(方括号的个数是维数,方括号内的是个数)
3.数组长度只能是常量和常量表达式(大于0),不能是变量。
注:c99标准中规定允许使用变量,但是vs编译器不允许,所以我们也不使用变量。
一位数组的元素的引用
数组可以通过下标来访问某一个元素,下表示具有整数值的表达式,也就是说下标可以是:
- 常量
- 变量
- 其他有整数值的表达式
数组元素的表示形式:
数组名[下标]
例如 :arrTem[3],arrTem[i+1];
,这里是已经初始化的数组,所以可以用变量来取元素的值
通过下标对每个元素的使用与普通变量一样。
注:数组下标从0开始,故而像int nTemp[10]
这样的数组,下标最大是9。
示例:
int main()
{
int nNum = 10;
int Arr1[10];//这里定义了一个元素个数为10的数组
int Arr2[10] = {1,2,3,4,5,6,7,8,9,0};//这里为数组进行了初始化
int loc = 0;
printf("%d\n",Arr2[loc]); //我们使用数组的时候,下标可以是变量。
loc++;
printf("%d\n",Arr2[loc]);
loc++;
printf("%d\n",Arr2[loc]);
}
一维数组的说明
数组是相同数据类型变量的集合,当你定义了int arrTem[11],实际上就相当于定义了11个int类型的变量。
使用数组名和下标来访问数组中的每一个元素,数组中的某一个元素就在使用的时候,和普通的变量没有区别。
例如:
int main()
{
int Arr1[10];
int Arr2[10] = {1,2,3,4,5,6,7,8,9,0};
printf("%d\n",Arr2[0]);
printf("%d\n",Arr2[9]);
scanf_s("%d",&Arr2[1]);//因为数组中的单个元素和变量没有区别所以也需要用取地址符
printf("%d\n",Arr2[1]);
}
数组初始化
在数组定义的时候,给每一个元素初始值,称之为初始化,通常有以下几种初始化的方式:
整体赋值
int arr[5] = {1,2,3,4,5};
部分赋值
int arr[5] = {1,2,3};
,剩下没有赋值的两个就自动为0
不给定数组长度,根据给定数组元素的个数来分配
int arr[] = {1,2,3,4,5,6,7};
,共有7个元素 ,所以分配28(sizeof(int)*7)个字节的空间
示例代码:
int main()
{
int nNum = 10;
int Arr1[10];
int Arr2[10] = {1,2,3,4,5,6,7,8,9,0};
int Arr3[] = {11,22,33,44};
//错误情况
//int Arr4[]; 错误,没有初始化不能忽略元素个数
//int Arr5[nNum]; 错误不能使用变量来,数组个数必须是常量
//Arr1 = Arr2;错误数组不能整体赋值
//Arr1 = {1,2,3,4,5}; 数组初始化过后不能整体赋值
//使用数组元素需要使用变量一致
scanf_s("%d",&Arr1[3]);
printf("%d",Arr[3]);
}
注:在定义数组的时候赋值叫做初始化,之后叫做赋值。
数组存储
数组在内存中存储是连续的。
//例:一个包含11个整型元素的数组
int arrTem[11]; //11表示的有11个元素,要与数据下标区分开。
arrTem[0],arrTem[1],arrTem[2]....arrTem[10];
//数组下标从0开始,所以最大下标为10。
注:在内存中用连续的空间存储,每个元素占4个字节。
定义数组的时候,数组长度必须是一个常量,使用数组的时候。
下标即可以是一个常量也可以是一个变量。
数组越界的问题
使用数组的时候,假如不小心下标超过了最大界限会出现什么情况?出现这种情况时候,编译器是不会检查的,称之为数组越界问题。这种情况非常危险,会破坏程序的内存。造成程序间歇性不稳定(程序运行的时候有时候会出错,有时候可以正常运行)。
int main()
{
int nNum = 0;
int Arr1[10] = {1};
int Arr2[10] = {11,22,33,44,55,66,77,88,99,100};
int loc = 0;
Arr2[loc] = 1;
loc++;
Arr2[loc] = 2;
loc++;
Arr2[loc] = 3;
loc++;
Arr2[loc] = 4;
loc++;
Arr2[loc] = 5;
loc++;
Arr2[loc] = 6;
loc++;
Arr2[loc] = 7;
loc++;
Arr2[loc] = 8;
loc++;
Arr2[loc] = 9;
loc++;
Arr2[loc] = 10;
loc++;
Arr2[loc] = 11;
Arr2[100] = 100;
}
当这些代码运行之后,就会报:
写入位置发生冲突的
的错误。
字符数组
字符数组是一种比较特殊的数组,主要体现在它的初始化方面以及存储字符串的时候的使用方面。
char Arr1[] = {'H','e','l','l','o','W','o','r','l','d'};
char Arr2[] = "HelloWorld"; //字符数组的特殊用法,可以用一个字符串初始化数组
printf("%d\n",sizeof(Arr1)); //这里会打印10
printf("%d\n",sizeof(Arr2)); //这里会打印11,因为字符串最后有一个结束符'\0'
printf("%s\n",Arr1); //这里不会正确打印helloworld,因为我们格式控制符是%s
//是用来打印字符串的,所以他会遇到'\0'才结束,而这里没有'\0'
//所以他会打印内存中数组后面的存的其他的内容,直到遇到'\0'
printf("%s\n",Arr2); //这里会正确打印helloworld
在C语言中,字符串是以'0'结尾的,所有使用字符串的地方,都是检测字符串结尾的'0'来判断字符串是不是结束了。
注:字符串的结尾是一个'0',这个字符的ASCII是0。而字符'0'的ASCII是0x30。
关于字符数组的输入与输出
数组名其实就是数组的起始地址,他是一个常量,这个概念大家可能第一次接触到,我们在以后的学习中慢慢理解。
接下来看一个例子:
int main()
{
char string[10];
scanf_s("%s",string,10); //会检测输入的数据是不是超过了三个参数
printf('%x',string); //这里scanf中,string没有用取地址符,因为数组名就是这个数组的首地址
}
关于一些字符串操作
4个基本的字符串操作函数
函数名 | 作用 |
---|---|
strlen | 求字符串的长度 |
strcpy/strcpy_s | 字符串拷贝函数 |
strcmp | 比较两个字符串是否相等 |
strcat/strcat_s | 将两个字符串拼接到一起 |
这几个函数使用起来都比较简单,基本使用方式如下:
int main()
{
char cChar1[10] = "hello";
char cChar2[20] = "hello";
char cChar3[20] = "world";
cChar3[5] = 0; //设置字符串的'\0'
//求字符串长度:strlen
printf("%d\n",sizeof(cChar1));
printf("%d\n",sizeof(cChar2));
printf("%d\n",sizeof(cChar3));
cChar2[3] = 0;
printf("%d\n",strlen(cChar2)); //注意strlen只检测'\0'
strcpy_s(cChar2,20,cChar3); //将后面的字符串拷贝到前面去
//比较两个字符串是不是一样的: strcmp
printf("%d\n",strcmp(cChar2,cChar3));
//如果两个字符串完全一样就是0,否则就是非0。
//拼接两个字符串: strcat
strcat_s(cChar1,10,cChar3); //会报错,因为缓冲区大小不够
strcat_s(cChar2,10,cChar3); //如果缓冲区大小足够,就不会报错,安全函数的作用就是再这里。
printf("%s",cChar1);
return 0;
}