【C语言】第六篇·数组

来源:互联网 发布:恒生指数期货模拟软件 编辑:程序博客网 时间:2024/06/11 22:28

一、数组基本概念
    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[n];    a[n] 这是错误的,最多能访问到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");}






0 0
原创粉丝点击