zoukankan      html  css  js  c++  java
  • C语言笔记整理(3)

    结构, union, enum, typedef

     

    struct structname

    {

             int i; //除了static,其余不可在定义struct时赋值.

             char buf[32];

             double f;

    } ;  //定义struct structname

    structname a; //定义变量 a

    structname a = {0, “123”, 1.2}; //初始化

    a.i = 10;

    支持初始化指定项目(C99)

    structname a = {.i = 1};

     

    不同平台的寻址方式不同,有的可能同偶地址开始读取, 编译器会将struct对齐, 以成员函数size的最大位对齐.

    对于

    struct structname

    {

             int i;

             char buf[32];

    } a; //sizeof(a) = 36; 4位对齐

     

    struct structname

    {

             double f;

    } b; //sizeof(b) = 8;  8位对齐

     

    struct structname

    {

             int i;

             char buf[32];

             double f;

    } c; //sizeof(c) = 48; 8位对齐

     

    #progma pack (2) 可以指定对齐位数, 此时最终对齐值为自身对齐值和指定对齐值中的较低的那个.

    对于空结构体,size == 1因为必须保证结构体的每一个实例在内存中都有独一无二的地址.
    结构体的静态成员不对结构体的大小产生影响,因为静态变量的存储位置与结构体的实例地址无关.

     

    struct structname

    {

    } a, *pstr; //定义struct和变量 a

     

    和数组不同,一个结构的名字不是该结构的地址,必须使用&运算符.

    memset(&a, 0, sizeof(structname));

     

    struct 允许赋值,数组不可.

    structname b;

    a = b;

     

    伸缩型数组成员(C99)

    struct structname

    {

             int i;

             double arr[]; //未分配任何内存,必须至少有一个其他成员,必须是最后//的一个数组成员.

    } *p;

    p = (structname *)malloc(sizeof(structname) + sizeof(double) * 5);

     

    union

    在同一存储空间里(但不同时)存储不同类型数据的数据类型,同一时间只能存储一个成员值,

    union unionname

    {

             int i;

             double f;

             char c

    } a;

    a.i = 10;

     

    支持初始化指定项目(C99)

    union a = {.i = 1};

    union允许赋值,数组不可.

    union b;

    a = b;

     

    enum

    enum enumname

    {

             one, //0

             two = 3, //注意,以逗号隔开

             three //4,注意没有逗号

    } a;

    a  = two;

     

    typedef

    typedef struct structname

    {

             int i;

    }nickname;

    nickname a;

    typedef char (* func())[5]; //typedef函数类型,无参数,返回值为指向char []的指针.

    typedef char [5] *(* func)(); //typedef函数指针,无参数,返回值为指向char []的指针.

     

    void func(char buf[]);

    int main(int argc, _TCHAR* argv[])

    {

             typedef void (* pfunc)(char buf[]);

             typedef void fun(char buf[]);

             pfunc  p = func;

             fun *a= func;

             return 0;

    }

    void func(char buf[])

    {

    }

     

    C预处理器和C

     

    编译器用一个空格字符代替每一个注释

    int/*===*/a; //等同于 int a;

    系统会删除反斜线和换行符的组合,但是编译其会有缩进,所以要注意喔.

     

    预处理指令

    #define

    #define X 1

    #define fun(n) n*n //func(4+2);最后结果为144+2*4+2

    预处理器不进行计算,只是进行文字替换操作,实际计算过程是在编译阶段.

    #运算符

    #define PRINT(n) printf(#n" = %d\n", n); //#n可以吧参数转换为相应的字符串

    #define PRINT1(n) printf("n = %d\n", n); //#n可以吧参数转换为相应的字符串

    int main(int argc, _TCHAR* argv[])

    {

             int x = 2;

    PRINT1(2); //n = 2

             PRINT(x); //x = 2

             PRINT(2); //2 = 2

             return 0;

    }

     

    ##运算符

    #define X(n) x##n

    #define PRINT(n) printf("x"#n"=%d\n", x##n);

    int main(int argc, _TCHAR* argv[])

    {

             int X(1) = 2; //等同于x1 = 2;

             PRINT(1); //x1 = 2

             return 0;

    }

     

    可变宏 __VA_ATGS__

    #define X(n) x##n

    #define PR(X,...) printf("hi, "#X": " _ _VA_ATGS_ _) //…必须放在最后

    int main(int argc, _TCHAR* argv[])

    {

             int X(1) = 2;

             PR(1, "x1 = %d", x1); //输出:hi, 1: x1 = 2

             return 0;

    }

     

    #define MYC

    #ifdef MYC //或者 #ifndef MYC

    ...

    #else

    ...

    #endif

     

    #define MYC

    #if defined(MYC) //同上面的代码意义相同,#if后面跟常量整数表达式,如果表达式为非0,则表达式为真

    ...

    #elif defined(YOURC)

    ...

    #else

    ...

    #endif

     

    #pragma来启动修改对编译器的设置

    #pragma C99 on

     

    内联函数inline,编译器没有预留给它的单独带麻快,所以无法获得内联函数的地址(如果获得地址,编译器会产生非内联函数),编译时候优化内联函数,所以内联函数的定义和调用必须在同一文件中,故在头文件中定义内联函数,具有内部链接,所以编译不会产生问题.

     

    int atexit(void (* pfunc)(void));

    注册函数,在exit执行时,注册函数会执行.函数按先进后出顺序执行.

     

    可变参数:stdarg.h

    int i = 2;

    char c = 'A';

    char buf[32] = "abc";

    func("%d%c%s", i, c, buf);

     

    void func(char *format, ...); //…必须为最后一个参数

    va_list ap//存放参数

    va_start(ap, format); //ap初始化为参数列表,参数是从开始的.

    int i = va_arg(ap, int); //n次调用va_arg,返回参数列表的第n个参数.va_arg不提供退回之前参数的方法,可用va_copy(apcopy, ap)先保存参数列表.

    va_end(ap); //释放动态分配的用于存放参数的内存

  • 相关阅读:
    远程监控JVM
    性能测试的思考
    吴恩达《机器学习》课程总结(11)机器学习系统的设计
    吴恩达《机器学习》课程总结(10)应用机器学习的建议
    吴恩达《机器学习》课程总结(9)神经网络的学习
    吴恩达《机器学习》课程总结(8)神经网络表述
    吴恩达《机器学习》课程总结(7)正则化
    吴恩达《机器学习》课程总结(6)逻辑回归
    吴恩达《机器学习》课程总结(5)Octave教程
    吴恩达《机器学习》课程总结(4)多变量线性回归
  • 原文地址:https://www.cnblogs.com/zengyou/p/2195571.html
Copyright © 2011-2022 走看看