C语言——结构体、局部变量和全局变量、枚举

来源:互联网 发布:linux mutex 实现原理 编辑:程序博客网 时间:2024/06/06 04:11

局部变量与全局变量

   按照作用域不同将变量分为 局部变量和全局变量
   局部变量:定义在函数内部变量
   作用域:从定义的那一行开始直到所在代码结束
   生命周期:从定义的那一行开始只直到其所在代码结束
   注意点:内部代码块中定义与外部代码块中的同名变量,那么内部代码中变量会覆盖外部代码块中定义的变量
   局部变量只有定义没有声明,存储位置:栈
 
   全局变量:定在函数外部变量,在所有函数中都可访问全局变量
   作用域:从定义的那一行开始直到文件结束
   生命周期:从程序加载的时候,直到程序退出
 
   全局变量的定义:变量类型 变量名称 = 值
   全局变量的声明  变量类型 变量名称
   1、全局变量的声明可以重复
   2、全局变量的定义不可以重复

   3、全局变量若只有声明没有定义那么系统会自动给它定义并将其初始化为 0
     作用域:从定义哪一行开始知道文件结束
     生命周期:从程序启动到程序退出
     存储位置:全局区

结构体

 void test(){
    //   结构体是一种构造类型
    //   构造类型:可以存放其他类型的那么一种类型
    //   数组:它只能存放一种数据类型的多个数据
    int nums[] = {1,3,4};
       Person(人)  年龄(int) 身高(float) 名字(char *)
        int Person[3] = {10,2.1,"巨人"};
        printf("%d,%d,%d",Person[0],Person[1],Person[2]);
        结构体定义格式:
        struct 结构体类型名称{
            数据类型 成员名称;
            ....
       };
    
    struct Person{
        int age;//此处也是分号
        float height;
        char *name;
        
    };//此处必须以分号结尾
    
    数据类型 变量名称
    结构体类型 结构体变量名称
    结构变量的定义
    struct Person p;
    //    p.age = 10; //通过.访问结构变量中成员
    //    p.height = 2.1f;
    //    p.name = "姚明二代";
    
    printf("age = %d,heigth = %.2f,name = %s\n",p.age,p.height,p.name);
}

结构体多种初始化方式

    struct Person{
        int age;
        float height;
        char *name;
    };
    
    1、先定义再初始化
    struct Person p;
    p.age = 10;
    
     2、定义的同时进行初始化
    struct Person pp = {10,2.1f,"ymsd"};
    
    printf("age = %d,heigth = %.2f,name = %s\n",pp.age,pp.height,pp.name);
     3、为指定的成员进行初始化
    struct Person ppp = {.age = 20,.name = "ym"};
    printf("age = %d,name = %s\n",ppp.age,ppp.name);
    
     4、结构体变量不可以在定义之后使用整体赋值的方式
     pp = {30,1.2,"zl"};

     5、可以将相同类型的结构变量赋值给另外的结构变量,把这个变量每一个成员赋值给另外一个变量的对应的成员

结构体内存分析

void test(){
    //    定义一个日期的结构体 年 月 日
    //  定义结构类型的时候不会分配存储空间,就如同我们系统不会int 分配存储空间一样
    struct Date{
        int year;
        int mouth;
        int day;
    };
    printf("%d",Date.year);
    //只有通过结构体类型定义变量的时候,才会为这个结构的变量分配存储空间
    struct Date today = {2014,7,21};
    size_t len =  sizeof(today);
    printf("%lu\n",len);
    //当这个结构类型中所有成员类型都相同的时候,那么结构体所在占用存储空间位所有成员的所占用存储空间的和
    //   按照定义的成员顺序来分配存储空间
    //   此时这个结构体它与一个基本数据类型的变量  today != &today
    // 在系统为结构分配存储空时候有一个补齐算法,要求结构体所占用存储空间是占用存储空间最大的成员,所占用存储空间的倍数
    printf("%p\n",today);
    printf("%p\n",&today);
}

多种定义方式

