zoukankan      html  css  js  c++  java
  • 初学c课程笔记整理7-->>二维数组、字符串、指针

    是什么?有什么用?用在什么地方?(理解)
    养成良好的编程习惯;
    培养编程思想;
    写代码之前应该先分析需求,分析完需求再开始写代码;(写注释)
     
    1.二维数组
     
    1.1 二维数组的基本概念:
     
         所谓多维数组就是一个一维数组的每个元素又被声明为一 维数组,从而构成二维数组. 可以说二维数组是特殊的一维数组。
     
      示例
          int a[2][3]
         可以看作由一维数组a[0]和一维数组a[1]组成,这两个一维数组都包含了3个int类型的元素
     
    1.2 二维数组的定义:
     
         数组中的每一个元素又是一个数组, 那么这个数组就称之为二维数组
         元素类型 数组名称[一维数组的个数][每个一维数组的元素个数];
         元素类型 数组名称[行数][列数];
        
         元素类型: 说明二维数组中每个一维数组存储什么类型的数据
         一维数组的个数: 说明二维数组有多少个元素
         每个一维数组的元素个数 说明二维数组中每一个一维数组的元素个数
         */
        int scoress[3][5] =
        {
            {1, 3, 5, 7, 9}, // 0 
            {2, 4, 6, 8, 10},// 1
            {1, 2, 3, 4 , 5} // 2
        };  // 每一个一维数组都是二维数组的一个元素
     
     如何遍历二维数组
         思路: 1.取出二维数组的每一个元素(取出二维数组中的一维数组)
              2.遍历一维数组
     
    1.3 二维数组的存储
    存储方式:
         1)计算机会给二维数组分配一块连续的存储空间
         2)数组名代表数组的首地址,从首地址位置,依次存入第1行、第2行、.....
         3)每一行存储方式,从行首地址还是,依次存储行的第1个元素、第2个元素、第3个元素......
         4)每个元素占用相同的字节数(取决于数组类型)
         5)并且数组中元素之间的地址是连续
     
    二维数组的存放顺序是按行存放的,先存放第一行的元素,再存放第2行的元素
         
    1.4 二维数组初始化及注意点:
     
    1.3.1二维数组的多种初始化方式
         1.定义的同时初始化
        int names[2][3] =
        {
            {'l', 'n', 'j'},
            {'x', 'm', 'g'}
        };
         2.先定义再初始化
        int names2[2][3];
        names2[0][0] = 'l';
        names2[0][1] = 'n';
        names2[0][2] = 'j';
       
        names2[1][0] = 'x';
        names2[1][1] = 'm';
        names2[1][2] = 'g';
        
         3.完全初始化
        int names3[2][3] =
        {
            {'l', 'n', 'j'},
            {'x', 'm', 'g'}
        };
       
         4.不完全初始化
        int names4[2][3] =
        {
            {'l', 'n'},
        };
       
        5.省略元素个数的两种写法
         明确的告诉二维数组, 我们有2个一维数组
        char names5[2][3] =
        {
            'l', 'n', 'j',
            'x', 'm', 'g'
        };
        char names15[2][3] =
        {
            'l', 'n', 'j',
            'x', 'm'
        };
       
         没有告诉二维数组我们有几个一维数组
         如果在"定义的同时"进行初始化, 那么一位数组的个数可以省略
        系统会自动根据每一个一维数组能够存放多少个元素, 自动根据初始化的值推断出二维数组中一共有多少个元素(多少个一维数组)
        char names6[][3] =
        {
            'l', 'n', 'j',
            'x', 'm', 'g',
            'n', 'b'
        };
       
         6.错误写法
        ⚠️ 注意点: 每个一维数组的元素个数不能省略
     
        int names7[2][] =
        {
            {'l', 'n', 'j'},
            {'x', 'm', 'g'}
        };
        
         搞不清楚应该分配多大的存储空间, 以及搞不清楚应该把哪些数据赋值给第一个数组, 以及哪些数据赋值给第二个数组
        int names7[2][] =
        {
            'l', 'n', 'j',
            'x', 'm', 'g'
        };//错误写法
        
    1.5 二维数组与函数
     
     
    1.二维数组的元素作为函数参数
     二维数组的元素就相当于变量,作为函数参数与变量相同 
     
    2.二维数组中的一维数组作为函数
     二维数组的一维数组实际上就是一个一维数组,作为函数参数与一维数组相同
     
    3.二维数组作为函数参数
      **二维数组作为函数参数是地址传递**
     二维数组作为函数形参,参数中一维数组的元素个数不可以省略
    void test(char cs[2][]) // 错误写法
    {
        printf("我被执行了 ");
    }
     
    void test(char cs[2][3]) // 正确写法
    {
        printf("我被执行了 ");
    }
     
    void test(char cs[][3]) // 正确写法
    {
        printf("我被执行了 ");
      二维数组作为函数参数,在被调函数中不能获得其有多少行,需要通过参数传入。
    ```
    void test(char cs[2][3])
    {
        int row = sizeof(cs);
        printf("row = %zu ", row);
    }
    输出结果:
    row = 8
    ```
     
    - 二维数组作为函数参数,在被调函数中可以计算出二维数组有多少列
     
    ```
    void test(char cs[2][3])
    {
        size_t col = sizeof(cs[0]);
        printf("col = %zd ", col);
    }
    输出结果:
    col = 3
    ```
     以后只要看到函数的参数是一个数组, 那么就是地址传递
     在函数中修改形参的值会影响到参数
     
    2.字符串
     
    1.字符串概念
     
          字符串是位于双引号中的字符序列
          在内存中以“”结束,所占字节比实际多一个
     
    2.字符串的初始化
     
    - 在C语言中没有专门的字符串变量,通常用一个字符数组来存放一个字符串。前面介绍字符串常量时,已说明字符串总是以‘’作为串的结束符。因此当把一个字符串存入一个数组时,也把结束符‘’存入数组,并以此作为该字符串是否结束的标志。有了‘’标志后,就不必再用字符数组 的长度来判断字符串的长度了。
     
    - 初始化
    ```
        char name[9] = "lnj"; //在内存中以“”结束, ASCII码值是0
        char name1[9] = {'l','n','j',''};
        char name2[9] = {'l','n','j',0};
        char name3[9] = {'l','n','j'};//静态数组如果没有赋值默认就是0,0就相当于
    ```
    - 错误的初始化方式
    ```
         //不正确地写法,结尾没有 ,只是普通的字符数组
        char name4[] = {'l','n','j'};
     
         //    的作用:字符串结束的标志
        char name[] = "cool";
         printf("name = %s ",name);
    输出结果: c
     
    3.字符串的输出、输入
         使用的格式字符串为“%s”,表示输入、输出的是一个字符串
            scant(“%s”,ch);//输入
            printf(“%s”,ch);//输出
       %s的原理, 从传入的"地址"开始逐个取出, 直到遇到""位置
     
    4.字符串的注意点
     字符串注意点, 字符串的初始化
        char str1[] = "lnj";
        char str2[] = {'l', 'n', 'j', ''};
        // 部分初始化, 部分初始化中, 没有被初始化的元素默认是0
        // 对应的ASCII 0
        char str3[10] =  {'l', 'n', 'j'}; // l n j 0000000
       
        char str4[3] = {'l', 'n', 'j'}; // 该方式不是字符串, 而是字符数组, 因为没有
        char str5[] = {'l', 'n', 'j'}; // 错误写法
       
           需要明白的一点就是字符串以结尾, 没有就不是字符串
           只要是用双引号括起来的都是字符串
           字符串的本质就是数组
    3.指针(重点)只能保存地址
    3.1内存地址
    地址与内存单元中的数据是两个完全不同的概念
        地址如同房间编号
        内存单元如同房间
        内存单元中存放着数据
     
    变量地址:
         系统分配给"变量"的"内存单元"的起始地址
     
    3.2 什么是指针
          在计算机中所有数据都存储在内存单元中,而每个内存单元都有一个对应的地址, 只要通过这个地址就能找到对应单元中存储的数据. 由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。因此,将地址形象化的称为“指针”
     
    内存单元的指针(地址)和内存单元的内容是两个不同的概念。
     
    3.3 什么是指针变量
    在C语言中,允许用一个变量来存放指针,这种变量称为指针变量。因此,一个指针变量的值就是
    某个内存单元的地址或称为某内存单元的指针。
        + 严格意义上说,指针是一个地址,是一个常量
        + 针变量是存放一个地址,是一个变量。
     
     示例
     
     
    3.4定义指针变量的格式
     指针变量的定义包括两个内容:
         指针类型说明,即定义变量为一个指针变量;
         指针变量名;
    > 其中,*表示这是一个指针变量,变量名即为定义的指针变量名,类型说明符表示本指针变量所指 向的变量的数据类型
     
    char *p; // 一个用于指向字符形变量的指针
    int *q; // 一个用于指向整形变量的指针
    long *t; // 一个用于指向长整形变量的指针
    float *r; // 一个用于指向单精度浮点形变量的指针
    double *s; // 一个用于指向双精度浮点形变量的指针
     
    ⚠️注意
         1)在定义指针时,“*”号表示定义的变量是指针变量,变量的值只能存放地址。
         2)一个类型的指针只能指向同类型的变量,不能指向其他类型的变量。
         3)指针也可以被声明为全局、静态局部和局部的。
     
    3.5指针变量初始化及注意点
     
    1.指针变量的初始化方法
     指针变量初始化的方法有两种:定义的同时进行初始化和先定义后初始化
        定义的同时进行初始化
               
                int a = 5;
                int *p = &a;
     
        先定义后初始化
     
                int a = 5;
                int *p;
                p=&a;
     
         把指针初始化为NUL
     
                int *p=NULL;
                int *q=0;
     
    不合法的初始化:
        指针变量不能被赋值一个整数值(因为我们不知道这个整形常量是内存哪块地址
    int *p;
    p =  250; // 错误写法
    int *p;
    *p=&a; //错误写法
    int *p;
    *p = &a;//正确写法
    ⚠️注意:
    多个指针变量可以指向同一个地址
     
    指针的指向是可以改变
    int a = 5;
    int *p = &a;
    int b = 10;
    p = &b; // 修改指针指
     指针没有初始化里面是一个垃圾值,这时候我们这是一个野指针
        + 野指针可能会导致程序崩溃
        + 野指针访问你不该访问数据
        + 所以指针必须初始化才可以访问其所指向存储区域
     
    访问指针所指向的存储空间
    int a = 5;
    int *p = &a;
    printf("a = %d", *p); // 访问指针变量
     
    4.(多)二级指针
     
    二级指针介绍
    如果一个指针变量存放的又是另一个指针变量的地址,则称这个指针变量为指向指针的指针变量。也称为“二级指针”
     
     
    char c = 'a';
        char *cp;
        cp = &c;
        char **cp2;
        cp2 = &cp;
        printf("c = %c", **cp2);
     
    多级指针介绍
    int ***m1; 取值***m1
    int *****m2 取值*****m2
     
     
  • 相关阅读:
    iostream与iostream.h的区别
    [HAOI2011]向量
    [POI2011]Temperature
    [洛谷2839/国家集训队]middle
    [TJOI2013]松鼠聚会
    [HNOI2015]接水果
    [BZOJ3772]精神污染
    [BZOJ3251]树上三角形
    [ZJOI2011]道馆之战
    [SDOI2013]森林
  • 原文地址:https://www.cnblogs.com/dreamWanweidong/p/4903216.html
Copyright © 2011-2022 走看看