zoukankan      html  css  js  c++  java
  • C语言-数组

    数组的定义

        /*
         变量如何定义?
         数据类型   变量名称
         数组如何定义?
         数据类型   数组名称[数据的个数]     这样
         元素类型   数组名称[元素个数]
         元素类型:就是数组中要存储的数据类型,一旦指定数组中就只能存储该类型的数据
         元素个数:就是数组中能够存储的数据个数
         */
        int scores[3]; // 定义了一个数据名称为 scores,数组中可以存储三个 int 类型的数据
        // 如何在内存中存储呢?
        // 先分配一个 12 个字节的空间给 scores,这个数组中n可以存放三个 int 类型的数据,那么就会等分成三个,四个字节的内存空间用来存储 int 类型的数据
        // 那么如何存值呢?
        // socres 中有三个小的空间,需要指定给哪个空间赋值
        // 只要 C语言定义了数组,那么系统就会给每个小的空间存储一个编号,这个编号称之为索引
        // 那么就只需要指定编号就可以赋值了
        scores[0] = 12;
        // 这个时候会将 12 的值赋值给 scores 存储空间中索引为 0 的空间中
        printf("scores[0]=%i
    ",scores[0]);
    

    数组的初始化

       // 数组的初始化
        int scores[5];
        scores[0] = 10;
        scores[1] = 20;
        scores[2] = 30;
        scores[3] = 40;
        scores[4] = 50;
        // 这样写很 low 哇,是不是很累啊
        // 完全初始化
        int scores1[5] = {1,2,3,4,5};
        // 部分初始化
        // 在部分初始化中对应的内存没有被初始化,那么值默认为 0
        int scores2[5] = {1,2}; // 默认从 0开始初始化
        printf("scores2[0]=%i
    ",scores2[0]);
        printf("scores2[1]=%i
    ",scores2[1]);
        printf("scores2[2]=%i
    ",scores2[2]); // 0
        
        printf("-------
    ");
        int scores3[3];
        printf("scores3[0]=%i
    ",scores3[0]);
        printf("scores3[1]=%i
    ",scores3[1]);
        printf("scores3[2]=%i
    ",scores3[2]);
        // 此时整个数组都没有初始化,只是定义了话,有时打印的不是 0,注意只有部分初始化的时候,没有初始化的值才为 0.同时也不要随意使用没有初始化的值,可能是一段垃圾数据
        
        // 注意定义数组的时候,数组的个数不能使用变量,如果使用了变量,数组中的值会是一些垃圾的值
        /*
        int num = 10;
        int scores[num];// 报错,变量是一个动态的值,不清楚要分配多少内存空间
        */
        
        // 如果定义的同时进行初始化,那么元素的个数可以被省略
        // 省略之后,初始化了几个数据,那么数组的长度就是几,也就是数据可以存储几个数据
        int scores5[] = {1,3};
        printf("scores5[0]=%i
    ",scores5[0]);
        printf("scores5[1]=%i
    ",scores5[1]);
        
        // 如果定义的同时没有进行初始化,那么元素的个数不能省略会直接报错
        // int scores6[]; // 此时直接报错
        
        // 指定位置初始化
        int scores7[5] = {0,0,0,3,4};
        int scores8[101] = {[99]=1,[100]=2};
        printf("scores8[99] = %i
    ",scores8[99]); // 1
        printf("scores8[100] = %i
    ",scores8[100]); // 2
    
    
        // 大括号只能在定义的同时才可以使用,
        // 先定义在初始化
        int scores9[3];
        scores9[0] = 1;
        scores9[1] = 1;
        scores9[2] = 1;
        
    

    数组的遍历

        // 数组的遍历
        int nums[6] = {99,88,77,55,66,44};
        for (int i = 0; i <= 6; i++) {
            printf("nums[%i] = %i
    ",i,nums[i]);
        }
        // 这么写可以但是,如果以后数组的长度发生了变化呢?还是需要修改,能否动态修改这个长度呢?
        int leight = sizeof(nums) / sizeof(nums[0]);
        printf("leight = %i
    ",leight);
        // 通过 sizeof 查出nums 这个数组的总内存空间的长度,再通过 sizeof 查出数组中第一个元素的长度(因为数组只能存储同一个类型的元素,所以每个元素所占的内存空间都是一样的),两个相除就是这个数组的长度
        
        for (int i = 0; i <= leight; i++) {
            printf("nums[%i] = %i
    ",i,nums[i]);
        }
    

    数组的内存存储

    • 变量存储数据是从高字节开始存储
    • 数组存储数据是从低字节开始存储
        // 数组的内存存储是从低字节开始存储,变量存储是从高字节开始存储
        char charValue[4] = {'a','v','c','d'};
        printf("charValue[0] = %p
    ",&charValue[0] ); // 0x7ffeefbff20c
        printf("charValue[1] = %p
    ",&charValue[1] ); // 0x7ffeefbff20d
        printf("charValue[2] = %p
    ",&charValue[2] ); // 0x7ffeefbff20e
        printf("charValue[3] = %p
    ",&charValue[3] ); // 0x7ffeefbff20f
        // 可以看出随着索引的变化,内存地址是变大的,所以数组的内存存储是从低字节开始存储的
    

    • 其实数组名就是数组地址
    char charValue[4] = {'a','v','c','d'};
    printf("charValue 数据名的内存地址:%p
    ",&charValue);
    printf("charValue[0] = %p
    ",&charValue[0] );
    
    /*
    charValue 数据名的内存地址:0x7ffeefbff20c
    charValue[0] = 0x7ffeefbff20c
    */
    
    &charValue = charValue[0] = charValue
    
    • 数组的每一个元素是从低字节开始存储,但是每个元素中的值又是从高字节开始存储

    数组注意点

    • 在使用数组的时候一定不要访问不是属于自己的存储空间,这样会导致数据混乱
        // 数组的注意点
        char num[2] = {1,2};
        char value[3] = {4,5,6};
        
        value[3] = 44;
        printf("num[0] = %i
    ",num[0]);
    
    // 控制台输出
    // num[0] = 44
    

    数组的练习

        // 练习
        // 从键盘输入三个数,计算总值和平均值
        // 不使用变量接收,使用数组接收
        int nums[3] = {-1};// 数组部分初始化
        int leight = sizeof(nums) / sizeof(nums[0]);
        
        for (int i = 0; i < leight; i++) {
            printf("nums[%i] = %i
    ",i,nums[i]);
        }
        
        printf("----------
    ");
        
        for (int i = 0; i < leight; i++) {
            printf("请您输入一个数,回车结束
    ");
            scanf("%i",&nums[i]); // 赋值给每个索引的值
            // 1printf("nums[%i] = %i
    ",i,nums[i]);
        }
        
        printf("----------
    ");
        int sum = 0;
        for (int i = 0; i < leight; i++) {
            printf("nums[%i] = %i
    ",i,nums[i]); // 打印每个索引的值
            // sum = sum + nums[i];
            sum += nums[i];
        }
        printf("求和的值:%i
    ",sum);
        printf("求平均值的值:%i
    ",sum/leight);
    

    数组和函数

        // 数组和函数
        // 基本数据类型是值传递
        int num = 10;
        test(num);
        printf("num = %i
    ",num); // 此时 num 的值还是 10,并不 50,因为基本数据类型是值传递
        printf("main函数中的 num 内存地址:%p
    ",&num);
        
        // 此时看一看我们传递一个数组
        int array[] = {1,2,3};
        testArray(array);
        printf("array[0] = %i
    ",array[0]); // 100,因为数组是地址传递,内存地址在哪里修改了都会受到影响
        printf("array[1] = %i
    ",array[1]); // 2
        printf("array[2] = %i
    ",array[2]); // 3
        printf("main函数中testArray[0]的内存地址:%p
    ",&array[0]);
        printf("main函数中testArray[1]的内存地址:%p
    ",&array[1]);
        printf("main函数中testArray[2]的内存地址:%p
    ",&array[2]);
        // 通过打印内存地址可以看到,基本数据类型在方法中都是新开辟的内存地址,数组并不是
        
        return 0;
    }
    
    void test(int num){
        num = 50;
        printf("test 方法中的 num 内存地址:%p
    ",&num);
    }
    
    void testArray(int array[]){
        array[0] = 100;
        printf("testArray方法中的 array[0]的内存地址:%p
    ",&array[0]);
        printf("testArray方法中的 array[0]的内存地址:%p
    ",&array[1]);
        printf("testArray方法中的 array[0]内存地址:%p
    ",&array[2]);
    }
    
    
    // 注意只需要看函数的参数是传递的基本数据类型还是指针(地址)就可以
    
    main(){
        // 要求实现一个函数,只要传递的是一个数组,就返回数组中所有的值
        int array1[5] ={1,2,3,4,5};
        int leight = sizeof(array1)/sizeof(array1[0]);
        getArrayNum(array1,leight);
        return 0;
    }
    
    int getArrayNum(int array1[],int leight){
        // int leight = sizeof(array1)/sizeof(array1[0]);
        // 这里不能将 leight在这里计算,因为传递的是一个数组的地址,地址永远是占 8 个字节
        for (int i = 0; i < leight; i++) {
            printf("array1[%i] = %i
    ",i,array1[i]);
        }
        return 0;
    }
    
    

    练习 2

    main(){
            // 设计一个函数 int arrayMax()找出数组元素的最大值
        int array[] = {0,-5,3,8};
        int leight = sizeof(array)/sizeof(array[0]);
        int maxNum = arrayMax(array,leight);
        printf("最大值是:%i
    ",maxNum);
        return 0;
    }
    
    // 错误的写法,用第一个元素跟第二个元素比较,这种比较会超出数组的长度.返回一个垃圾值
    int arrayMax(int array[],int leight){
        int temp = 0;
        for (int i = 0; i < leight; i++) {
            if(array[i] >= array[i+1]){ 
                temp = array[i];
            }
            else{
                temp = array[i+1];
            }
        }
        return temp;
    }
    
    // 方法一 (设置一个临时值,用这个临时值跟数组的没一个值作比较,如果临时值小于,那就替换)
    int arrayMax(int array[],int leight){
        int temp = 0;
        for (int i = 0; i < leight; i++) {
            if(temp <= array[i]){
                temp = array[i];
            }
        }
        return temp;
    }
    
    // 但是方法一还存在问题,如果数组中的数都小于临时值的话那就出现了 bug
    // 所以用数组中的一个数作为最大值
    int arrayMax(int array[],int leight){
        int temp = array[0];
        for (int i = 0; i < leight; i++) {
            if(temp <= array[i]){
                temp = array[i];
            }
        }
        return temp;
    }
    
    
    //方法二 定义一个temp 值为索引值,
    int arrayMax2(int array[],int leight){
        int temp = 0;
        for (int i = 1; i < leight; i++) { // 此处 i 可以从 1 开始
            if(array[temp] <= array[i]){
                temp = i;
            }
        }
        return array[temp];
    }
    
    

    练习 3

        // 从键盘输入3 个 0-9 之间的数,然后输出 0-9 之间那些数没有出现过
        int num1,num2,num3;
        printf("输入
    ");
    //    scanf("%i",&num1);
    //    scanf("%i",&num2);
    //    scanf("%i",&num3);
        scanf("%i,%i,%i",&num1,&num2,&num3);
        printf("输入结束
    ");
        int array[3] = {num1,num2,num3};
        int leight = sizeof(array)/ sizeof(array[0]);
        for (int i = 0; i <= 9; i++) {
            if(array[0] != i &&
               array[1] != i &&
               array[2] != i){
                printf("%i没出现过
    ",i);
            }
        }
        
    
    
    
        // 方法二,输入三个数,使这三个数作为下标,将次s复制为 1,那么值 为 0 的就是没有输入过的数
        int array[10] = {0}; // 部分初始化,没有被初始化的都为 0,并不是垃圾值
        int value = -1;
        int leigth = sizeof(array) / sizeof(array[0]);
        for (int i = 0; i < 3; i++) {
            printf("请输入第%i个数,回车结束
    ",i+1);
            scanf("%i",&value);
            array[value] = 1;// 将每次的 value 值复制给
        }
        
        for (int i = 0; i <  leigth; i++) {
            printf("数组第%i 个的值:%i
    ",i,array[i]);
        }
        
        for (int i = 0; i < leigth; i++) {
            if(array[i] != 1){//只要是 值为 0 的那么就是没有出现过的,巧妙的利用了 0-9 之间的数,先将输入的数当做下标,把数组的这个下标的值设置为 1,那么m不是1 的值,他的下标就是么有c输入过的
                printf("0-9 之间没有出现过:%i
    ",i);
            }
        }
    

    练习 4

        // 要求从键盘输入6 个 0-9 之间的数,排序后输出
    
    	// 分析:部分初始化一个数组,依次输入 6 个数字,循环将输入的 6 个数作为下标,将数组中的数赋值为 1,那么此数组中值为 1 的下标就是输入的数,再次循环输出值为 1 的下标,既从小到大输出
        int array[10] = {0}; // 部分初始化
        int value = -1;
        int leight = sizeof(array) / sizeof(array[0]);
        for (int i = 0; i < 6; i++) {
            printf("请输入第%i个值:
    ",i+1);
            scanf("%i",&value);
            array[value] = 1;
        }
        
        for (int i = 0; i <= 9; i++) {
            if(array[i] == 1){
                printf("从小到大排序:%i
    ",i);
            }
            
        }
    
    
    
    // 改进:
        // 但是输入了相同的值时,不会依次输出.而是将之前的值进行了覆盖
        int array[10] = {0}; // 部分初始化
        int value = -1;
        int leight = sizeof(array) / sizeof(array[0]);
        for (int i = 0; i < 6; i++) {
            printf("请输入第%i个值:
    ",i+1);
            scanf("%i",&value);
            array[value] += 1; // 此处如果多次输入了d同一个下标,那么就进行加 1
        }
        
        for (int i = 0; i <= 9; i++) {
            if(array[i] != 0){ // 如果所在角标的值不是 0,那么久开始循环,条件表达式是 j<=这个下标所对的值
                for (int j = 1; j <= array[i]; j++) {
                    printf("从小到大排序:%i
    ",i);
                }
                
                
            }
            
    
  • 相关阅读:
    Jmeter之CSV文件读取
    性能计数器及性能分析方法
    性能测试的应用领域
    动态加载JS文件方法总结
    handler method 参数绑定常用注解
    A4纸网页打印
    page-break-before和page-break-after 实现分页打印
    $.ajax 中的contentType
    @Controller和@RestController的区别?
    web页面内容打印总结
  • 原文地址:https://www.cnblogs.com/shanshan-test/p/13021852.html
Copyright © 2011-2022 走看看