ios学习之旅------玩转结构体

摘要:
在局部变量的作用域范围内。直到文件结束生命周期:从程序启动開始。其它与普通变量一样#includestructPerson{intage;charsex;};intmain{structPersonp2;p2.sex='s';p2.age=10;structPerson{intage;};structPersonp={10};printf;{structPersonp={20};structMonkey{char*name;};}return0;}5.结构体数组结构体数组:数组元素为结构体数组定义结构体数组结构类型数组名称[元素个数];数组元素的类型数组名称[元素个数];#include//普通情况下结构体类型都是定义在函数的外部structDog{char*name;intage;};voidtest(){//intnums[]={1,2,3,4};//结构体假设没有初始化。
1.全局变量和局部变量
局部变量:
概念:定义函数内部变量
定义格式:变量类型 变量名称;
作用域:从定义那一行開始到所在代码块结束
生命周期:从代码运行到定义的哪一行開始,到其所在的代码的结束为止
特点:同样的代码块中不能够有同名的变量
不同的代码块中能够有同名的变量。内部的变量会覆盖外部定义的变量
全局变量:
概念:定义在函数外部变量
定义:变量类型 变量名称 = 值;
声明:变量类型 变量名称;
特点:1、不能够反复定义,但能够反复声明
2、局部变量能够与全局变量同名。在局部变量的作用域范围内。那么局部变量会覆盖全局变量
3、假设未定义仅有声明,系统自己主动给它定义并将其初始化为0
作用域:从定义的那一行開始。直到文件结束

生命周期:从程序启动開始。直到程序退出才消亡

#include <stdio.h> 
 int num;//声明
