zoukankan      html  css  js  c++  java
  • C Primer Plus--结构和其他数据类型(2)

    C Primer Plus--结构和其他数据类型(2)

    枚举类型 enumerated type

    枚举是用来代表整数常量的符号,枚举类型的声明与struct声明类似。枚举常量都是int型的。枚举声明的花括号内枚举了该类型变量可能有的值。枚举是为了增强程序的可读性。

    enum vehicle {bicycle,car,plane,train,ship};
    

    上面说了枚举类型就是int类型的常量,那么凡是可以使用int的地方都可以使用枚举常量。

    枚举默认值

    枚举列表中的默认值被指定为整数值0、1、2等等。如上面枚举声明中:
    bicyclecarplanetrainship的值依次为0 1 2 3 4

    为枚举指定值

        enum levels {low = 20, medium = 50, high = 80, perfect = 100};
        enum phones {ios, windowsPhone = 60, blackberry = 80, android};
        //ios = 0; android = 81
    

    在C中,允许对枚举类型的变量使用自增(++)或自减(--)符号,但是在C++中不允许,为了使得程序兼容,应该一开就将变量声明为int型。

    enum vehicle {bicycle,car,plane,train,ship};
        enum vehicle trans;
        //在C++中要声明为
        //int trans;
        //trans此时的值不确定,需要赋值
        for (trans = bicycle;  trans <= ship  ; trans++) {
            printf("%d
    ",trans);
        }
    

    命名空间 namespace

    在C中,变量名和标记名(结构标记、联合标记、枚举标记)不在同一个命名空间中,因此二者可以同名,但在C++中不可以。

    struct car {
            char brand[30];
            int litre;
        };
        int car = 0;
        //C中不冲突
    

    typedef关键字

    typedef工具是一种高级数据特性,他使您能够为某一类型创建您自己的名字。在这个方面,它和#define相似,但是它们具有三个不同之处:

    1. #define不同,typedef给出的符号名称仅限于对类型,而不是对值
    2. typedef的解释由编译器而不是预处理器执行
    3. 虽然它的的范围有限,但在其受限范围内,typedef#define更灵活

    这里就告诉我们typedef并不创建新的数据类型,只是创建了易于使用的标签别名。
    例:顶一个一个数据类型别名BYTE,它只占一个字节,可以先定义一个char变量BYTE,然后在前面加上typedef即可。

    typedef unsigned cahr BYTE;
    
    BYTE x;//定义一个x
    BYTE Y[10];//定义一个数组容纳十个BYTE
    BYTE * z;//定义一个指向BYTE的指针
    

    总之,#define只是由预处理器对文件里的字符进行替换,而typedef则新建了一种数据类型的代替。

    typedef char * STRING;//STRING成了char指针的别名
    STRING a,b;//声明两个char指针a,b
    
    //若是用define来试一试
    #define STRING char *;
    
    STRING a , b;//这里被预处理器替换,成了char * a , b;两个就不都是指针了,只有a是,b成了字符。
    
    typedef struct {
    	float real;
        float imag;
    } COMPLEX; //将这个struct起个别名COMPLEX
    
    COMPLEX foo = { 1.0 ,1};//一个复数
    

    复杂的typedef

    typedef char (* FRPTC())[5];
    

    这里FPRTC返回的是一个指向含有5个元素的char数组的指针。

    * () []修饰符

    这三者优先级有低到高:* < () = [],而且他们与变量名的结合是从左到右的。

    int foo[12][24];//一个12x24的int二维数组
    int * p;//一个指向int的指针
    int ** ptr;//一个指向int的指针的指针
    char * strings[5];//一个数组,共5个元素,每个元素是一个指向char的指针
    int (* pointer) [5];//一个指向int[5]数组的指针
    int * bar[12][24];//一个12x24的二维数组,每个元素是一个指向int的指针
    int (* pp) [12][24];//一个指向12x24二维数组的指针
    int (* ppp[3]) [4];//一个数组,共三个元素,每个元素是一个指向int[4]数组的指针
    
    char * func();//一个返回值为指向char的指针的函数
    char (* funcp) func1();//一个指针,该指针指向一个返回类型为char的函数
    char (* funcps[3]) func2();//一个数组,共3个元素,每个元素是一个指针,指针指向一个返回值为char的函数
    

    typedef与这三个运算符结合

    typedef int array5[5];
    typedef array5 * p_to_array5;
    typedef p_to_array5 arrayp[10];
    
    array5 foo;//foo是一个int[5]数组
    p_to_array5 p;//p是一个指向int[5]数组的指针
    arrayp array;//array是一个数组,共10个元素,每个元素是一个p_to_array5指针
    

    函数与指针

    指针可以指向函数。指向函数的指针保存着函数代码起始处的地址。当声明一个函数指针时,必须声明它指向的函数类型,即指定函数的返回类型以及函数的参量类型。
    void eat(char * food);声明了一个形式参量为字符指针的的函数,要声明一个指向这样类型函数的指针,需要这样做:
    void (* pointer) (char *);

    声明一个指向特定函数类型的指针,首先声明一个该类型的函数,然后用(* pf)形式的表达式替换函数名称,pf就成为了可指向那种类型函数的指针了。

    声明了指针之后,还需对指针进行赋值,赋值给指针的函数必须拥有与指针声明中一致的形参和返回值。

    函数指针作为参数

    有了函数的指针,可以利用指针来访问函数:

    • 通过 (*pf) (参数)的方式访问函数
    • 通过 pf (参数)的方式访问函数
    #include <stdio.h>
    
    void toUpper(char *);
    void toLower(char *);
    void foo( void (*pf)(char *),char * string);
    int main() {
        void (*pf) (char *);
        
        char test[] = "I love you";
        
        pf = toUpper;
        
        (* pf)(test);//1
        
        pf = toLower;
        
        pf(test);//2
        
        foo(pf,test);//foo函数调用
    }
    /*
     * foo接受一个函数指针与char指针
     */
    void foo( void (*pf)(char *),char * string){
        pf(string);
        puts(string);
    }
    
    世事茫茫,光阴何其有限!
  • 相关阅读:
    MacOS下保护浏览器主页和默认搜索
    Tokyo Tyrant(TTServer)系列(一)-介绍和安装
    四:二叉树的镜像递归非递归求解
    Android 异常 android.os.NetworkOnMainThreadException
    Android开发学习之路--传感器之初体验
    Xcode真机调试失败:The identity used to sign the executable is no longer valid
    hdu 3068 最长回文(manacher&amp;最长回文子串)
    bzoj1030【JSOI2007】文本生成器
    HDU2082母函数模板题
    Oracle数据库远程连接配置教程
  • 原文地址:https://www.cnblogs.com/bobliao/p/9932197.html
Copyright © 2011-2022 走看看