Day10

作者: 喝酸奶要舔盖__ | 来源:发表于2018-09-10 12:34 被阅读0次

    指针

    • 指针与函数
    #include <stdio.h>
    void test();
    int main()
    {
        /*
         * 指向函数的指针
         *   计算机也会给函数分配存储空间,所以函数也有自己的地址,所以指针
         * 变量也可以保存函数的地址
         *
         * 数组名保存的就是数组的地址,函数名中保存的也是函数的地址
         *
         * 如何定义函数指针变量
         * 1. 将需要函数拷贝
         * 2. 在函数返回值和函数名之间加*
         * 3. 修改函数名称
         * 4. 需要将*和变量名称用括号括起来
         *
         * 注意点:
         * 如果是数组,我们可以直接将数组名称赋值给一个指针变量
         * 如果是函数,我们可以直接将函数名称赋值给一个指针变量
         */
    
        //定义函数指针变量
        void (*funcp)();
        //将函数的地址赋值给函数指针
    //    funcp = &test;
        funcp = test; //因为函数名称保存的是地址,所以这种写法也可以
    
    
    
        //test();  //调用函数的第一种方式
        //(*funcp)(); //调用函数的第二种方式
        funcp();  //调用函数的第三种方式
        return 0;
    }
    
    void test(){
        printf("打印点东西");
    }
    
    • 练习
      回调函数
    #include <stdio.h>
    int sum(int, int);
    int minus(int, int);
    int main()
    {
        /*
         * 需求: 要求一个函数既可以计算两个变量的和也可以计算两个变量的差
         */
        int res = test(10, 20, minus);
        printf("%i\n", res);
        return 0;
    }
    /*
     * 注意点: 指向函数的指针,作为函数的形参的时候,指针变量的名称,就是形参名称
     * 如果指向函数的指针作为函数的形参,那么这个函数可以称之为回调函数
     */
    int test(int a, int b, int (*funcp)(int ,int)){
        return funcp(a, b);
    
    }
    
    int sum(int a,int b){
        return a + b;
    }
    
    int minus(int a, int b){
        return a - b;
    }
    

    结构体

    • 基本概念
        /*
         * 结构体
         *   结构体是构造类型的一种,数组也是构造类型,数组的作用是存储一组相同
         * 类型的数据,结构体的作用是存储一组不同类型的数据
         *
         * 如何定义结构体变量
         * 1. 先定义结构体的类型
         * 2. 通过结构体的类型定义结构体的变量
         *
         * 定义结构体的类型
         * struct 结构体类型名称{
         *      数据类型 属性名称;
         *      数据类型 属性名称;
         *      .
         *      .
         * }
         *
         * 定义结构体变量
         * struct 结构体类型名称 变量名称;
         *
         * 访问结构体属性
         * 结构体变量名称.结构体属性名称;
         */
        //定义结构体的类型
        struct Person{
            char *name;
            int age;
            double height;
        };
        //定义结构体变量
        struct Person p;
        //使用结构体变量
        p.name = "niuzi";
        p.age = 18;
        p.height = 1.6;
        printf("%s\n", p.name);
        printf("%i\n", p.age);
        printf("%lf\n", p.height);
    
    • 结构体变量初始化
    /*
         * 结构体的初始化
         * 1. 定义的同时初始化
         * 2. 先定义后初始化
         * 3. 先定义结构体变量,后再完全初始化,但是不建议这样写
         */
        
        struct Dog
        {
           char *name;
           int age;
        };
        //1. 先定义后初始化
    //    struct Dog p;
    //    p.name = "ww";
    //    p.age = 10;
        
        //2. 定义的同时初始化
        //注意点: 定义的同时初始化,那么初始化顺序必须和结构体类型中的顺序一致
    //    struct Dog p ={"ww", 10};
        struct Dog p ={.name = "ww", .age = 10}; //这种顺序可以变
    
    • 定义结构体变量
    /*
         * 定义结构体变量的几种方式
         * 1. 先定义结构体类型,再定义结构体变量
         * 2. 定义结构体类型的同时定义结构体变量
         * 3. 定义结构体类型的同时省略结构体名称,同时定义结构体变量
         */
        //1.先定义结构体类型,再定义结构体变量
    //    struct Person
    //    {
    //        char *name;
    //        int age;
    //    };
    //    struct Person p;
    
        //2. 定义结构体类型的同时定义结构体变量
        struct Person
        {
            char *name;
            int age;
        } p2;
    
        p2.age = 18;
        p2.name = "ll";
        printf("%i\n", p2.age);
    
        //3. 定义结构体类型的同时省略结构体名称,同时定义结构体变量
        //匿名结构体,结构体类型只能使用一次
        struct
        {
            char *name;
            int age;
        } p3;
    
    • 结构体变量作用域
      结论; 和变量的作用域一样,在代码块中只能在该代码块中使用,外界无法访问的到

    • 结构体数组
      定义一个数组保存结构体变量

        /*
         * 结构体数组
         * 结构体类型 数组名称[元素个数];
         */
        struct Person
        {
            char *name;
            int age;
        };
        struct Person p1 = {"ww", 16};
        struct Person p2 = {"jj", 18};
        struct Person p3 = {"nn", 20};
        //结构体数组第一种方式
        struct Person ps[3] = {p1, p2, p3};
        //结构体数组第二种方式
        struct Person ps[3] = {
            {"ww", 16},
            {"jj", 18},
            {"nn", 20}    
        };
    
    • 结构体内存分析


        /*
         * 结构体内存分析
         */
    
        /*
         * 结构体在分配内存的时候,会做一个内存对齐操作
         * 会先获取所有属性中内存最大的属性的字节,然后在开辟最大属性字节的内存给第一个属性
         * 之后再分配给第二个属性,如果分配的内存存储第一个属性后,不够第二个属性存储
         * 那么会再次开辟最大属性字节的内存,再往后分配
         * 
         */
        
        struct Person
        {
            char *name;
            int score;
        };
        
        //结构体在分配内存的时候,会做一个内存对齐的操作,会按照结构体属性当中
        // 占用内存最大的那个字节属性的字节倍数来分配
        
        struct Person p;
        printf("sizeof = %i\n", sizeof(p)); //8
        //结构体变量名称没有保存结构体首属性的地址
        printf("p = %p\n", p); //00000054
        printf("&p = %p\n", &p); //0028FEB8
        printf("p.name = %p\n", &p.name); //0028FEB8
        printf("p.score = %p\n", &p.score); //0028FEBC
    
    • 结构体指针
    /*
         * 结构体指针
         * 定义指向结构体变量的指针的套路和过去定义指向普通变量一样
         * 
         * 如果指针指向了一个结构体变量,那么访问结构体属性就有三种方式
         * 1. 结构体变量名称.属性名称
         * 2. (*结构体指针变量名称).属性名称
         * 3. 结构体指针变量->属性名称
         */
    
        struct Person
        {
           char *name;
           int age;
        };
        struct Person per = {"niuzi", 18};
        //定义结构体指针
        struct Person *p;
        p = &per;
        //指针两种访问属性方式
        printf("%s\n", (*p).name);
        printf("%i\n", p->age);
    
    • 结构体嵌套
        /*
         * 结构体嵌套
         * 可以提高代码的复用率
         */
    
        //1. 定义一个日期的结构体
        struct Date
        {
           int year;
           int month;
           int day;
        };
        //2. 定义一个人的结构体
        struct Person
        {
           char *name;
           int age;
           struct Date birthday;  //结构体嵌套
        };
        //结构体嵌套初始化
        struct Person per = {"ww", 18, {2008,10,23}};
        printf("%i\n", per.birthday.year); //访问嵌套属性
        printf("%i\n", per.birthday.month);
        printf("%i\n", per.birthday.day);
    
    • 结构体和函数
      注意点: 结构体变量之间是值传递,和普通变量一样
     /*
         * 结构体和函数
         * 结构体是构造类型,但是结构体变量之间是值传递,和普通变量一样
         *
         * 注意点: 定义结构体类型的时候不会分配存储空间,只有定义结构体变量
         * 的时候才会分配存储空间
         */
    
        struct Person
        {
            char *name;
        };
        struct Person p1 = {"nn"};
        struct Person p2;
        p2 = p1; //值传递
        p2.name = "haha";
        printf("p1 = %s\n", p1.name); //nn
        printf("p2 = %s\n", p2.name); //haha
    
    #include <stdio.h>
    struct Person
    {
        char *name;
    };
    void test(struct Person per);
    
    int main()
    {
        /*
         * 结构体和函数
         * 结构体是构造类型,但是结构体变量之间是值传递,和普通变量一样
         *
         * 注意点: 定义结构体类型的时候不会分配存储空间,只有定义结构体变量
         * 的时候才会分配存储空间
         */
    
    //    struct Person
    //    {
    //        char *name;
    //    };
    //    struct Person p1 = {"nn"};
    //    struct Person p2;
    //    p2 = p1; //值传递
    //    p2.name = "haha";
    //    printf("p1 = %s\n", p1.name); //nn
    //    printf("p2 = %s\n", p2.name); //haha
    
        struct Person p1 = {"nn"};
        test(p1);
        printf("p1 = %s\n", p1.name);
    
    
        return 0;
    }
    /*
     * 在main函数中结构体是局部,外部函数无法访问所以要放到外面
     * 结构体变量是值传递,不是传递地址,所以函数内部无法改变结构体的属性
     */
    void test(struct Person pe){
        pe.name = "zs";
    }
    

    相关文章

      网友评论

          本文标题:Day10

          本文链接:https://www.haomeiwen.com/subject/pcnjgftx.html