C语言和C++中结构体定义与使用的区别
问题
在PAT网站做题目“02-线性结构1 两个有序链表序列的合并 (15 分)”时,遇到了代码编译错误的问题。
题目只允许使用C语言。
网站给出的List结构定义
typedef struct Node *PtrToNode;
struct Node {
ElementType Data; /* 存储结点数据 */
PtrToNode Next; /* 指向下一个结点的指针 */
};
typedef PtrToNode List; /* 定义单链表类型 */
原代码
List Merge(List L1, List L2)
{
Node *p1, *p2; //编译错误
p1 = L1->Next;
p2 = L2->Next;
if (p1 == NULL) //判断是否存在空链表
return L2;
if (p2 == NULL)
return L1;
List L; //创建合并后链表的头结点
L = (Node*)malloc(sizeof(Node)); //编译错误
if (!L) return 0;
L->Next = NULL;
Node* tmp = L; //编译错误
while (p1 && p2)
{
if (p1->Data <= p2->Data)
{
tmp->Next = p1;
tmp = tmp->Next;
L1->Next = p1->Next; //删除被合并到L上的结点
p1 = p1->Next;
}
else
{
tmp->Next = p2;
tmp = tmp->Next;
L2->Next = p2->Next;
p2 = p2->Next;
}
}
if (p1) //将剩下的一段加入链表L
{
tmp->Next = p1;
L1->Next = NULL;
}
if (p2)
{
tmp->Next = p2;
L2->Next = NULL;
}
return L;
}
OJ评判结果
编译错误:unknown type name ‘Node’
问题修正
根据提示,Node不能作为一种数据类型,应该使用List或struct Node。
修改后代码
List Merge(List L1, List L2)
{
struct Node *p1, *p2;
p1 = L1->Next;
p2 = L2->Next;
if (p1 == NULL) //判断是否存在空链表
return L2;
if (p2 == NULL)
return L1;
List L; //创建合并后链表的头结点
L = (List)malloc(sizeof(struct Node));
if (!L) return 0;
L->Next = NULL;
struct Node* tmp = L;
while (p1 && p2)
{
if (p1->Data <= p2->Data)
{
tmp->Next = p1;
tmp = tmp->Next;
L1->Next = p1->Next; //删除被合并到L上的结点
p1 = p1->Next;
}
else
{
tmp->Next = p2;
tmp = tmp->Next;
L2->Next = p2->Next;
p2 = p2->Next;
}
}
if (p1) //将剩下的一段加入链表L
{
tmp->Next = p1;
L1->Next = NULL;
}
if (p2)
{
tmp->Next = p2;
L2->Next = NULL;
}
return L;
}
OJ评判结果
问题分析与总结
思考
为何原代码在VS2019中可以编译通过,而在PAT上却显示编译错误?
原因在于C和C++语言中对结构体的定义要求略有不同。由于PAT对于本题限制使用C语言,故出现编译失败的问题。
下面具体看看C和C++语言中结构体如何定义(以链表结点为例)。
C语言中结构体的定义
方法一
struct Node
{
ElemType data;
struct Node *next;
};
那么要声明这种结构体的变量,必须要这样写:
struct Node xxx;
也就是说,每次必须在前面加上“struct”。
有没有更加简便的方法呢?
方法二
用typedef给这种结构定义一种类型名
typedef struct Node
{
ElemType data;
struct Node *next;
}MyNode;
现在你拥有了一种新的类型,叫做MyNode,可以用它定义变量:
MyNode xxx;
C++中结构体的定义
在C++中,struct和class本质上都是类,就不用写typedef了,直接定义即可:
struct Node
{
ElemType data;
Node *next;
};
在声明结构对象时,也不须加上关键字“struct”了。
Node xxx;
同时C++也支持C的方式,struct Node xxx;
和Node xxx;
是相同的。