您的位置:首页 > 编程语言 > C语言/C++

【C语言】第六篇·数组

2015-08-17 08:08 393 查看
一、数组基本概念
1.在程序设计中,为了处理方便,把具有相同类型的若干变量按有序的形式组织起来。这些按序排列的同类数据元素的集合称为数组。
在C语言中,数组数据构造类型。
2.按存储内同分类:数值数组,字符数组,指针数组,结构数组
3.按维度分类:一维数组,二维数组,多位数组

二、数组的使用
1. 数组的定义
1)定义的格式:
类型 数组名[常量表达式];
常量表达式:1)数字 2)返回数字的整数 3)变量(C99不支持,但是LLVM支持,VC使用的C99)
例如:int arr[10]; //定义一个int类型的数组,长度为10,数组名是arr
2)注意:
数组名不能和变量名同名
数组在定义的时候可以和定义其他变量混合定义 inta,b,c[10];
2. 数组的初始化和引用方法
1)初始化的方法:
(1)定义的时候初始化
<1> 完全初始化
int a[5]={1,2,3,4,5}
<2> 部分初始化
int a[5]={1,2,3}
<3>指定位置元素的初始化
int a[5]={[2]=4,[4]=2}
<4>定义的同时初始化,但是不指定长度,系统会根据赋值的内容来确定数组的长度
int a[]={1,2,3,4,5};
(2)先定义后初始化

inta[3];//定义一个长度为3的int型数组
通过下标来初始化,显式的对每一个元素初始化
a[0]=1;
a[1]=100;
a[2]=200;
2)访问的方法:
(1)对数组的访问是使用数组的下标来进行访问的,因为下标从0开始,访问数组的时候,如一个数组的长度为n ,下标的范围0-n-1,绝对不能越界访问。
int a
; a
这是错误的,最多能访问到a[n-1]
越界:
(2)约错了对象(访问了我们不应该访问的空间),越界访问为不安全的访问,其他语言中约见都会报错,但是现在用的C99的标准,是不报错的。

3. 数组的存储原理
1)存储原理
(1)数组在内存中是一片连续的内存存储空间,数组名指向数组的首地址。
(2)数组中每个元素的地址是连续的
(3)每个元素在存储数据的时候,低位存在低地址字节,高位存在高地址字节
(4)数组名是用来存放数组的首地址的。数组名 == &a[0] ==数组的首地址
2)如何计算数组的长度问题:
sizeof(数组名) 整个数组在内存中占用的存储空间
数组的长度 = sizeof(数组名)/sizeof(数组元素的类型)
4. 数组作为函数的参数
1)数组的元素作为函数的参数
数组的每个元素可以用 a[i] 来表示,a[i]相当于是一个变量, 相当于把a[i]值赋值一份,传递给函数的形参
总结:数组的元素作为函数参数就是值传递。
2)数组名作为函数的参数
数组名作为函数的参数,就不一样了,数组名是一个地址。
int a[10];
数组名作为实参的时候print_arr(a),把数组的首地址传递给函数的形参了, 因为函数的形参和我们数组的名称都指向的是同一块内存空间,所以函数中对数组的操作,就等同于直接操作我们的数组。

三、字符数组
1. 定义:char c[10];
2. 初始化:c[10]={'c','b','d'};
3. 输入输出:用格式控制符%s输入输入输出
4. 字符串处理函数:
1)头文件 #include <string.h>
2)输出:puts(字符数组) 输入:gets(字符数组)
3)字符串连接函数:strcat(字符数组1,字符数组2) 把字符串2连接到1后面
4)字符串复制函数:strcpy(字符数组1,字符数组2) 把字符串2复制到1,把字符串1覆盖掉
5)strncpy(str1,str2,n) 把str2中的前n个字符复制到str1中
6)字符串比较函数:strcmp(字符串1,字符串2)
字符串1 == 字符串2,返回值为0
字符串1 > 字符串2 ,返回一个正整数
字符串1 < 字符串2,返回一个负整数
7)测字符串长度:strlen(字符数组) 注意:它是测字符串的实际长度,不包含\0
例如:char str[10] ={"China"}; strlen(str) = 5
8)转换为小写字母:strlwr(字符串) 转换为大写字母:strupr(字符串)

四、数组元素排序
1. 冒泡排序
1)算法思想:由小到大排序,大数下沉法(小数上浮法),在一次循环的过程当中,数组中的一个数,与下一个数进行比较,当这个数比下个数大时两数交换位置,直到在一次循环中所有的数的位置没有发生改变时,结束循环。
2)示例程序:

#include <stdio.h>
void main(){
int arry[10];
int i,j,flag=-1;
int temp;  //存放某一次排序当中的最大数
int count; //循环次数
printf("请输入需要排序的10个数:\n");
//输入数据
for(i=0;i<10;i++){
scanf("%d,",&arry[i]);
}
//输出数据
printf("\n输入的数据分别为:\n");
for(i=0;i<10;i++){
printf("%d  ",arry[i]);
}
printf("\n");
//改进算法
for(i=0;i<9;i++){ //n个数,最多循环n-1次,即可完成排序
count=9;  //防止出现越界:arry[9]>arry[10]
flag=0;
for(j=0;j<count;j++){
if(arry[j]>arry[j+1]){
temp=arry[j];
arry[j]=arry[j+1];
arry[j+1]=temp;
flag=1;
}
}
if(flag == 0) break; //此次循环中所有的数的位置没有发生改变,跳出循环
count--;  //下一次循环的时候,最后一个数已完成排序,没有必要在此进行比较
}
printf("\n按照由小到大的排序为:\n");
for(i=0;i<10;i++){
printf("%d ",arry[i]);
}
printf("\n");
}