#include <stdio.h>
int main(int argc, const char * argv[]){
先定义结构体类型再定义结构变量

定义一个点 (x,y)
    struct Point{
        int x;
        int y;
    };
    struct Point p1 = {1,1};
第二种方式:定义结构体类型的同时定义结构体变量
    struct Point1{
        int x;
        int y;
    } p2 = {1,1};
    p2.x = 1;
    p2.y = 1;  
//结构体定义不可以重名
//    struct Point1{
//        int x;
//        int y;
//    } p3 = {1,1};
总结:凡是有名字的东西,在相同代码块都是不可以重名的
第三种方式 定义一个匿名的结构类型,同时定义结构变量
    struct{
        int x;
        int y;
    } p3 = {1,1};
    struct{
        int x;
        int y;
    } p4 = {1,1};

  1、缺点:这种结构类型不可以重复使用
    return 0;
}

结构体数组

#include <stdio.h>
int main(int argc, const char * argv[]){
    int nums[] = {1,2,3,4};
    struct Point{
        int x;
        int y;
    }; 
//  先定义结构体数组再进行初始化
    struct Point ps[3];
    ps[0].x = 1;
    ps[0].y = 1;
    
    printf("%d,%d\n",ps[0].x,ps[0].y);
    
// 定义结构数组的同时进行初始
    struct Point points[] = {
        {1,1},
        {1,2},
        {1,3}
    };
//  结构体数组的遍历
    int size = sizeof(points) / sizeof(struct Point);
    for (int i = 0; i < size; i++) {
        printf("(%d,%d)\n",points[i].x,points[i].y);
    }
//    points[0] = {2,2};
//   只能在定义结构体数组的同时进行整体的初始化,不可以定义后使用整体赋值方式
    struct Point p;
//    p = {2,2};
    return 0;
}

结构类型的作用域

//定义在函数外部结构体类型的作用域:从定义的哪一行开始,直到文件结尾
//结构体类型的定义没有声明的
//  结构体定义也是有作用域的
// 函数内部定义的结构类型与局部变量的的作用相同
//  在函数内部定义的与外部同名结构类型,那么内部结构类型覆盖外部结构类型

结构体指针

#include <stdio.h>
int main(int argc, const char * argv[]){
//   数据类型 * 变量名称
//    1、首先定义一个Person 的结构体类型
    struct Person{
        int age;
        float heigth;
        char *name;
    };
//    2、定义结构体变量
    struct Person p = {10,1.3,"xh"};
//    3、定义一个结构体类型的指针
    
    struct Person *pp;
    pp = &p;
    printf("%d\n",p.age);
//  第一种方式
    (*pp).age = 20;
    printf("%d\n",p.age);
//  第二种方式
    pp->age  = 30;//结构指针访问成员最常用方式
    printf("%d\n",p.age);
    return 0;
}

结构体与函数

//结构变量作为函数参数传递是值传递
#include <stdio.h>
struct Person{
    int age;
    float height;
    char *name;
};

void printPerson(struct Person person){
    person.age = 20;
    printf("age = %d,height = %.2f,name = %s\n",person.age,person.height,person.name);
}

int main(int argc, const char * argv[]){
    struct Person p = {10,1.6f,"zc"};
      printPerson(p);
    printf("%d\n",p.age);
    return 0;
}

结构体嵌套

 结构体不可以直接嵌套也就是说它不可以直接定义自己本身的结构体类型的成员
    struct Person{
       int age;
        struct Person son;
    };

枚举

 当一个变量只有几个固定的取值时候就是用枚举
 枚举的作用:提高代码可读性
    int sex = 0;
    可以为枚举类型指定初始值,若没有指定就是从0开始
    enum Sex{
        Man = 1,//此处是个逗号
        WoMan,
        Other
    };
    enum Sex s = Man;
    
 枚举类型它不是构造类型,枚举的实质是一个整形
 枚举里面成员默认是从0开始的

数据类型的总结

