C 语言学习(4) ---- C语言中的 typedef 关键字

typedef 关键字定义

C语言允许用户使用 typedef 关键字来定义自己习惯的数据类型名称,typedef 的真正含义是给一个已经存在的类型名称起一个别名,注意是已经存在的数据类型,而非变量

typedef 可以给下面的类型取别名,基本数据类型,数组类型名称,指针类型名称和用户自定义的结构体类型,枚举类型,共用类型

一旦用户在程序中定义了自己的数据类型名称,就可以在该程序中用自己的数据类型来定义变量的类型,数组类型,指针变量类型和函数类型等,typedef 不是真正创造了一种数据类型,而是给已有的绘制复合型的以及复杂的数据类型取一个更加容易理解的别名。

typedef 定义基本类型

typedef signed char        int8_t;
typedef short              int16_t;
typedef int                int32_t;
typedef long long          int64_t;
typedef unsigned char      uint8_t;
typedef unsigned short     uint16_t;
typedef unsigned int       uint32_t;
typedef unsigned long long uint64_t;

上面是为已有的数据类型起了一个别名,使用 int8_t 的时候 就和使用 signed char 类型是一致的,此外,我们还可以使用这种方法来定义于平台无关的类型,这样,当跨平台移植程序时,我们只需要修改一下 typedef 的定义即可,而不用对其他源代码做任何修改。

typedef 定义指针和数组类型

//  pointer 一个指向 int 类型的指针类型
typedef int *pointer;

//  一个数组类型 pointerarray
typedef int *pointerarray[10];

//  数组指针类型arraypointer, 数组元素为 int 类型,数组大小为10
typedef int (*arraypointer)[10];

typedef int array[];

// 数组类型 fixedarray,数组元素为 int 类型,数组大小为10
typedef int fixedarray[10];

// 二维数组类型,数组元素为 int 类型,数组大小为10 *10 
typedef int fixedsarray[10][10];

typedef int *pointer 定义了一个指针类型,当我们使用 pointer p 声明一个指针变量就和使用 int *p 的含义是一样的

typedef int *pointerarray[10]  定义了一个数组类型,当我们使用 pointerarray p 声明变量 p,表示声明一个数组 p ,数组大小为10,数组的元素类型为 int*

    	/*p[0] = 0053F968
	p[1] = 0053F96C
	p[2] = 0053F970
	p[3] = 0053F974
	p[4] = 0053F978
	p[5] = 0053F97C
	p[6] = 0053F980
	p[7] = 0053F984
	p[8] = 0053F988
	p[9] = 0053F98C*/
	{
		int a[10] = {0};
		pointerarray p = {NULL};
		for (int i = 0; i < 10; i++) {
			p[i] = &a[i];
		}

		for (int i = 0; i < 10; i++) {
			printf("p[%d] = %p \n", i, p[i]);
		}
		printf("\n");
	}

typedef int (*arraypointer)[10]; 定义了一个数组指针类型,当我们使用 arraypointer p 声明变量 p,表示声明一个指针变量 p,p 指向一个元素类型为 int,大小为 10 的数组

typedef int fixedarray[10];
typedef int fixedsarray[10][10];

定义了两个数组类型,fixedarray a,表示定义了一个元素类型为 int,大小为10 的数组,同理fixedsarray 表示的是 10x10 的二维数组

typedef 定义结构体类型

typedef struct {
	int x;
	int y;
	int width;
	int height;
} stBufferinfo;

typedef struct {
	int x;
	int y;
	int width;
	int height;
} *pstBufferinfo;

typedef enum {
	MON,
	TUE,
	WED,
	THR,
	FRI,
	SAT,
	SUN,
} enweekday;

typedef enum {
	sMON,
	sTUE,
	sWED,
	sTHR,
	sFRI,
	sSAT,
	sSUN,
} *penweekday;

stBufferinfo 定义了一个结构类型,stBufferinfo bufferinfo 就表示定义了一个结构体,结构体类型为stBufferinfo,结构体变量名为 bufferinfo。

pstBufferinfo 定义了一个指针类型,指向的是pstBufferinfo 前定义的结构体类型

同理 enweekday 和 penweekday 也是定义了了一个枚举类型和指向枚举的指针类型

