c语言拾遗

枚举常量:

枚举是一个常量整型值的列表的列表,例如 enum boolean{NO,YES};

在没有显示说明的情况下,enum类型中第一个枚举名的值为0,第二个为1,以此类推。

如果只指定了部分枚举名的值,那么未指定的枚举名的值将依着最后一个指定值递增,步长为1。

    enum days {one = 1, two=3, three};
    enum days day = one; //或enum{one=1, two=3, three}day;
    printf("%d %d %d",day, two, three);

enum的声明的形式和struct很相似。
 

结构:
1.即使成员列表完全相同,两个结构也会被编译器当作是不同的类型。

比如:

struct {
    int a;
    char b;
    float c;
} x;

struct {
    int a;
    char b;
    float c;
} y[20], *z;

z = &x; //这条语句是非法的。

2.typedef

typedef struct {
    int a;
    SELF_REF3 *b;
    int c;
} SELF_REF3;
这个声明将会失败,因为在结构内部这个结构尚未被定义。
解决方案:
typedef struct SELF_REF3_TAG {
    int a;
    struct SELF_REF3_TAG *b;
    int c;
} SELF_REF3;
或者是避免使用typedef

3.不完整声明

当两个结构互相依赖时,可以使用一个不完整声明来完成
struct B;

struct A{
    struct B *partner;
};

struct B{
    struct A *partner;
};

4.结构的初始化

结构的初始化由花括号内部被逗号分割的一系列值给出,赋值顺序为结构成员的列表顺序,当初始列表的值不够时,剩余的结构成员将使用缺省值初始化。

struct INIT_EX{
        int a;
        short b[10];
        char c;
    }x = {
       10,
       {1,2,3,4,5},
       6
    };
printf("%d", x.c);  得到6

5.内存对齐

sizeof会按照内存对齐后的大小给出结构体的大小,比如
struct ALIGN{
    char a;
    int b;
    char c;
};
sizeof(struct ALIGN)会得到12。
如果使用宏offsetof(ALIGN, b),可以得到4,即指定结构成员的偏移量。

6.位段

位段的初始化与使用和结构类似,但不应在嵌套使用位段和结构的时候这样初始化)除了要求类型必须是整型,以及冒号后跟的是bit的个数。
struct bit_file{
        unsigned a:7;
        signed b:6;
        int c:19;
        unsigned d:32;
    }x = {2};

printf("%d", sizeof(x));

7.联合

struct VARIABLE{
    enum {INT, FLOAT, STRING} type;
    union {
          int int_value;
          float float_value;
          char *string_char;
    } value ;
}v;
v.value.int_value = 8;
printf("%d", v.value.int_value);
}
联合的所有成员引用的是内存中的相同位置,联合初始化的方式和位段一样,但是必须使用第一个成员的类型来对联合初始化。

数组:

1.字符指针

char message1[] = "hello" 将会创造一个长度为6的指针数组
char *message2 = "hello" 创造一个指针

sizeof(message1)得到包括''的字符串长度
strlen(message1)得到不包括'0'的字符串长度
sizeof(*message1)得到1

sizeof(message2)得到4 (地址为32位的)
sizeof(*message2)得到1 

 2.存储顺序

多维数组的存储数据按照最右边的下标先变化的原则。

3.多维数组

matrix[3][10]可以看作是一个一维数组,包含三个元素,每个元素又是包含十个元素的数组。

matrix[1][5]相当于*( *( matrix + 1 ) + 5)

类型转换:
当不存在unsigned类型的操作数时,两个操作数中小者总会转换为大者(float和double除外,不会自动转换)。

赋值时:右边的类型转换为左边的类型

当把long/int转换为char时,超出的高位将被丢弃,所以对于

int i;

char c;

i = c;

c = i;

不会改变c的值。

当把float转换为int类型时,会舍去小数位,把double转换为float时的依赖于具体实现。

当不存在函数原型时,char和short会被提升为int,float会被提升为double。

整型提升:

在一个表达式中如果信息不会被丢失,那么char、short、枚举、位字段都会被提升为int,如果int不足以保存,则会转为unsigned int。

原文地址:https://www.cnblogs.com/autoria/p/5890889.html