数组(Day8)

一、数组

问题:(1)统计全班同学的平均身高;(2)获取到全班同学各自的身高。 
 最无脑的,直接:
  float stu1;
  float stu2;
  float stu3;
  ...
  float stu20;

  那此时该如何批量的处理数据?
  

1***.数组概念:  一组相同类型数据(变量)的集合 
 
 1.数组分类 
   一维整型数组 
   一维字符型数组 
   二维整型数组 
   二维字符型数组 

 2****.一维整型数组 定义 
 语法:
  类型说明符 数组名[常量表达式] 
     (1)       (2)     (3)
     
(1) 类型说明符  --- 说明这个数组中放的是哪一种类型的数据
(2) 数组名      --- 类似与变量名
                    通过数组名 代表 数组
                    数组名:
                    1.数组名代表的数据类型 -- 整个数组-数组也是一种数据类型
                    sizeof(a) //a代表的是 整个数组类型 
                    2.数组名代表的值-表示的是数组首元素的地址 也是整个数组的起始地址                    
                    //?
                    //数组名-起名字的规则与变量名起名规则一致
(3).[常量表达式]--- [] //定义时,表示此时定义的是一个数组 
                    常量表达式 --数组长度 
                    所谓数组长度,
                    指的是这个数组中相同类型的数据的个数        
int a[10]; //表示定义了一个包含了10个int型变量的数组 
           
float stu[20]; //直接就批量的相当于定义了20个float类型的变量 
float stu[10000];        

3.判断数据类型的通用方式:去掉变量名(标识符) 剩下的就是数据类型 

int a[10]; //a去掉之后,剩下int[10] 这个称为数组类型 

int[10] a;

4.数组的大小:数组大小=sizeof(数据类型)*数组长度 
    
    
5.数组的初始化和赋值 

//初始化 
//全部初始化 
int a[10] = {1,2,3,4,5,6,7,8,9,10}; //{} 表示 初始化 
//部分初始化 
int a[10] = {1,2,3,4,5}; //这些值依次给到前面的元素,后边未初始化的元素,默认是0
//未初始化 
int a[10];  //此时数组中放的是 随机值(垃圾值)

//数组初始化为0 
int a[10] = {}; 
int a[10] = {0};

6.赋值:
 //1.可以通过计算出一些值,赋值到数组中
  for (i = 0; i < len; ++i)
  {
    a[i] = 表达式;
  }
  
 //2.通过键盘输入 
 
  for (i = 0; i < len; ++i)
  {
    scanf("%d",&a[i]);
  }

7.数组元素引用
方法:
    数组名[下标] //此时中括号 表示 数组下标运算 
    

注意:
   1).下标 
     可能会越界 ---编译不报错,这个问题,需要程序员自己小心 
   2).下标的取值范围 
      0~数组长度-1
   3).数组长度必须是个整型 
   4).定义时,数组长度可以省略,但是实际长度取决于 初始化元素的个数 
     int a[] = {1,2}; //必须要初始化 数组长度可以省略,但是必须要初始化 
                   //因为,编译器要根据实际给到的值,推算出数组长度 
   5).数组      不能整体赋值      不能整体操作      只能操作到具体元素 
     

  
   
 8.可变长数组:
  数据类型 数组名[常量表达式]
  c99标准之后,
  允许数组长度是一个变量。
  
  注意:
     int a[n]; //n是一个变量,不能初始化 

  //默认是signed int 
  int a = 0x8000 0000; //负的最小值
  1|000 0000 0000 0000 0000 0000 0000 0000 //32个位 
  
  1|000 0000 0000 0000 0000 0000 0000 0000 //负0 
 
  signed short a = 0x8000;
  signed long  a = 0x8000000000000000;
  
9.数组特点:
   1.单一性  //数组中元素的类型都是一样的 
   2.连续性  //数组开辟的是一块连续的内存空间 
   3.有序性  //元素间是按照顺序存储的 
   
练习:
  给定一个数组 (准备10个数据)
  对数组进行逆序 
  
       // 0 1 2 3 4 5 6 7 8 9   //下标     
 int a[]={1,2,3,4,5,6,7,8,9,10};//数值 
          //10,9,8,7,6,5,4,3,2,1
  
  所谓逆序:
  对应位置上值交换一下 
  
  0号位置  9号位置  //下标相加 为 9 // len - 1
  1号位置  8号位置 
  2号位置  7号位置 
  3号位置  6号位置
  4号位置  5号位置
  
  int i; 
  a[i] <=> a[9-i];
 
  int temp;
  temp = a[i];
  a[i] = a[9-i];
  a[9-i] = temp;
  i 从0~4  //
  //两个变量 
  i 表示从前面往后走 i //0 1 2 3 4  
  j 表示从后面往前走 j //9 8 7 6 5 
  
-------------------------------------
  int i = 0;
  for (i = 9; i >= 0; --i)
  {
       printf("%d\n",a[i]);
  }
-------------------------------------

3****.排序:
     排序
     从小到大 升序 
     从大到小 降序      
规定:
    c语言中 统一都是 升序排列
    

//选择排序 
//冒泡排序 
//插入排序 
//快速排序 //以后再说


求极值 (最大最小)
1.选择排序:
    思想:  
         给对应的位置选择合适的数 
        

2.冒泡排序:
    思想:
         相邻两个元素,两两比较,
         小的放前,大的放后 


冒泡排序 对比 选择排序 