typedef 定义函数类型

typedef int stfunction(int a, int b);

typedef int  (*pstfunction)(int a, int b);

typedef int  *prstfunction(int a, int b);

stfunction 定义的是一个函数类型,此函数返回值为int,两个参数都是 int 类型,但是C语言中不存在函数的类型,使用时可以使用 stfunction* 的形式定义一个函数指针。

pstfunction 直接定义个函数指针类型

注意 prstfunction 和 pstfunction相比只是少了括号,含义却是一个函数类型,返回值为 int 类型指针,有两个int 类型的参数

	{
		stfunction *pfunc = CommonAdd;
		//stfunction *pfunc = &CommonAdd;
		printf("test pfunc a + b = %d \n", pfunc(10, 20));
		printf("test pfunc a + b = %d \n", (*pfunc)(10, 20));
	}
	printf("=========================================\n");

	{
		pstfunction pfunc = CommonAdd;
		printf("test pfunc a + b = %d \n", pfunc(10, 20));
		printf("test pfunc a + b = %d \n", (*pfunc)(10, 20));
	}
	printf("=========================================\n");

	{
		//prstfunction = CommonAdd;

	}

注意函数指针赋值时,可以直接使用函数名,也可以对函数名取地址。

typedef 和宏定义之间的关系

typedef 的功能是为已经存在的类型起一个别名,这一点 #define 也可以做到,但是除此之外 #define 还有其他用处,这个是 typedef 所不具备的。

从执行时间上讲,对于 #define 定义的宏,在预处理阶段就会被替换,而 typedef 的定义是在编译期间处理

从一般来说 #define 定义的宏没有作用域的限制,只要在使用前定义就可以,而 typedef 定义的别名是有作用域的(在文件头声明或者在函数中声明有区别)

我们使用 typedef 定义一个指针类型,然后使用该类型可以同时声明多个变量,而 #define 却不是这样的。例如,typedef (int*) pType; 可以使用pType a, b; 这里 a 和 b 都是指向整数的指针变量。但我们同样定义 #define pType int*, 若使用 pType a, b; 定义 a 和 b,则 a 是指向整数的指针变量,而 b 不是

从功能范围来讲,typedef 主要是为已经存在的关键字或者类型及其组合取一个我们容易识别的别名。在这一点上 #define 也可以实现,但除此之外 #define 还有其他用处,如果愿意的话你可以使用它定义任何代码,这是 typedef 所不具备的。

从执行时间来讲,对于 #define 定义的宏,其在预处理阶段就会被替换,而 typedef 定义的类型会在编译时处理。

从作用域上来讲,一般来说 #define 定义的宏没有作用域的限制,只要在使用前定义就可以,而 typedef 定义的别名是有作用域的。

从实现效果来讲,我们使用 typedef 定义一个指针类型,然后使用该类型可以同时声明多个变量,而 #define 却不是这样的。例如,typedef (int*) pType; 可以使用pType a, b; 这里 a 和 b 都是指向整数的指针变量。但我们同样定义 #define pType int*, 若使用 pType a, b; 定义 a 和 b,则 a 是指向整数的指针变量,而 b 不是。

还需要特别注意的是,虽然 typedef 并不真正影响对象的存储特性,但在语法上它还是一个存储类的关键字,就像 auto、extern、static 和 register 等关键字一样。因此,像下面这种声明方式是不可行的:

typedef static int marray[];

  • 6
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 要遍历C语言关键字,可以使用C语言标准库的<string.h>头文件和<ctype.h>头文件的函数。下面是一种实现方式: 1. 定义一个字符数组来存储C语言的所有关键字,例如: ``` char *keywords[] = {"auto", "break", "case", "char", "const", "continue", "default", "do", "double", "else", "enum", "extern", "float", "for", "goto", "if", "int", "long", "register", "return", "short", "signed", "sizeof", "static", "struct", "switch", "typedef", "union", "unsigned", "void", "volatile", "while"}; ``` 2. 对于输入的每个单词,使用C语言标准库的<ctype.h>头文件的函数检查它是否为关键字。例如,使用strcmp函数比较输入的单词是否与数组的任何一个关键字相等: ``` int is_keyword(char *word) { int i, n; n = sizeof(keywords) / sizeof(char *); for (i = 0; i < n; i++) { if (strcmp(word, keywords[i]) == 0) { return 1; } } return 0; } ``` 3. 对于输入的每个单词,还需要使用C语言标准库的<ctype.h>头文件的函数将其转换为小写字母,以便与关键字数组的字符串进行比较。例如,使用tolower函数将单词转换为小写字母: ``` void to_lower(char *word) { while (*word) { *word = tolower(*word); word++; } } ``` 4. 最后,可以将输入的文本分解成单词,并调用is_keyword函数和to_lower函数来检查它们是否为关键字。 以下是一个完整的示例程序,演示如何遍历C语言关键字: ``` #include <stdio.h> #include <string.h> #include <ctype.h> char *keywords[] = {"auto", "break", "case", "char", "const", "continue", "default", "do", "double", "else", "enum", "extern", "float", "for", "goto", "if", "int", "long", "register", "return", "short", "signed", "sizeof", "static", "struct", "switch", "typedef", "union", "unsigned", "void", "volatile", "while"}; int is_keyword(char *word) { int i, n; n = sizeof(keywords) / sizeof(char *); for (i = 0; i < n; i++) { if (strcmp(word, keywords[i]) == 0) { return 1; } } return 0; } void to_lower(char *word) { while (*word) { *word = tolower(*word); word++; } } int main() { char text[] = "for (int i = 0; i < n; i++) { printf(\"%d\\n\", i); }"; char *word; word = strtok(text, " "); ### 回答2: 在C语言关键字是预定义的标识符,用于表示语言的特殊功能和结构。要遍历C语言关键字,可以按照以下步骤进行: 1. 创建包含C语言所有关键字的数组。根据C语言的标准,可以将关键字存储在一个字符串数组。 2. 使用循环结构,遍历数组的每个关键字。可以使用for循环或while循环来实现遍历。 3. 在循环,将每个关键字打印出来或进行其他操作。可以使用printf函数将关键字输出到控制台上,也可以将其存储在新的数组或其他数据结构。 4. 执行完循环后,即可遍历所有的C语言关键字。 下面是一个简单的示例代码,用于遍历C语言关键字: ```c #include<stdio.h> #include<string.h> int main() { char* keywords[] = {"auto", "break", "case", "char", "const", "continue", "default", "do", "double", "else", "enum", "extern", "float", "for", "goto", "if", "int", "long", "register", "return", "short", "signed", "sizeof", "static", "struct", "switch", "typedef", "union", "unsigned", "void", "volatile", "while"}; int numKeywords = sizeof(keywords) / sizeof(keywords[0]); for(int i = 0; i < numKeywords; i++) { printf("%s\n", keywords[i]); } return 0; } ``` 以上代码通过使用循环遍历并打印出C语言的所有关键字。运行代码后,会依次打印出每个关键字,完成关键字的遍历。 ### 回答3: 要遍历C语言关键字,首先需要了解C语言关键字有哪些。C语言关键字是由编译器预先定义的,用于表示特定功能或命令的保留字。 C语言关键字共有32个,包括基本数据类型(如int、float、char等)、流程控制语句(如if、while、for等)、函数定义关键字(如void、return等)等。 遍历C语言关键字可以采用以下步骤: 1. 定义一个字符串数组,用于存储C语言关键字。 2. 创建一个循环,循环变量从0到31(因为C语言一共有32个关键字)。 3. 在循环,依次将每个关键字赋值给字符串数组的元素。 4. 遍历完所有关键字后,输出或处理字符串数组关键字。 以下是示例代码: ``` #include <stdio.h> #include <string.h> int main() { char keywords[32][10] = {"auto", "break", "case", "char", "const", "continue", "default", "do", "double", "else", "enum", "extern", "float", "for", "goto", "if", "int", "long", "register", "return", "short", "signed", "sizeof", "static", "struct", "switch", "typedef", "union", "unsigned", "void", "volatile", "while"}; int i; for (i = 0; i < 32; i++) { printf("%s\n", keywords[i]); } return 0; } ``` 以上代码会将C语言关键字遍历并逐个输出。可以根据实际需求,将关键字存储到其他数据结构,或进行其他处理操作。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值