zoukankan      html  css  js  c++  java
  • 初学c课程笔记整理6-->>数组

    是什么?有什么用?用在什么地方?(理解)
    养成良好的编程习惯;
    培养编程思想;
    写代码之前应该先分析需求,分析完需求再开始写代码;(写注释)
     
    1.数组的定义
    数组的定义格式:
         数据类型 变量名称;
         数据类型 数组名称[数据的个数];
         元素类型 数组名称[元素个数];
         元素类型: 就是数组中需要存储的数据类型, 一旦指定, 数组中就只能存储该类型的数据
         元素个数: 就是数组中能够存储的数据(元素)的个数
     
          int scores[3];
    // 定义了一个名称叫做scores的数组, 数组中可以存放3int类型的数据
       scores = 12; // 系统搞不清楚应该赋值给谁
     
    只要定义一个C语言的数组,
    系统就自动会给数组中的每一块小得存储空间一个编号
    这个编号从0开始, 依次递增
    数组中系统自动绑定的编号, 我们称之为 索引
     
    3.数组的初始化
    需求保持全班101个人的分数
      定义数组:
      元素类型 数组名称[元素个数];
        /*
        // 先定义再初始化
        int scores[5];
        scores[0] = 99;
        scores[1] = 88;
        scores[2] = 77;
        scores[3] = 66;
        scores[4] = 100;
         */
        // 依次将{}中的每一个值赋值给数组中的每一个元素
        // 并且从0开始赋值
        // 也称之为数组的初始化(完全初始化)
        int scores[5] = {99,88,77,66,100};
       
        // 部分初始化
        // 默认从0开始初始化, 依次赋值
        // 注意: 如果"在部分初始化中"对应的内存没有被初始化, 那么默认是0
        int scores1[3] = {11, 22};
        printf("0 = %i ", scores1[0]);
        printf("1 = %i ", scores1[1]);
        printf("2 = %i ", scores1[2]);
       
    ⚠️数组注意事项
         在定义数组的时候[]里面只能写整型常量或者是返回整型常量的表达式
        ⚠️ 注意: 如果没有对数组进行初始化(完全和部分), 那么不要随便使用数组中的数据, 可能是一段垃圾数据(随机值)
        
     
        ⚠️ 注意: 定义数组的时候, 数组的元素个数不能使用变量, 如果使用变量, 那么数组中是一些随机值
       
        ⚠️注意: 不建议使用变量定义数组, 如果使用了变量定义数组, 作为数组的元素个数, 不初始化的情况下是随机值, 如果初始化会直接报错
       
        ⚠️注意: 如果定义的同时进行初始化, 那么元素的个数可以省略
           省略之后, 初始化赋值几个数据, 那么数组的长度就是几. 也就是说数组将来就能存储几个数据
        int scores5[] = {1, 3};
        printf("0 = %i ", scores5[0]);
        printf("1 = %i ", scores5[1]);
        printf("------- ");
       
        ⚠️注意; 如果定义数组时没有进行初始化, 那么不能省略元素个数
         可以通过[索引] = 的方式, 给指定索引的元素赋值
        int socres7[101] = {[99] = 1, [100] = 3};
        printf("3 = %i ", socres7[99]);
        printf("4 = %i ", socres7[100]);

       
         ⚠️注意: 只能在定义的同时利用{}进行初始化, 如果是先定义那么就不能使用{}进行初始化
         如果先定义那么就不能再进行整体赋值, 只能单个赋值
     
    4.数组的遍历
    取出数组中所有的值, 称之为遍历
         
      ⚠️注意: 在遍历数组的时候, 尽量不要把遍历的次数写死
        遍历多少次应该由数组来决定, 也就是说遍历多少次应该通过数组计算得出
        
        printf("scores = %lu ", sizeof(scores));
        // 计算出数组占用的总字节数
     
        printf("scores[0] = %lu ", sizeof(scores[0]));
        // 计算出数组中某一个元素占用的字节数
     
        printf("一个有多少个元素 : %lu ",
        sizeof(scores) / sizeof(scores[0]));
       
    // 动态计算数组的元素个数
        int length = sizeof(scores) / sizeof(scores[0]);
     
     // 数组的遍历
        for (int i = 0; i < length; i++) {
            printf("scores[%i] = %i ", i,scores[i]);
        }
        return 0;
     
    5.数组的内存分配
    1.数组内部存储细节
       存储方式:
        1)计算机会给数组分配一块连续的存储空间
        2)数组名代表数组的首地址,从首地址位置,依次存入数组的第1个、第2个....、第n个元素
        3)每个元素占用相同的字节数(取决于数组类型)
        4)并且数组中元素之间的地址是连续
    ⚠️注意:字符在内存中是以对应ASCII值的二进制形式存储的,而非上表的形式。
    在这个例子中,数组x的地址为它的首元素的地址0x08,数组ca的地址为0x03
     
    2.数组的地址
    - 在内存中,内存从大到小进行寻址,为数组分配了存储空间后,数组的元素自然的从上往下排列 存储,整个数组的地址为首元素的地址。
        数组a的地址是ffc1,a[0]的地址是ffc1,a[1]的地址是ffc5
        因此a == &a[0],即第一个元素的地址就是整个数组的地址
     
    3.数组的越界问题
      数组越界导致的问题
         约错对象
          程序崩溃
        char cs1[2] = {1, 2};
        char cs2[3] = {3, 4, 5};
        cs2[3] = 88; // 注意:这句访问到了不属于cs1的内存
        printf("cs1[0] = %d ", cs1[0] );
    输出结果: 88

     
    6.数组与函数
    基本数据类型作为函数的参数是值传递
       如果形参是基本数据类型, 在函数中修改形参的值不会影响到实参的值
     
     ⚠️注意1: 数组名作为函数的参数传递, 是传递的数组的地址
          因为数组名就是数组的地址 &number = &number[0] == number
     ⚠️注意2: 如果数组作为函数的形参, 元素的个数可以省略
          如果形参是数组, 那么在函数中修改形参的值, 会影响到实参的值
     
    如果传递的数组的名称, 其实传递的是地址
    如果传递的是地址, 其实传递的是指针
    指针在64位编译环境占8个字节
     
      ⚠️注意: 如果数组作为形参, 那么在函数中就不能通过数组的名称计算出数组元素的个数
      因为系统会自动将数组形参转换为指针, 指针占用8个字节
     
     
    数组的一些练习的函数封装:
    选择排序、冒泡排序
    // 遍历数组
    void printArray(int nums[], int length)
    {
        for (int i = 0; i < length; i++) {
            printf("排序后:nums[%i] = %i ", i, nums[i]);
        }
    }
    //选择排序
    void selectSort(int nums[], int length)
    {
        for (int i = 0; i < length - 1; i++) {
            for (int j = i + 1; j < length; j++) {
                if (nums[i] > nums[j]) {
                    int temp = nums[i];
                    nums[i] = nums[j];
                    nums[j] = temp;
                }
            }
        }
        //    输出选择排序后的排列
        printArray(nums,length);
    }
    //冒泡排序
    void bubbleSort(int nums[], int length)
    {
        for (int i = 0; i < length - 1; i++) {
            for (int j = 0; j < length - 1; j++) {
                if (nums[j] > nums[j + 1]) {
                    int temp = nums[j];
                    nums[j] = nums[j + 1];
                    nums[j + 1] = temp;
            }
            }
        }
            //    输出冒泡排序后的排列
       printArray(nums, length);
    }
    折半查找
    //    遍历数组
    int findKye(int nums[], int length, int value)
    {
        for (int i = 0;  i < length; i++) {
            if (nums[i] == value) {
                return i;
        }
    }
        return -1;
    }
    //折半查找
    int findKey2(int nums[], int lengh, int value)
    {
    //    定义两个变量分别来记录下标最大和最小值
        int max = lengh - 1;
        int min = 0;
    //    for循环遍历数组
        for (int i ; i < lengh; i++) {
    //        定义一个变量来记录下标中间值
            int mid = (max + min) / 2;
    //        判断要查找的值和中位值比较大小
    //        要查找的值比中位值大,则中位变最大位并-1
            if (nums[min] > value) {
                max = mid - 1;
            }
    //         要查找的值比中位值小,则中位变最小位并+1
            else if (nums[min] < value)
            {
                min = mid + 1;
            }
    //        相等则返回下标
            else{
                return mid;
            }
        }
    //    要查找的值不存在便返回-1
        return -1;
    }
    进制查表法
    void total(int value, int base, int offset)
    {
        // 1.定义一个数组, 用于保存十六进制中所有的取值
        char charValues[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
        // 2.定义一个数组, 用于保存查询后的结果
        char results[32] = {'0'};
        // 3.定义一个变量, 用于记录当前需要存储到查询结果数组的索引
        int pos = sizeof(results)/ sizeof(results[0]);
       
        while (value != 0) {
            // 1.取出1位的值
            int res = value & base;// 1 7 15
            // 2.利用取出来得值到表中查询对应的结果
            char c = charValues[res];
            // 3.存储查询的结果
            results[--pos] = c;
            // 4.移除二进制被取过的1
            value = value >> offset;// 1 3 4
        }
       
        // 4.打印结果
        for (int i = pos; i < 32; i++) {
            printf("%c", results[i]);
        }
        printf(" ");
       
    }
     
     
     
     
  • 相关阅读:
    centos 查看版本(转)
    防火墙内设置FileZilla Server注意事项
    mycat读写分离与主从切换
    用mycat做读写分离:基于 MySQL主从复制
    mysql处理海量数据时的一些优化查询速度方法
    CentOS下LVS DR模式负载均衡配置详解
    Linux清除arp缓存
    扫描局域网内所有主机和MAC地址的Shell脚本
    Windows+Python 3.6环境下安装PyQt4
    Python 爬虫-豆瓣读书
  • 原文地址:https://www.cnblogs.com/dreamWanweidong/p/4903201.html
Copyright © 2011-2022 走看看