算法 随着 数据规模的扩展,算法的 时间复杂度的变化 


一条条的机器指令 --- CPU运行 


O(n) //大o记法  


//选择排序
     for (j = 0; j < n - 1; ++j)
    {
        for (i = j + 1; i < n; ++i)
        {
            if (a[i] < a[j])
            {
                t = a[i];
                a[i] = a[j];
                a[j] = t;
            }
        }
    }
    
    //j = 0  i // n-1
    //j = 1  i // n-2
      ...   
      j = n-2 i //1 
  
  1+2+3+...+n-1  // 等差数列 
  
  (1 + n-1)*(n-1)/2
        n*(n-1)/2  
        
        (n^2 - n) /2  // O(n^2) 
        
  
//冒泡排序
    for (j = 1; j < n; ++j)
    { 
        for (i = 0; i < n - j; ++i)
        {
            if (a[i] > a[i+1])
            {
                t = a[i];
                a[i] = a[i+1];
                a[i+1] = t;
            }
        }
    }
    
    j = 1    // n-1
    j = 2    // n-2
    ...
    j = n-1 // 1
    1+2+...+n-1

3.插入排序:
    思想:  
         将一个数,插入到一个(有序的序列中)
         找到合适的位置,然后插入
         
         
    实现步骤:
    1.拿一个要插入的值
    2.寻找最终要插入的位置
    3.找到后插入数据
    

    //原地插入 
    for (i = 1; i < n; ++i)
    {
        int k = a[i];
        j = i;
        while (j > 0 && a[j-1] > k)
        {
            a[j] = a[j-1];
            --j;
        }

        a[j] = k;
    }
  i = 1  //1
  i = 2  //2
  i = 3  //3
  ... 
  i = n-1 //n-1
 
 1+2+...+n-1 
 它的时间复杂度 n(n^2)
 
    
思考:
   1.能不能直接a数组中完成插入排序?
   

4****.查找

//排序 -- 目的  --方便进行查找 

//查找的算法 
二分查找:
前提:
    查找的数据 一定是有序的。 
    
思路:
   1.找一个中间位置 mid  (实际是数组中间位置的下标 )
     判断中间位置上的值 与 要查找的值的大小关系 
      a[mid] > n
   2.a[mid] > n 
     缩小区间 ,到前面小的一部分继续 二分查找 
   3.a[mid] < n
     缩小区间, 到后面大的一部分继续 二分查找
   4.a[mid] == n 
     直接表示找到了 
     

----------------------------------------------------
5****.一维字符型数组:
char s[10]; //一维字符型数组
            //这个数组是用来放,char类型的数据的 

练习:
   hello --- 大写 
      c1 c2 c3 
      //定义一个数组,存放 一个 hello这几个字符
   转换成大写输出 
   
1.字符串 //存储字符串数据 
特点:
   形式上 "hello"
   存储上  "hello" -->本质上是按照字符数组的特点存储
            "hello"  //字符串 --- 一串字符 
   结束标志 最后会有一个 '\0' 作为结束标志 
           //好处
             有了结束标志,此时字符数组长度其实不重要了。
             此时处理字符串时,主要看 '\0'结束标志 
             
   

2.字符数组:
   //初始化它 //全部初始化,部分初始化,未初始化 
              用字符串初始化 
              
  //赋值 
      //通过表达式给值 
      for (i = 0; i < n; ++i)
      {
          s[i] = 'a'+i;
      }
      //通过输入给值 
      for (i = 0; i < n; ++i)
      {
         //scanf("%c",&s[i]);
         s[i] = getchar();
      }
      
      
3.gets() 
功能: 给字符数组中,输入一个"字符串"
char *gets(char *s)
char *gets(char s[]) //传一个字符数组的数组名 
参数:
 s 表示 需要传的是一个 字符数组的 名字 
返回值:
   表示 存放字符串的 那块空间的地址 
   注意:
      这个函数是危险的,不推荐使用。(一不小心可能就越界了)
      fgets(); //这个函数可以解决(后面学)
4.puts()
功能: 将字符串输出,(它会默认输出一个'\n')
int puts(const char *s);
参数:
   s //可以是数组名 也可以是 一个字符串常量 
返回值:
   成功 非负数
   失败 -1 
  
eg:
  char s[10] = "hello";
  puts(s); //数组名
  
  puts("hello"); //字符串常量 
      

注意:
   1.数组 主要是用来 存储数据的 
   2.字符数组,主要是 存储 "字符串" 数据的
  
练习:
   字符串 
   字符串的长度 
   "hello" 
   本质
   'h''e''l''l''o''\0' //字符串长度指的是 '\0'前面字符的个数 
   
   
   数组的长度 
   char s[10];// 数组长度是 10
   char s[10] = "hello"; //字符串的长度?
   
   
   输入一个字符串,
   打印出字符串长度
   
   
//函数原型    
size_t strlen(const char *s); 
功能:
    统计 给到的字符串的长度
参数:
  s //数组名 或 字符串常量 
返回值:
  表示字符串长度 
  
eg:
 char s[] = "hello";
 strlen(s); //数组名 
 
 strlen("hello"); //字符串常量 

//字符串复制 
 因为字符数组不能整体赋值
 char s1[] = "hello";
 char s2[10];
 s2 = s1 ; //这个操作 c语言中不行 
 
 
//
while ()
{
  //逐个字符操作 复制过去
}
//为了让s2中是字符串 
s[i] = '\0';//让最终成为字符串

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值