一、基本数据类型
        整形
            int         %d 4个字节
            short       %hd 2个字节
            long        %ld 8字节
            long long   %lld 8字节
            signed  表示有符号数,默认就有符号
            unsigned 表示无符号数,表示正整数的范围比有符号数大一倍
        字符型 char  %c  1个字节  本质是整形
        浮点型:
             float  %f  4字节
             dobule %lf 8字节
        枚举:当一个变量只有几个固定的取值的时候就使用枚举
        枚举类型定义格式:
        enum 枚举名称{
            成员,
            ...
        };
        作用:提高代码的可读性
        特点:先定义枚举类型 再定义枚举变量
     
     二、构造类型
         1、数组:用来保存相同数据类型的多个数据的集合
         数组定义格式:数据类型 数组名称[元素个数]
         我们是同下标访问数组中元素
         特点:只能保存一种数据类型的数据
         2、结构体:用来保存不同数据类型的多个数据的,
                  相同数据类型的但可以表示特定含义的也使用结构体
         定义格式:
         struct 结构体类型{
            成员类型 成员名称;
            .....
         };
         作用:1、提高代码的可读性
              2、让代码结构化
         特点:先定义结构体类型,然后定义结构体变量
     
     三、指针类型:
            指针:就是内存中字节地址编号,只要有地址就可以访问对应的存储空间。
            特点:间接性
        1、基本数据类型的指针
           int a = 10;
           int *p = &a;
           *p;//访问p所指向存储空间的值
        2、指针与数组
           int nums[] = {1,2,3};
           int *p = nums;
           p[1] == nums[1] == *(p + 1) == *(num + 1)
        3、指向数组的指针
           int names[][10] = {"zsf","sb"}
           int (*p)[10]  = names;
        4、结构体指针
           struct Person { int age};
           struct Person p = {10};
           struct Person *pp = &p;
           pp->age;
        5、函数指针:指向函数的指针
          int sum(int num1,int num2) { retunr num1 + num2; }
         
          int (*sumPointer)(int,int) = sum;
          sumPointer();
     
总结数据类型的特点:
     1、所有的数据类型都可以定义变量
     2、所有的数据类型都可以作为函数参数
     3、所有的数据类型都可以作为函数的返回值

结构体总结

结构体:用来存储不同数据类型的多个数据,相同数据类型只要能表示特定含义就可以使用结构体
     特点:先定义结构体类型,然后定义结构体变量
     作用:1、提高代码的可读性
          2、让代码更有组织
          3、封装数据
     结构体类型的定义格式:
     struct 结构体类型名称{
            数据类型 成员名称;
            ....
     };
//   定义结构体变量
     struct 结构体名 结构体变量名
     结构体初始的多种方式
     1、先定义结构体变量,然后初始化
     2、定义结构体变量的同时,初始化结构体成员
     3、定义结构体变量的同时,为指定的成员初始化
     注意点:
     定义后的结构体变量不可以使用一次赋值方式,进行赋值
 
     结构体的内存分析:
        1、结构体是按照成员定义顺序来分配存储空间
        2、结构体在分配存储空的时候有一个补齐算法,它要去结构体所占存储空间是其中占用存储空间最大的成员所占用存储空间的倍数
        3、结构体中所有成员的数据类型相同,那么结构体所占存储空间为各个成员所占存储空间之和
    
      结构体类型定义多种方式
      1、向定义结构体类型,然后定义结构体变量
      2、定义结构体类型的同时定义结构体变量
      3、定义匿名结构体类型同时定义结构体变量
 
     结构体类型的作用域
       在方法内部结构体类型的作用域与局部变量相同
       在方法外部定义的结构体类型的作用域与全局变量相同
       注意:结构体类型没有声明
    
    结构体数组:存储结构体的数组
    struct Person{ int age;};
    struct Person persons[5] = { {10},{20},{30} }
    结构体数组的遍历与基本数据类型的数组遍历方式相同的
 
    结构体指针:指向结构体类型的指针
    struct Person *p;
    
    结构体与函数
        1、结构体变量作为函数参数传递是指传递
        2、结构体指针作为函数参数传递是地址传递
 
    结构体嵌套:
        一个结构体内部可以嵌套其他类型结构体
        结构体不可以嵌套自己,但可以嵌套自己的指针
 
    枚举:当某个东西只有几个固定取值,我们就是用枚举,比如性别、颜色
    特点:先定义枚举类型,再定义枚举变量
    enum 枚举类型名称{
         成员,
         ....
    };
 
    枚举类型的实质是整形
 
    enum 枚举类型名称 变量名称 = 成员
 
    有了枚举我就不要再使用相关的数值来表示某个枚举成员

0 0
原创粉丝点击