在实际中需要处理的数据是复杂多样的。一方面需要处理的数据量可能很大,另一方面,数据之间可能存在某种关系,比如学生学号和姓名的关系
为了简单方便地描述现实中更加复杂的数据,像其他高级语言一样C提供了用户自己定义数据描述方法:有若干个基本数据类型(元素,成员,分量),按一定的规则组成复杂数据对象,即构造类型,如数组类型,结构体类型,共用体类型。构造数据类型的引入,使C语言具有更强的描述现实世界复杂数据对象的能力。为设计更复杂的程序,解决更复杂的实际问题提供了更有效的手段。
数组:相同类型数据的有序集合。
一维数组
定义
模式:存储类型 类型标识符 数组名称标识符 [常量表达式];
存储类型说明:说明数组类型的存储属性,即作用域和生成期。可以是static,auto,extern(auto可以省略)。
注意:
比如:int a[4];(习惯面向对象之后可能会觉得这个定义语句别扭)
定义数组的时候[]内必须是常量,因为在数组的长度在编译阶段就必须被确定,而变量只有在程序运行时候才能确定下来。
数组元素的引用
C中数组名实质上是数组的首地址,是一个常量地址(一个地址常量或者说是一个指针常量),不能对他进行赋值,因此不能利用数组名来引用数组,只能单个引用数组元素。
对数组元素引用时,下标可以是整型常量,变量,表达式可以是字符表达式或者枚举类型表达式。
C的编译系统不会进行数组越界检查(笔者未经测试)。
在实际应用中用一维数组描述一组相同类型的数据对象,以方便处理。
存储结构与初始化
存储结构:
C的编译系统为数组在内存中分配一段连续的空间,每个元素占用相同的字节数。
由于数组是连续存储在内存中的,数组名代表了数组在内存中的起始地址,而且每个元素的字节数相同,所以根据元素序号可以求得个元素在内存中的地址,并实现对数组元素进行随机存储。
初始化:
C允许在定义数组的同时指定初始值,这个过程叫做初始化。初始化在编译阶段完成,不占用运行时间(正因为如此所以定义数组时[]内必须是常量)。
对所有元素赋初始值:int a[3] = {1,2,2};
对部分元素赋初始值:int a[3] = {1};
对所有元素赋初始值的时候可以不定义下标:int a[]={1,2,2};
注意:若static数组或者外部数组不进行初始化,那么对数值型数组默认值为0,字符型数组默认值为'\0'(也就是NULL)
若auto数组不进行初始化,那么默认为系统分配给数组各元素的内存单元的初始值(也就是这片内存上一次使用的值)所以在不同的时间和机器上结果是不同的。
当给数组部分初始化的时候必须指定长度。
案例说明数组的使用
输入5个数,输出最大值最小值。
#include "stdio.h" #define N 5 void main(){ int i,j,k,max,min; //i 循环控制变量 //jk,最大值最小值下标识 //max,min最值 int a[5]; //数组容器 for(i = 0;i < 5;i ++){ scanf("%d",&a[i]); } max = min = a[0]; for(i = 0;i<5;i ++){ if(max <= a[i]){ max = a[i]; j = i; } else if(min >= a[i] ){ min = a[i]; k = i; } } printf("max:a[%d]%d\nmin:a[%d]%d",j,a[j],k,a[k]); scanf("%d",a[0]); }
二维数组
此处待续
数组的应用
数组常用的有一下几个方面:
数组存储数据,遍历处理
#include "stdio.h" int main(){ int sorces[100],avg,number = 1;//成绩,平均成绩,学生数量 int sam=0,temp,i = 0;//总成绩,临时成绩,循环计数变量 //循环录入成绩 while(temp >= 0){ printf("\ninput %d :",number); scanf("%d",&temp); if(temp > 0){ sorces[number - 1] = temp; number ++; sam += temp; } } avg = sam/number; printf("the avg is :%d\n\n",avg); for(i = 0;i < number-1;i++){//控制写错了 if(sorces[i] > avg)printf("%d:%d\n\n",i+1,sorces[i]); } scanf("%d",&i); return 1; }
数组排序
#include "stdio.h" int main(){ //选择法排序,由大到小 //在程序设计上 ,应该有两大步:一步应该是算法的设计,一个是算法的实现(也就是用代码描述算法)。后者是程序员的基础技能,这个弄不懂或者不熟练的话,就没必要在程序员这条路上走了,这样应该也是不明智的! //有时候真怀疑自己是不是合适在程序员这个行业做!哎,应该很快就有分晓了。 int a[3] = {1,2,3};//支持100个数的排序 int temp;//临时最大值 int n,i;//计数变量 //排序之前显示数组 for(i = 0;i < 3;i ++){ printf("%d\n",a[i]); } //排序 for(i = 0;i < 3;i++){ for(n = 2;n >= i;n --){//将a[n]和a[i]比较,大值左移 if(a[n] > a[i]){ temp = a[n]; a[n] = a[i]; a[i] = temp; } } printf("\na[%d] = %d:",i,a[i]); } printf("\n--------------------\n"); //排序之后显示数组 for(i = 0;i < 3;i ++){ printf("%d\n",a[i]); } scanf("%d",a); return 0; }
数组查找(二分查找)
#include "stdio.h" int main(){ int a[7] = {1,2,3,4,5,6,7};//排序后的数组 int M = 9;//查询的数 int begin = 0,end = 6,midle;//开始和结束索引 while(1==1){ midle = (begin + end)/2;//中间索引 if(a[midle] == M) {//找到了 puts("yes"); break; } if(a[midle] > M){ end = midle; }else{ begin = midle; } if((end - begin)==1){ puts("no");//直到结束还没有找到 break; } } puts("------end------"); scanf("%d",a); return 1; }
字符数组与字符串
字符数组的定义与初始化
略(与常规数组没有区别)
字符串概念及其存储
C中没有字符串类型,自然没有字符串变量。但是可以使用字符串常量,使用双引号表示。
没有字符串类型,那么怎么存储呢?答案是使用字符数组。
为了方便处理字符串,C规定可以直接使用字符串来初始化字符数组。
Char s[13] = {"hello world!"};
或者省略花括号cahr str[14] = "hello world!";
输出输入字符串
输出:
Printf("%s",str);//这个不是地址么
Puts(str)//函数原型为:puts(cahr * str);//参数为指针或者字符数组
输入:
Scanf("%s",str);//这种方式不能输入空格
Puts(str)//能输入空格,原型为:char *gets(char *str),参数为指针或者字符数组
字符串处理函数
String.h库
复制,比较,长度,追加,截取...
数组做函数的参数
Void sort(int a[]){...}//形参
Void sort(a);//实参,传的是地址
数组是基本的构造类型,也是常用的数据类型。基本功很重要!