42 C 语言 typedef:为基本数据类型、数组、指针、结构体、共用体起别名

目录

1 typedef 介绍

2 为某个基本类型起别名

2.1 为 int 类型起别名 Integer

2.2 为 unsigned char 类型起别名 Byte

2.3 为基本类型一次起多个别名

3 为结构体、共用体起别名

3.1 为结构体起别名

3.1.1 分开定义结构体和别名

3.1.2 与结构体定义一起使用 typedef

3.1.3 为匿名结构体起别名

3.2 为共用体起别名

4 为指针起别名

4.1 为 int* 起别名 intptr

4.2 为 char* 起别名 String

5 为数组起别名

5.1 为数组类型起别名

5.2 为数组指针取别名

6 综合案例


1 typedef 介绍

        C 语言允许为一个数据类型起一个新的别名,就像给人起“绰号”一样。起别名的目的不是为了提高程序运行效率,而是为了编码方便。例如,有一个结构体的名字是 Student,定义一个结构体变量 stu1,代码如下:

struct Student stu1;

        struct 看起来多余,但不写又会报错。如果为 struct Student 起一个别名 Student,书写起来就简单了:

typedef struct Student Student;
Student stu1;

        这种写法更加简练,意义也非常明确,不论是在标准头文件中还是在以后的编程实践中,都会大量使用这种别名。


2 为某个基本类型起别名

        typedef 命令可以用来为某个类型起别名。

typedef 类型名 别名;

        习惯上,常把用 typedef 声明的类型名的第 1 个字母用大写表示,以便与系统提供的标准类型标识符相区别。

2.1 为 int 类型起别名 Integer

#include <stdio.h>

// 为 int 类型起别名 Integer
typedef int Integer;

int main()
{
    // 声明并初始化两个 Integer 类型的变量
    Integer a, b;
    a = 1;
    b = 2;

    // 打印变量的值
    printf("a: %d\n", a); // a: 1
    printf("b: %d\n", b); // b: 2

    return 0;
}

2.2 为 unsigned char 类型起别名 Byte

#include <stdio.h>

// 为类型 unsigned char 起别名 Byte
typedef unsigned char Byte;

int main()
{
    // 声明并初始化一个 Byte 类型的变量
    Byte c = 'z';

    // 打印变量的值
    printf("c: %c\n", c);                // 以字符形式打印 c: z
    printf("ASCII value of c: %u\n", c); // 以无符号整数形式打印 ASCII 值 ASCII value of c: 122

    return 0;
}

2.3 为基本类型一次起多个别名

#include <stdio.h>

// 为 int 类型一次性起三个别名
typedef int chocolate, doughnut, mushroom;

// 为其他基本数据类型起别名
typedef unsigned char Byte;
typedef float Real;
typedef double Double;

int main()
{
    // 声明并初始化 int 类型的别名变量
    chocolate choco = 10;
    doughnut donut = 20;
    mushroom mush = 30;

    // 打印变量的值
    printf("chocolate: %d\n", choco); // 10
    printf("doughnut: %d\n", donut);  // 20
    printf("mushroom: %d\n", mush);   // 30

    // 声明并初始化其他基本数据类型的别名变量
    Byte b = 'A';
    Real r = 3.14f;
    Double d = 2.71828;

    // 打印变量的值
    printf("Byte: %c\n", b);    // A
    printf("Real: %f\n", r);    // 3.140000
    printf("Double: %lf\n", d); // 2.718280

    return 0;
}

3 为结构体、共用体起别名

        typedef 命令可以为 struct、union 等命令定义的复杂数据结构创建别名,从而便于引用。

3.1 为结构体起别名

3.1.1 分开定义结构体和别名

#include <stdio.h>

// 定义结构体 Treenode
struct Treenode
{
    char *name; // 树的名称
    int legs;   // 树的腿数
    int speed;  // 树的速度
};

// 为 struct Treenode 起别名 Tree
typedef struct Treenode Tree;

int main()
{
    // 声明一个 Tree 类型的变量
    Tree t;

    // 初始化结构体变量的属性
    t.name = "Oak"; // 名称
    t.legs = 0;     // 树没有腿
    t.speed = 0;    // 树不能移动

    // 打印结构体变量的属性
    printf("Name: %s\n", t.name);   // Oak
    printf("Legs: %d\n", t.legs);   // 0
    printf("Speed: %d\n", t.speed); // 0

    return 0;
}

3.1.2 与结构体定义一起使用 typedef

#include <stdio.h>

// 定义结构体 Treenode 并同时为它起别名 Tree
typedef struct Treenode
{
    char *name; // 树的名称
    int legs;   // 树的腿数
    int speed;  // 树的速度
} Tree;

int main()
{
    // 声明一个 Tree 类型的变量
    Tree t;

    // 初始化结构体变量的属性
    t.name = "Oak"; // 名称
    t.legs = 0;     // 树没有腿
    t.speed = 0;    // 树不能移动

    // 打印结构体变量的属性
    printf("Name: %s\n", t.name);   // Oak
    printf("Legs: %d\n", t.legs);   // 0
    printf("Speed: %d\n", t.speed); // 0

    return 0;
}