int main(int argc, const char * argv[]) {    
    printf("num = %d
",num);    
    int num = 20;
    printf("num = %d
",num);
    {
        num = 40;
        int num = 10;
        printf("num = %d
",num);
        num = 30;
    }
    printf("num = %d
",num);         
    return 0;
}
2.结构体
构造类型:由已有的数据类型构成类型
1、数组:多个同种类型的数据构成的那么一种类型
特点:仅仅能存放一种数类型
2、结构体:从来存放表示某种特定含义的一组数据
它是对数据封装
函数对功能封装
优点:提高代码的可读性
提高数据易用性
提高代码可维护性

定义结构体:
1、定义结构类型
struct 结构类型名称{
成员类型 成员名称;
...
};//必须加分号
2、通过结构体类型定义结构变量
struct 结构类型名称 结构体变量名称;
#include <stdio.h>
int main(int argc, const char * argv[]) {

    //    int scores[] = {59,60};    
    //     int  年龄  姓名 char *  性别 char  身高 double  体重 double        
    //    int age;
    //    char sex;
    //    double height;
    //    double weight;
    //    char *name;
    //
    //    int ages[50];
    //    char sex[50];
    //    ....
    //  定义一个人结构体类型
    struct Person{
        int age;
        char sex;
        double height;
        double weight;
        char *name;
    };    
    //  int num;
    //  int * pointer;
    //  定义结构体变量
    struct Person person;    
    //  訪问结构体成员
    person.age = 10;    
    person.sex = 'M'; 
    person.weight = 20.2;    
    person.height = 1.2;    
    person.name = "小明";    
    printf("age = %d,sex = %c,weight = %.2lf,height = %.2lf,name = %s
",person.age,person.sex,person.weight,person.height,person.name);
   
    return 0;
}
ios学习之旅------玩转结构体第1张
3.定义结构体的多种类型
#include <stdio.h>
/*
 第一种方式
  1、先定义结构体类型
  2、定义结构变量
 */
void test()
{
    
    struct Person{
        int age;
        double height;
    };
    
    struct Person p1;
}

/*
另外一种方式
   定义结构体类型的同一时候定义结构变量
 */
void test1()
{
    struct Person{
        int age;
        double height;
    } p1,p2 = {20,1.75};
    
    p1 =(struct Person){10,1.2};
    
    printf("age = %d,height = %.2lf
",p1.age,p1.height);
    
    printf("age = %d,height = %.2lf
",p2.age,p2.height);
    //  结构体类型定义是不能够重名的
    //    struct Person{
    //        int age;
    //        double height;
    //    } p3,p4 = {20,1.75};
}
/*
第三种方式
   定义匿名的结构类型的同一时候定义结构体变量
 */
int main(int argc, const char * argv[]) { 
    struct{
        int age;
        char sex;
    } p1,p2 = {20,'M'};
    p1.age = 10;
    p1.sex = 'W';
    printf("age = %d,sex = %c
",p1.age,p1.sex);
    p1 = p2;
    printf("age = %d,sex = %c
",p1.age,p1.sex);
    //
    //    p1 = (struct) {10,'w'};
    //   1、不支持总体赋值
    //   2、结构体类型不能反复使用
    struct{
        int age;
        char sex;
    } p3,p4 = {20,'M'};   
    return 0;
}
4.结构体作用域
在函数内部,结构类型作用域就如同局部变量一样
在外边定义的结构体类型像全局变量的作用域
作用域:从定义的那一行開始直到文件的结束
注意点:结构类型不能声明
结构体类型的作用,除了不能声明以外。其它与普通变量一样
#include <stdio.h>
struct Person{
    int age;
    char sex;
};
int main(int argc, const char * argv[]) {  
    struct Person p2;    
    p2.sex = 's';
    p2.age = 10;    
    struct Person{
        int age;
    };  
    struct Person p = {10};
    printf("age = %d
",p.age);  
    {
        struct Person p = {20};
        struct Monkey{
            char *name;
        };    
    }    
    return 0;
}

ios学习之旅------玩转结构体第2张
5.结构体数组
结构体数组:数组元素为结构体数组
定义结构体数组
结构类型 数组名称[元素个数];
数组元素的类型 数组名称[元素个数];
#include <stdio.h>
//普通情况下结构体类型都是定义在函数的外部
struct Dog{
    char *name;
    int age;
};
void test()
{
    //    int nums[] = {1,2,3,4};
    //    结构体假设没有初始化。它里面都是垃圾值
    //  第一种方式:向定义结构体数组然后初始化
    struct Dog dogs[5];
    dogs[0] = (struct Dog){"旺財",1};
    dogs[1].age = 1;
    dogs[1].name = "大黄";   
    //  遍历结构体数组    
    for(int i = 0;i < 5;i++)
    {
        printf("age = %d,name = %s
",dogs[i].age,dogs[i].name);
    }
}
void test2()
{
    //  定义结构体数组的同一时候进行初始化
    //  假设没有显式初始化的结构体。那么这个结构体中全部成员都会被初始化为0
    struct Dog dogs[10] = {{"旺財",1},{"大黄",2},{"来福",3},{"小黑",4},{"小白",5}};
    //  计算数组的元素个数
    int len = sizeof(dogs) / sizeof(struct Dog);    
    for(int i = 0;i < len ;i++)
    {
        printf("age = %d,name = %s
",dogs[i].age,dogs[i].name);
    }
    
}
int main(int argc, const char * argv[]) {  
//    test();
    tset2();
    return 0;
}
ios学习之旅------玩转结构体第3张
6.结构体与指针
结构体指针:指向结构体的指针
指针所指向的数据类型 * 指针变量名称;
结构类型 * 指针变量名称;
#include <stdio.h>
struct Student{
    char *name;//姓名
    int no;//学号
    double score;//成绩
};
int main(int argc, const char * argv[]) {   
    struct Student stu = {"大木",60,59};    
//   定义结构体指针
    struct Student *sp1;
    sp1 = &stu;
//  定义的同一时候进行初始化
    struct Student *sp = &stu;
//  通过指针訪问结构体的成员的第一种方式
    (*sp).score = 60;    
//  另外一种方式(重点)
    sp->name = "小木";
    sp->no = 59;
    printf("name = %s,no = %d,score = %.2lf
",stu.name,stu.no,stu.score);
      
    return 0;
}
ios学习之旅------玩转结构体第4张
7.结构体嵌套
一个结构体内部能够有其它类型的结构体成员
结构体嵌套的注意点:
1、结构体不能够嵌套自己,不能有字节这样的类型的成员
2、结构体能够嵌套自己类型的指针
#include <stdio.h>
//定义了一个日期的结构体
struct Time{
    int hour; // HH
    int minute;//mm
    int second;//ss
};
struct Date{
    int year;
    int month;
    int day;
    struct Time time;
};
struct Employee{    
    int no;
    char name[20];
//  入职日期
//    int year;
//    int month;
//    int day;
    struct Date inDate;
//  生日
//    int birthyear;
//    int birthmonth;
//    int birthday;
    struct Date birthday;
//  离职日期
//    int goyear;
//    int gomonth;
//    int goday;
    struct Date outDate;
};
void test()
{
    struct Employee emp = {1,"大幕",{2014,10,14,{12,12,12}},{1990,10,14},{2014,11,14}};
    
    printf("no = %d,name = %s,入职日期 = %d-%d-%d %d:%d:%d
"
           ,emp.no,emp.name,emp.inDate.year,emp.inDate.month,emp.inDate.day,
           emp.inDate.time.hour,emp.inDate.time.minute,emp.inDate.time.second);
    }
struct Person{
    char *name;
//    struct Person son;
    struct Person *son;
};
/*
 1.某班有5个学生,三门课。分别编写3个函数实现下面要求:
 (1) 求各门课的平均分;
 (2) 找出有两门以上不及格的学生,并输出其学号和不及格课程的成绩。
 (3) 找出三门课平均成绩在85-90分的学生,并输出其学号和姓名
 */
int main(int argc, const char * argv[]) {   
    struct Person father = {"father"};   
    struct Person son = {"son"};    
    father.son = &son;    
    printf("son name = %s
",father.son->name);

    return 0;
}
8.枚举
枚举:一个一个列举出来
枚举作用:消除魔法数字
使用场景:当某个东西仅仅有那么几个取值时候就是用枚举
定义枚举格式
enum 枚举类型的名称{
元素,//逗号
...
};
注意点:
1、枚举类型定义中。全部元素都是整形常量
2、枚举类型的本质就是整形
#include <stdio.h>
//定义性别枚举类型
enum Sex{
     Man,
     Woman,
     Other
};

//int Man = 10;//枚举定义之后,后面不可定义与成员同样变量
void test()
{
    //  在代码中出现的这样的表示特殊含义数字,我们魔法数字
    //    int sex = 0;  
    enum Sex sex;
    printf("%d
",Man);
    int Man = 10;
    printf("%d
",Man);  
    //    sex = 1;// 这里不能把要给数字赋值给一个枚举类型的变量,这样枚举存在的意义就没有了
    //    Man = 1;
    
}
// 能够指定枚举中每个元素值
enum Season{
   Spring = 2,
   Summer,
   Autumn,
   Winter,
   SOther = 9
};
void PrintSeason(enum Season season)
{
    switch (season) {
        case Spring: //Case后面的值务必与枚举中成员一致,不要出现魔法数字
            printf("春季
");
            break;
        case Summer:
            printf("夏季
");
            break;
        case Autumn:
            printf("秋季
");
            break;
        case Winter:
            printf("冬季
");
            break;
        case SOther:
            printf("不是地球上季节
");
            break;
        default:            
            break;
    }
}
int main(int argc, const char * argv[]) {
    printf("%d,%d,%d
",Man,Woman,Other);
    printf("%d,%d,%d,%d
",Spring,Summer,Autumn,Winter);       
    enum Season season = Summer;    
    PrintSeason(season);
    
    return 0;
}
ios学习之旅------玩转结构体第5张
9. typedef:
给已有数据类型起别名
基本数据类型
int char float double
结构体
枚举
指针
1、普通变量的指针
2、结构体指针
3、函数指针
基本数据类型
定义格式:typedef 已有数据类型 别名;
#include <stdio.h>
void testBaseType()
{   
    typedef int  Int;   
    Int num = 10;   
    typedef Int Integer;    
    Integer a = 20;    
    printf("%d
",a);   
}
/*
    给结构体类型起别名 
 */
void testStruct()
{    
//  第一种方式:先定义结构体类型再给结构体类型起别名
    struct _Person{
        int age;
        char *name;
    };    
    typedef struct _Person Person;    
    Person p1 = {10,"小红"};
    printf("age = %d,name = %s
",p1.age,p1.name);   
// 另外一种方式,定义结构体类型的同一时候给结构体类型起别名       
    typedef struct _Dog{
        int age;
        char *name;
    } Dog;    
    Dog dog = {1,"大黄"};    
//  第三种方式:定义匿名结构体类型的同一时候给结构体起一个别名   
    typedef struct{
        int age;
        char * name;
    } Cat;    
    Cat cat = {1,"tom"};   
}
//给枚举起别名
void testEnum()
{
//  1、先定义枚举类型然后给枚举起别名   
    enum _Sex{
      Man,
      Woman,
      Other
    };   
    typedef enum _Sex Sex;    
    Sex sex = Man;
//  2、定义枚举类型的同一时候给枚举类型起一个别名   
   typedef enum _Season{
        Spring,
        Summer
    } Season;        
    Season season = Spring;    
//  3、定义匿名枚举类型同一时候给枚举起一个别名   
    typedef enum {
         Cong,
         Suan,
         Jiang
    } TiaoWei;    
    TiaoWei zuoLiao = Cong; 
}
//4、指针类型
//4.1 基本数据类型的指针
void testTypedefBasicPointer()
{
    typedef  int * IntPointerType;
    int a = 10;    
    IntPointerType p = &a;   
    *p = 20;   
    printf("%d
",a);    
}
//4.2 给结构体类型的指针起别名
void testTypedefStructPointer()
{
    typedef struct {
        char *name;
        int age;
    } Person;    
    typedef Person * PersonPointerType;    
    Person p = {"张三",10};    
    PersonPointerType pp = &p;        
    typedef struct _Cat{
        char *name;
        int age;    
    } Cat, * CatPointerType;    
    Cat cat = {"小猫",1};    
    CatPointerType catPointer = &cat;    
    printf("name = %s,age = %d
",catPointer->name,catPointer->age);    
}
//4.3 给枚举类型的指针起别名
void testTypedefEnumPointer()
{
//  先定义枚举类型
    enum _Sex{
         Man,
        Woman,
        Other
    };    
    typedef enum _Sex * SexPointer;   
    enum _Sex sex = Man;        
    SexPointer sexPointer = &sex;    
    *sexPointer = Woman;    
    printf("%d
",sex);    
}
//4.4 给函数指针起别名
int sum(int num1,int num2){    
    return num1 + num2;
}
int minus(int num1,int num2){    
    return num1 + num2;
}
//给函数指针起别名
//typedef 指针所指向的函数的返回值类型 (*函数指针类型别名)(所指向的函数的形參列表);
void testTypedefMethodPointer()
{   
//    int (*sumPointer)(int num1,int num2) = sum;
//    
//    int (*minusPointer)(int num1,int num2) = minus;   
    typedef  int (*MethodPointerType)(int num1,int num2);    
    MethodPointerType sumPointer = sum;    
    MethodPointerType minusPointer = minus;    
    int rs =  sumPointer(10,20);
    printf("rs = %d
",rs);    
}
//了解
void testTypedefArrayPointer()
{
    char names[][10] = {"xtf","zbz","wf"};   
    char (*arrayPoiner)[10];   
    arrayPoiner = names;    
    typedef char (*ArrayPointerType)[10];    
    ArrayPointerType pointer = names;   
    printf("%s
",pointer[0]);   
}
int main(int argc, const char * argv[]) {        
//
//    testBaseType();
//    testStruct();
    testTypedefBasicPointer();    
    testTypedefStructPointer();    
    testTypedefEnumPointer();    
    testTypedefMethodPointer();    
    testTypedefArrayPointer();
    return 0;
}
ios学习之旅------玩转结构体第6张

免责声明:文章转载自《ios学习之旅------玩转结构体》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇div包裹页面后多余部分没有显示,也没滚动条 overflow 属性设置进度条QProgressBar下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

C/C++文件输入输出操作——FILE*、fstream、windowsAPI

基于C的文件操作在ANSI C中,对文件的操作分为两种方式,即流式文件操作和I/O文件操作,下面就分别介绍之。 一、流式文件操作这种方式的文件操作有一个重要的结构FILE,FILE在头文件stdio.h中定义如下: typedef struct {int level;unsigned flags;char fd;unsigned char hold;int...

JS-为金额添加千分位逗号分割符

前言:这个功能在前端页面中使用的还是比较多的,正好我们的项目中也有使用此功能,不过YY同学写的代码不像个方法的样子,一个入口中间又插了几道子,所             以,我写了下面这个方法,经过测试,适用性还是蛮好的,留在这里以备后用! <!DOCTYPE html> <html> <head> <...

c++ 关于char *的类库函数

转自:c++ 关于char *的类库函数 一,拷贝:   char stpcpy(char *dest,const char *src) 将字符串src复制到dest   char strncpy(char *dest,const char *src,size_t maxlen) 复制src中的前maxlen个字符到dest中   char strnse...

GDB调试教程

简介   GDB(GNU debugger)是GNU开源组织发布的一个强大的UNIX下的程序调试工具。可以使用它通过命令行的方式调试程序。它使你能在程序运行时观察程序的内部结构和内存的使用情况。你也可以使用它分析程序崩溃前的发生了什么,从而找出程序崩溃的原因。相对于windows下的图形界面的VC等调试工具,它提供了更强大的功能。如果想在Windows下使...

ffmpeg 使用 gdb 调试相关技巧

本文说明了,在ffmpeg二次开发或调用库的过程,如何借助于ffmpeg源码进行调试。 注:ffmpeg版本是4.0。 1. 编写代码 编写将pcm数据转换为mp2的代码 pcm_to_mp2.c #include <libavformat/avformat.h> #include <libavcodec/avcodec.h> #i...

字符串右移

编写一个函数,要求输入一个字符串和要移动的位数n,使得该字符串能向右移动n位,输出移动后的字符串。例如:tomloveslily移动2位得lytomlovesli。 思路:把字符串变成两部分,交换位置,实际操作先把后n个字符保存起来,将strlen-n个字符往后移动n个位置,最后把n个字符放在前面(C语言) void right_move(char* st...