c知识记录-关于数组

关于数组

  1. C编译器不会检查数组的下标是否正确,而一般这种错误,会导致数据被放置在已被其他数据占用的地方,可能会破坏程序的结果、或导致程序异常中断(segment fault)

    float debts[20];
    
    debts[20] = 88.32; //这样的错误,编译器是找不出来的
    
  2. char型数组末尾包含空字符**‘\0’**,那数组的内容就构成一个字符串

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F0RtQ5oD-1661656316691)(关于数组.assets/image-20220807222425893.png)]

  3. scanf会跳过空白字符

  4. ⭐️模块化设计:就是把程序划分为一些独立的单元,每个单元执行一个任务

  5. 在c语言中,main()通常只提供整个程序的框架,最好把main()放在所有函数定义的前面

    • 这个意思就是,你把可以把函数的声明放在main函数前面(或头文件里),但是函数的定义,你要放在main函数的下面
  6. 要设置只读数组,加const即可,记得初始化

  7. 数组初始化用的数值少于数组元素个数时,编译器把剩余元素都初始化为0

  8. 初始化数组时,数组大小是可以省略的,这时⭐️编译器会根据初始化列表中的项数来确定数组的大小

  9. 计算数组大小公式:sizeof(days) / sizeof(days[0])

  10. 二维数组的初始化方法差异

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SVp5l3qE-1661656316695)(关于数组.assets/image-20220808215436668.png)]

  11. ⭐️数组名是该数组首元素的地址

  12. ⭐️在c中,指针加1指的是增加一个存储单元。

    • 换句话说就是:指针加1,指针的值递增它所指向类型的大小

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A5SFJkz4-1661656316696)(关于数组.assets/image-20220808215721576.png)]

  13. 许多计算机都是按字节编址,就是说内存中的每个字节都是按顺序编号的,比如double类型的变量,他的地址通常是该对象第一个字节的地址

  14. 在使用数组作为函数参数的时候,最好带上数组的大小作为参数

    int sum(int ar[], int n) // 这样的写法比 int sum(int *ar)更好,使用 int sum(int *ar, int n)也是可以的
    {
        int i = 0;
        int total = 0;
        
        for (; i < n; ++i)
        {
            total += ar[i];
        }
        
        return total;
    }
    
  15. C保证在给数组分配空间时,指向数组后面第一个位置的指针仍是有效指针

    #define SIZE 10
    
    int marbles[SIZE] = {26, 29, 0};
    
    int answer = sump(marbles, marbles + SIZE);
    
    int sump(int *start, int *end)
    {
        int total = 0;
        
        while(start < end)
        {
            total += *start; //把数组元素值加起来
            
            start++; // c的机制保证了指针指向数组后面下一个的时候,是有效的
        }
        
        return total;
    }
    
  16. total += *start++; //循环体内的简化版操作
    
    //建议写成
    total += *(start++)
    • ⭐️ 一元运算符*和++的优先级相同,但结合律是从右往左, 所以显示start++,再才是*start,
      • 先把指针指向位置上的值加到total上
      • 在递增指针
    • ⭐️ 如果使用*++start,则
      • 先递增指针
      • 再使用指针指向位置上的值
    • ⭐️ 如果使用(*star)++
      • 先使用指针指向的值
      • 在递增该值(不是递增指针)
      • 就是说指针一直指向同一个位置,但是该位置上的值发生了变化
  17. ⭐️数组名是不能做自增操作的,因为数组名虽然是指针,但是它是一个常量,常量是无法修改的

  18. 针对一个处理基本类型(如int)的函数时,会面临两种选择

    • 传递int类型的值
    • 传递指向int的指针
    • ⭐️ 通常都是直接传递数值,只有需要在函数中改变该数值时,才会传递指针
  19. 一般而言,在把数组作为函数参数时

    • 需要修改数组—在声明数组形参时不使用const
    • 不需要修改数组—在声明时加上const
  20. const指针:指向const、指向非const都是合法的

  21. 非const指针:只能指向非const

  22. 关于多维数组

    int zippo[4][2]
    
    • int zippo[4][2]:可以看做zippo是一个内涵4个元素的数组,每一个元素,含有2个int型元素
    • 最关键的就是指针的指向
      • zippo = &zippo[0] = &zippo[0][0]
      • c知识记录-关于数组_第1张图片
      • c知识记录-关于数组_第2张图片
  23. 使用二维数组作为形参

    • int array[3][4];
      
      /*第一个形参只描述了它是一个二维函数,且每一列都有4个,但是行数你不知道*/
      void func(int (*p)[4], int rows); 
      
      void func(int pt[][4], int rows);//空的方括号表示pt是一个指针
      
    • //这种写法是错误的
      //因为在编译的时候,编译器会把数组表示法转换成指针表示法
      //ar[1]转换成ar+1,编译器对ar+1求值,要知道ar所指对象的大小
      int sun2(int ar[][], int rows);
      
      int sun2(int ar[][4], int rows);//有效,ar+1,就是"该地址加上16字节"
      
      //你可以理解为ar[]就是ar指针,后面的括号是用于描述ar指针所指向数据对象的类型
      
    • c里规定,数组的维数是固定的,不能用变量来代替COLS(列数)

  24. 使用变长数组的特性

    • 变长数组中的,指的是:在创建数组时,可以使用变量指定数组的维度。而不是说可以随意修改已创建数组的大小

    • int sum(int rows, int cols, int ar[rows][cols]);//有效
      
      int sum(int ar[row][cols], int rows, int cols); //无效,因为ar的声明要使用rows和cols,所以在形参列表中必须在声明ar前先声明这两个形参
      
  25. c把数组名解释为该数组首元素的地址。换言之,数组名与指向该数组首元素的指针等价。

  26. 在C语言里,不能将整个数组传递给函数,但是可以传递数组的地址,然后借由函数地址操作原数组

  27. 如果在函数中,没有修改原数组的意图,应在声明函数的形式参数时使用功能关键字const

  28. 指针加上一个整数或递增指针,指针的值以所指向对象的大小为单位改变

你可能感兴趣的:(知识点总结,c语言)