C语言中typedef,条件编译,结构体的说明

typedef (类型别名)

typedef关键字,可以给类型取别名(alias),语法:

typedef 原类型名 新类型名

使用typedef去给函数指针类型取别名,语法略有不同。

typedef void(*PFNTYPE1)(int sig);
typedef void(*PFNTYPE2)(int sig);
PFNTYPE2 mysignal(int sig, PFNTYPE1 func);

善于使用typdef,可以增强代码可读性。
也可以减少重构中修改代码的量。

条件编译

条件编译属于一种预处理命令,它可以根据宏是否定义,来决定某段代码是否要编译。
假设一个场景,我们写的程序,可能在windows和Linux上编译,在Linux上,因为种种原因,不能得到全面的支持。
我们希望按照条件编译,只要一份源码,可以自动的编译出windows和linux对应的版本。

#ifdef ARCH_WIN
/*代码段1*/
int main(int argc, char* argv[])
{
    
    printf("windows,    OK");

    return 0;

}
#else
int main(int argc, char* argv[])
{

    printf("Linux,       OK");

    return 0;

}
#endif

以上代码:如果定义了ARCH_WIN这个宏,那么编译代码段1,否则,编译代码段2.
条件编译在工程中的应用非常多。比如我们所谓的Debug版本,和Release版本其实就是条件编译控制的。
我们不仅可以通过define指令去设置宏,还可以通过VS设置宏:

vs设置宏的原理,是直接通过编译器的编译选项设置。所以对于所有的cpp文件全部生效。

条件编译在头文件包含中的应用

赤裸裸的头文件包含,容易产生重复包含的问题。
有些头文件被重复包含了。轻则降低效率,重则编译出错。
我们可以使用条件编译,解决这个问题。
解决方案,是按照以下模板去写头文件:

#ifndef 非常特殊的宏
#define 非常特殊的宏
你的头文件的内容……
#endif

这种套路,被更新的指令

#pragma once

所取代。

结构体

现在,我们开始学习非基本数据类型。非基本数据类型,顾名思义,不是编译器天生
直到的类型。是程序员发明的类型:

  • 程序员先发明新类型(非基本数据类型)
  • 然后再用新类型,去定义新变量
    我们即将学习的结构体(struct),是C语言中最重要的非基本数据类型。
    它的发明目的,是为了复合信息。
    举例,如果我们要写一个学生管理系统,那么当然要保存学生的信息,比如:
  • 姓名, char[12]
  • 性别, int
  • 学号, int
    如果没有到结构体语句的话
    记录一,两个学生的信息还好,当需要记录的学生越来越多时,容易出错。因为姓名、ID、学号没有被很好
    的封装起来。
    结构体,就是为了解决封装问题而诞生的语法。

    定义结构体类型

struct tagStudent
{
    char szname[8];
    int nGender;
    int nStuId;
};

使用结构体定义新的结构体变量

纯正c89语法:

struct tagstudent stu1;

之后的C++以及较新的C编译器,都允许省略struct来定义结构体变量

tagstudent stu1;

结构体成员的引用与赋值

从结构体类型的定义就可以看出,结构体中封装了多种变量。
我们可以通过"."运算符,去引用到结构体内部的变量(结构体成员)。

struct tagStudent
{
    char szName[8];
    int nGender;
    int nStuId;
};

int main(int argc, char* argv[])
{

    struct tagStudent stu1;

    strcpy(stu1.szName, "刘x");
    stu1.nGender = 1;
    stu1.nStuId = 20172519;

    return 0;

}

结构体指针及其引用

如果需要将结构体作为参数传递
强烈不推荐使用值传递的方法传递结构体。
而强烈推荐使用指针传递结构体。
因为以值传递的方式传递结构体,结构体会整体被拷贝到栈帧并随函数返回释放。这常常意味着较大的消耗资源。
甚至可能造成栈帧的崩溃

struct tagStudent
{
    char szName[2000000];
    int nGender;
    int nStuId;
};

void ShowStu(tagStudent stu)
{
    printf("姓名:%s, 性别:%d, 学号:%d",
        stu.szName,
        stu.nGender,
        stu.nStuId);
}

struct tagStudent g_stu1;

int main(int argc, char* argv[])
{

    strcpy(g_stu1.szName, "刘x");
    g_stu1.nGender = 1;
    g_stu1.nStuId = 20172519;

    ShowStu(g_stu1);

    return 0;

}

综上所述,我们推荐使用地址的方式(结构体指针)传递结构体。

  • 结构体指针的定义:
struct tagStudent
{
    char szName[200000];
    int nGender;
    int nStuId;
};

void ShowStu(tagStudent* pstu)
{
    printf("姓名:%s, 性别:%d, 学号:%d",
        pstu->szName,
        pstu->nGender,
        pstu->nStuId);

       pstu->nGender = 0;
}

struct tagStudent g_stu1;

int main(int argc, char* argv[])
{

    strcpy(g_stu1.szName, "XX");
    g_stu1.nGender = 1;
    g_stu1.nStuId = 1233456;

    ShowStu(&g_stu1);

    return 0;

}

猜你喜欢

转载自www.cnblogs.com/BuFanJieDa/p/12070308.html