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

news/2024/12/21 21:50:01/

目录

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: 1printf("b: %d\n", b); // b: 2return 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: zprintf("ASCII value of c: %u\n", c); // 以无符号整数形式打印 ASCII 值 ASCII value of c: 122return 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); // 10printf("doughnut: %d\n", donut);  // 20printf("mushroom: %d\n", mush);   // 30// 声明并初始化其他基本数据类型的别名变量Byte b = 'A';Real r = 3.14f;Double d = 2.71828;// 打印变量的值printf("Byte: %c\n", b);    // Aprintf("Real: %f\n", r);    // 3.140000printf("Double: %lf\n", d); // 2.718280return 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);   // Oakprintf("Legs: %d\n", t.legs);   // 0printf("Speed: %d\n", t.speed); // 0return 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);   // Oakprintf("Legs: %d\n", t.legs);   // 0printf("Speed: %d\n", t.speed); // 0return 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);   // Oakprintf("Legs: %d\n", t.legs);   // 0printf("Speed: %d\n", t.speed); // 0return 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.718return 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); // 20return 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: helloprintf("str2: %s\n", str2); // str2: helloreturn 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: 10printf("Real: %.2f\n", r);    // Real: 3.14printf("Character: %c\n", c); // Character: Aprintf("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: 10printf("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;
}

http://www.ppmy.cn/news/1536839.html

相关文章

认证技术原理与应用

目录 原理 依据 类型 方法 应用 原理 认证技术主要是确认一个实体&#xff08;如人、设备&#xff09;是否为其所声称的身份。这通常通过以下步骤实现&#xff1a; 身份识别&#xff1a;确定被认证对象的身份标识&#xff0c;如用户名、ID号等。 身份验证&#xff1a;验…

算法知识点————【DFS】【BFS】【树】【图】

** 深度优先搜索 ** DFS 用于遍历树和图的算法&#xff0c;过程中深入到不能深入为止&#xff0c;每个结点遍历一次。 ** 广度优先搜索 ** BFS 用于 从根结点开始遍历&#xff0c;遍历根结点下面的所有孩子结点&#xff0c;然后从孩子结点在进行宽度搜索&#xff0c;直到所有的…

Redis: 集群环境搭建,集群状态检查,分析主从日志,查看集群信息

集群环境搭建 在 Redis 5版本以前是用 Ruby 来搭建集群&#xff0c;在后面的版本中仍保留了相关功能可以再源码src目录中&#xff0c;看到 redis-trib.rb 这个东西&#xff0c;只是现在用这种方式搭建的少了我们看新的版本是怎样搭建集群的&#xff0c;新版构建集群的方式简单…

前端面试:项目细节重难点问题分享(17)

更多详情&#xff1a;爱米的前端小笔记&#xff08;csdn~xitujuejin~zhiHu~Baidu~小红shu&#xff09;同步更新&#xff0c;等你来看&#xff01;都是利用下班时间整理的&#xff0c;整理不易&#xff0c;大家多多&#x1f44d;&#x1f49b;➕&#x1f914;哦&#xff01;你们…

zabbix -rockylinux安装

文章目录 一、环境配置1.1、修改主机名1.2、修改静态ip地址1.3、系统更新1.4、安装epel仓库 二、安装zabbix2.1、添加zabbix仓库2.2、配置数据库2.3、配置zabbix服务器2.4、启动zabbix服务 一、环境配置 1.1、修改主机名 [rootecs-204824 /]# vi /etc/hostname [rootecs-2048…

诸葛亮的传奇人生,对后世有哪些深远的影响?

诸葛亮&#xff0c;字孔明&#xff0c;号卧龙&#xff0c;生于东汉光和四年&#xff08;公元181年&#xff09;&#xff0c;卒于蜀汉建兴十二年&#xff08;公元234年&#xff09;&#xff0c;是中国历史上一位卓越的政治家、军事家、战略家、文学家、发明家。他的一生充满了传…

大学生就业市场:Spring Boot招聘系统的设计与实现

4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式&#xff0c;是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示&#xff1a; 图4-1系统工作原理…

1.MySQL存储过程基础(1/10)

引言 数据库管理系统&#xff08;Database Management System, DBMS&#xff09;是现代信息技术中不可或缺的一部分。它提供了一种系统化的方法来创建、检索、更新和管理数据。DBMS的重要性体现在以下几个方面&#xff1a; 数据组织&#xff1a;DBMS 允许数据以结构化的方式存…