3.1.3 为匿名结构体起别名

#include <stdio.h>

// 为一个匿名结构体起别名 Tree
typedef struct
{
    char *name; // 树的名称
    int legs;   // 树的腿数
    int speed;  // 树的速度
} Tree;

int main()
{
    // 声明一个 Tree 类型的变量
    Tree t;

    // 初始化结构体变量的属性
    t.name = "Oak"; // 名称
    t.legs = 0;     // 树没有腿
    t.speed = 0;    // 树不能移动

    // 打印结构体变量的属性
    printf("Name: %s\n", t.name);   // Oak
    printf("Legs: %d\n", t.legs);   // 0
    printf("Speed: %d\n", t.speed); // 0

    return 0;
}

3.2 为共用体起别名

#include <stdio.h>

// 为 union 起别名 Quantity
typedef union
{
    short count;  // 计数
    float weight; // 重量
    float volume; // 体积
} Quantity;

int main()
{
    // 声明一个 Quantity 类型的变量
    Quantity q;

    // 初始化共用体变量的属性
    q.count = 10; // 设置计数

    // 打印共用体变量的计数值
    printf("Count: %hd\n", q.count); // 10

    // 重新设置共用体变量的属性
    q.weight = 5.5; // 设置重量

    // 打印共用体变量的重量值
    printf("Weight: %.2f\n", q.weight); // 5.50

    // 重新设置共用体变量的属性
    q.volume = 2.718; // 设置体积

    // 打印共用体变量的体积值
    printf("Volume: %.3f\n", q.volume); // 2.718

    // 注意:由于共用体共享同一块内存,最后一次赋值会覆盖之前的值
    printf("Count (after setting volume): %hd\n", q.count);    // -3146(数据溢出与补码存储原理)
    printf("Weight (after setting volume): %.3f\n", q.weight); // 2.718

    return 0;
}

4 为指针起别名

        typedef 可以为指针类型起别名,使代码更加简洁和易读。然而,使用指针别名时要小心,因为这可能会使代码的可读性降低,特别是当变量类型不明显时。

4.1 为 int* 起别名 intptr

#include <stdio.h>

// 为 int* 类型起别名 intptr
typedef int *intptr;

int main()
{
    // 声明一个 int 类型的变量
    int a = 10;

    // 声明一个 intptr 类型的变量,并初始化为 a 的地址
    intptr x = &a;

    // 打印变量 a 的值
    printf("Value of a: %d\n", a); // 10

    // 打印变量 x 的值(即 a 的地址)
    printf("Address of a (stored in x): %p\n", (void *)x);

    // 通过指针 x 修改变量 a 的值
    *x = 20;

    // 再次打印变量 a 的值
    printf("New value of a: %d\n", a); // 20

    return 0;
}

        intptr 是 int* 的别名。虽然这样写可以使代码更简洁,但需要注意 x 是一个指针类型,以免引起混淆。

4.2 为 char* 起别名 String

#include <stdio.h>

// 为 char* 类型起别名 String
typedef char *String;

int main()
{
    // 之前的写法
    char *str1 = "hello";

    // 现在的写法
    String str2 = "hello";

    // 打印字符串
    printf("str1: %s\n", str1); // str1: hello
    printf("str2: %s\n", str2); // str2: hello

    return 0;
}

        String 是 char* 的别名。使用 String 声明变量时,可以更容易地识别该变量是一个字符串指针。


5 为数组起别名

        typedef 也可以用来为数组类型起别名,使代码更加简洁和易读。

5.1 为数组类型起别名

#include <stdio.h>

// 为 int[5] 类型起别名 fiveInts
typedef int fiveInts[5];

// 为 int[100] 类型起别名 Num
typedef int Num[100];

// 为 double[10] 类型起别名 DoubleArray
typedef double DoubleArray[10];

// 为 char[20] 类型起别名 CharArray
typedef char CharArray[20];

int main()
{
    // 声明并初始化一个 fiveInts 类型的数组
    fiveInts x = {11, 22, 33, 44, 55};
    // 打印 fiveInts 数组的内容

    printf("fiveInts array x:\n");
    for (int i = 0; i < 5; i++)
    {
        printf("%d ", x[i]); // 11 22 33 44 55
    }
    printf("\n");

    // 声明一个 Num 类型的数组
    Num a;

    // 初始化 Num 数组
    for (int i = 0; i < 100; i++)
    {
        a[i] = i;
    }

    // 打印 Num 数组的部分内容
    printf("Num array a (first 10 elements):\n");
    for (int i = 0; i < 10; i++)
    {
        printf("%d ", a[i]); // 0 1 2 3 4 5 6 7 8 9
    }
    printf("\n");

    // 声明并初始化一个 DoubleArray 类型的数组
    DoubleArray db = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.0};

    // 打印 DoubleArray 数组的内容
    printf("DoubleArray array db:\n");
    for (int i = 0; i < 10; i++)
    {
        printf("%.2f ", db[i]); // 1.10 2.20 3.30 4.40 5.50 6.60 7.70 8.80 9.90 10.00
    }
    printf("\n");

    // 声明并初始化一个 CharArray 类型的数组
    CharArray ch = "Hello, World!";

    // 打印 CharArray 数组的内容
    printf("CharArray array ch: %s\n", ch); // Hello, World!

    return 0;
}

5.2 为数组指针取别名

#include <stdio.h>

// 为 int (*)[5] 取别名为 IntArrayPointer
typedef int (*IntArrayPointer)[5];

// 为 double (*)[10] 取别名为 DoubleArrayPointer
typedef double (*DoubleArrayPointer)[10];

// 为 char (*)[20] 取别名为 CharArrayPointer
typedef char (*CharArrayPointer)[20];

int main()
{
    // 定义 int 类型的数组
    int arr[5] = {1, 2, 3, 4, 5};

    // 使用别名定义数组指针
    IntArrayPointer ptr = &arr;

    // 打印 int 数组的内容
    printf("int array arr:\n");
    for (int i = 0; i < 5; i++)
    {
        printf("%d ", (*ptr)[i]); // 1 2 3 4 5
    }
    printf("\n");

    // 定义 double 类型的数组
    double dbl_arr[10] = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.0};

    // 使用别名定义数组指针
    DoubleArrayPointer dbl_ptr = &dbl_arr;

    // 打印 double 数组的内容
    printf("double array dbl_arr:\n");
    for (int i = 0; i < 10; i++)
    {
        printf("%.1f ", (*dbl_ptr)[i]); // 1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 9.9 10.0
    }
    printf("\n");

    // 定义 char 类型的数组
    char char_arr[20] = "Hello, World!";

    // 使用别名定义数组指针
    CharArrayPointer char_ptr = &char_arr;

    // 打印 char 数组的内容
    printf("char array char_arr: %s\n", *char_ptr); // Hello, World!

    return 0;
}

6 综合案例

#include <stdio.h>
#include <string.h>

// 为基本数据类型起别名
typedef int Integer;
typedef float Real;
typedef char Character;
typedef char *String;

// 为结构体起别名
typedef struct
{
    char name[50];
    int age;
} Person;

// 为共用体起别名
typedef union
{
    int count;
    float weight;
    float volume;
} Quantity;

// 为指针类型起别名
typedef int *IntPtr;
typedef char *CharPtr;

// 为数组类型起别名
typedef int FiveInts[5];
typedef double TenDoubles[10];
typedef char TwentyChars[20];

// 为数组指针类型起别名
typedef int (*IntArrayPointer)[5];
typedef double (*DoubleArrayPointer)[10];
typedef char (*CharArrayPointer)[20];

int main()
{
    // 基本数据类型
    Integer i = 10;
    Real r = 3.14;
    Character c = 'A';
    String s = "Hello, World!";

    // 结构体
    Person p = {"Alice", 30};

    // 共用体
    Quantity q;
    q.weight = 5.5;

    // 指针类型
    IntPtr iptr = &i;
    CharPtr cptr = &c;

    // 数组类型
    FiveInts fi = {1, 2, 3, 4, 5};
    TenDoubles td = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.0};
    TwentyChars tc = "test string";

    // 数组指针类型
    int arr[5] = {10, 20, 30, 40, 50};
    IntArrayPointer ip = &arr;

    double dbl_arr[10] = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.0};
    DoubleArrayPointer dp = &dbl_arr;

    char char_arr[20] = "Another test string.";
    CharArrayPointer cp = &char_arr;

    // 打印基本数据类型
    printf("Integer: %d\n", i);   // Integer: 10
    printf("Real: %.2f\n", r);    // Real: 3.14
    printf("Character: %c\n", c); // Character: A
    printf("String: %s\n", s);    // String: Hello, World!

    // 打印结构体
    printf("Person: %s, %d years old\n", p.name, p.age); // Person: Alice, 30 years old

    // 打印共用体
    printf("Quantity (weight): %.2f\n", q.weight); // Quantity (weight): 5.50

    // 打印指针类型
    printf("Value at IntPtr: %d\n", *iptr);  // Value at IntPtr: 10
    printf("Value at CharPtr: %c\n", *cptr); // Value at CharPtr: A

    // 打印数组类型
    printf("FiveInts array:\n");
    for (int j = 0; j < 5; j++)
    {
        printf("%d ", fi[j]); // 1 2 3 4 5
    }
    printf("\n");

    printf("TenDoubles array:\n");
    for (int j = 0; j < 10; j++)
    {
        printf("%.1f ", td[j]); // 1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 9.9 10.0
    }
    printf("\n");

    printf("TwentyChars array: %s\n", tc); // TwentyChars array: test string

    // 打印数组指针类型
    printf("IntArrayPointer array:\n");
    for (int j = 0; j < 5; j++)
    {
        printf("%d ", (*ip)[j]); // 10 20 30 40 50
    }
    printf("\n");

    printf("DoubleArrayPointer array:\n");
    for (int j = 0; j < 10; j++)
    {
        printf("%.1f ", (*dp)[j]); // 1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 9.9 10.0
    }
    printf("\n");

    printf("CharArrayPointer array: %s\n", *cp); // CharArrayPointer array: Another test string.

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Thanks_ks

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值