typedef为结构体指针命名

文章探讨了在C语言中typedef的作用,特别是在建立循环单链表时使用二级指针的情况。作者指出,typedef并不等同于#define,它用于定义类型别名。在InitList函数中,使用二级指针CL是为了确保在函数内部对链表头节点的修改能在函数外部保持。文章通过代码示例和运行结果展示了typedef和#define的区别以及指针在函数参数中的行为。
摘要由CSDN通过智能技术生成

typedef随笔

今天看数据结构的循环单链表的时候发现了一个有意思的问题,先看代码。

InitList(List *CL)
{
    *CL = (List)malloc(sizeof(Node));
    (*CL)->next = *CL;
}

这里的->一般适用于结构体指针,那么CL为一个指针,可见CL是一个二级指针,而函数形参的声明是List CL,这一般来说是一个一级指针的声明,于是产生了不解,故查看了List结构体的声明如下。

typedef struct Node
{
    ElemType data;
    struct Node *next;
}Node,*List;

看到这里笔者发现了问题,当时的C语言课程时,老师所教授的typedef的作用和**#define是一样的即是机械替换,那么这里的List*该如何解释?按照笔者习惯将他拆解为:

typedef struct Node* List;

也就是说List其实是一个Node类型的结构体指针声明,可用List代替struct Node*,那么不难看出InitList(List *CL)中的CL其实是一个二级指针的声明。那么这里是为什么用到了二级指针?

在这里插入图片描述

:在InitList函数中,主要是建立循环单链表的头节点,创建好的头节点的next指针必须指向自己,若单单传入一级指针CL将丢失Node结点地址,因为这里的CL只是函数的形参一旦离开函数所保存到的值将丢失。

代码验证

#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
	int data;
	struct node *next;	
} node,*Node;
void func1(Node T){
	printf("\nfunc1\n");
	printf("T的地址		%p\n",&T);
	printf("T的值		%p\n",T);
	Node *p;//这里的p是二级指针 
	p=(Node*)malloc(sizeof(Node));
	*p=T;//同为一级指针 
	printf("p的地址是	%p\n",&p);	
	printf("p的值是		%p\n",p);
	printf("*p的值		%p\n",*p);
}
void func2(Node *T){
	printf("\nfunc2\n");
	printf("T的地址		%p\n",&T);
	printf("T的值		%p\n",T);
	printf("*T的值		%p\n",*T);
}
void func3(Node T){
	Node p=(Node)malloc(sizeof(node));
	T=p;//T指向新节点
	printf("新节点的地址	%p\n",p); 
} 
int main(){
	Node T=NULL;
	T=(Node)malloc(sizeof(node));
	T->data=1;
	printf("main函数\n");
	printf("T的地址		%p\n",&T);
	printf("T的值		%p\n",T);
	func1(T);
	func2(&T);
	func3(T);
	printf("在func3中更改T的值后T的值\n		%p",T); 
}

运行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LVbaWc3W-1680107624223)(C:\Users\郑志玮_\AppData\Roaming\Typora\typora-user-images\image-20230330002637958.png)]

另注:typedef区别于**#define**的一个点

typedef char *STR;

编译器把STRING解释为一个类型的表示符,该类型指向char。因此

STR name, sign;

等价于

char *name, *sign; 

即name和sign均为字符指针,而若用**#define**

#define STR char *

下面的声明:

STR name, sign;

将被翻译成:

char *name, sign;

这导致sign只是一个字符变量。

TR char *

下面的声明:

STR name, sign;

将被翻译成:

char *name, sign;

这导致sign只是一个字符变量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值