2.选择排序:
1)算法思想:由小到大排序,在一次循环过程当中,首先记录循环的次数n,此次循环中找出最小的一个数,并且记录其下标col,然后将最小数与数组的第n个数进行交换位置,下一次循环时跳过上一次排序完成的数,知道在一次循环中所有的数没有发生位置交换时退出循环。
2)示例程序

#include <stdio.h>
void main(){
int i,j;
int arr[10];
int minNum,col; //存储某次循环中的最小值和最小值的下标
printf("输入10需要排序的数:\n");
for(i=0;i<10;i++){
scanf("%d,",&arr[i]);
}
printf("\n输入的10个数分别为:\n");
for(i=0;i<10;i++){
printf("%d ",arr[i]);
}
printf("\n\n");
//选择排序
for(i=0;i<9;i++){
minNum=arr[i];  //记录当前循环第一个值和列号
col=i;
for(j=i+1;j<10;j++){
if(arr[j] < minNum){
col = j;   //如果发现比minNum还要小的数,记录其列号和值
minNum = arr[col];
}
}
//当前循环的第一个值与最小值交换
arr[col] = arr[i];
arr[i] = minNum;
}
printf("10个数由小到大排序为:\n");
for(i=0;i<10;i++){
printf("%d ",arr[i]);
}
printf("\n");
}


4.折半查找
1)折半查找首先要在一个有序的序列当中,然后设置三个变量low,hign,mid,分别记录在此次查找的过程当中的第一个数,最后一个数,中间数。在一次查找的过程当中,如果要查找的数x> mid,则low = mid+1,然后继续下一次查找;如果x < mid ,则high = mid -1。直到low>high时跳出循环。
2)示例程序:

#include <stdio.h>
void main(){
int i,j;
int arr[10];
int minNum,col; //存储某次循环中的最小值和最小值的列号
int low,high,mid,num;
printf("输入10需要排序的数:\n");
for(i=0;i<10;i++){
scanf("%d,",&arr[i]);
}
printf("\n输入的10个数分别为:\n");
for(i=0;i<10;i++){
printf("%d ",arr[i]);
}
printf("\n\n");
//选择排序
for(i=0;i<9;i++){
minNum=arr[i];  //记录当前循环第一个值和列号
col=i;
for(j=i+1;j<10;j++){
if(arr[j] < minNum){
col = j;   //如果发现比minNum还要小的数,记录其列号和值
minNum = arr[col];
}
}
//当前循环的第一个值与最小值交换
arr[col] = arr[i];
arr[i] = minNum;
}
printf("10个数由小到大排序为:\n");
for(i=0;i<10;i++){
printf("%d ",arr[i]);
}
printf("\n");
while(1){     //程序改进:可以将条件改为while(low<=high) 下面的条件适当修改
//折半查找
printf("\n输入要查找的数:");
scanf("%d",&num);
printf("要查找的数为:%d\n",num);
low = 1;
high = sizeof(arr);
mid = (low+high)/2;
while(1){
if(num > arr[mid-1]){
low = mid+1;
mid = (low+high)/2;
}
else if(num < arr[mid-1]){
high = mid-1;
mid=(low+high)/2;
}
else{
printf("%d已经找到,是第%d个数!\n",arr[mid-1],mid);
break;
}
if((low == high) && num != arr[mid-1]){  //当low和high的值相同,并且num与mid指向的值不相同时代表没有找到该数
printf("%d在该序列中不存在!\n",num);
break;
}
}
}
}


5. 有序序列中插入一个数
1)算法思想:通过折半查找的方法,查找要插入的数x。如果找到,将x插入到low的位置,如果没有找到将x插入到low指向的位置。
2)示例程序:

#include <stdio.h>
int insertLoc(int arry[],int num){
int low,high,mid;
low=1;
high=10;
mid=(low+high)/2;
while(low<=high){
if(num>arry[mid-1]){
low=mid+1;
mid=(low+high)/2;
}
else if(num < arry[mid-2]){
high=mid-1;
mid = (low+high)/2;
}
else{
return mid;
break;
}
}
return low; //当low == high时,不管num与中间数的大小关系,low始终指向要插入的位置,即:小则
}

void main(){
int arr[11];
int i,j;
int num,loc;
int insertLoc(int arry[],int num);
printf("请输入10个有序的数:\n");
for(i=0;i<10;i++){
scanf("%d,",&arr[i]);
}
printf("\n输入的10个数分别为:\n");
for(i=0;i<10;i++){
printf("%d ",arr[i]);
}
printf("\n输入需要插入的数:");
scanf("%d",&num);
loc=insertLoc(arr,num);
printf("插入的位置为:%d\n",loc);
for(i=10;i>loc-2;i--){
arr[i] = arr[i-1];
}
arr[loc-1]=num;
printf("插入后的序列为:\n");
for(i=0;i<11;i++){
printf("%d ",arr[i]);
}
printf("\n");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: