-
结构体定义,使用typedef和不使用的区别
近期在学习c语言开发中,发现关于结构体的定义与使用,不同的人,不同出处的代码写法和用法都不一样的,而我在看了两种方式后,尝试去写一下代码,发现编译不过,于是怀着探究的态度,对着代码一顿尝试,终于算是理解了一点点,将过程记录下来。
原始代码如下:
struct ListNode
{
int val;
struct ListNode *next;
};
struct ListNode *addTwoNumbers(struct ListNode *l1, struct ListNode *l2)
{
struct ListNode *head = NULL;
struct ListNode *tail = NULL;
int carry = 0;
while (l1 || l2)
{
int n1 = l1 ? l1->val : 0;
int n2 = l2 ? l2->val : 0;
int sum = n1 + n2 + carry;
if (!head)
{
head = tail = (struct ListNode *)malloc(sizeof(struct ListNode));
tail->val = sum % 10;
tail->next = NULL;
}
else
{
tail->next = (struct ListNode *)malloc(sizeof(struct ListNode));
tail->next->val = sum % 10;
tail = tail->next;
tail->next = NULL;
}
carry = sum / 10;
if (l1)
{
l1 = l1->next;
}
if (l2)
{
l2 = l2->next;
}
}
if (carry > 0)
{
tail->next = (struct ListNode *)malloc(sizeof(struct ListNode));
tail->next->val = carry;
tail->next->next = NULL;
}
return head;
}
这段代码在定义ListNode的时候,直接使用了struct关键字,然后在下个函数使用时,对结构体的引用和maccloc申请内存时,均需要指定struct关键字,这样编译下来没有报错,如果我们换成typedef定义看看会发生什么呢?
typedef struct _ListNode
{
int val;
struct ListNode *next;
} ListNode;
这样定义后,进行编译,果不其然就发生了错误:
原因在于使用了typedef定义了ListNode后,就不需要再使用struct关键字进行申请了,从实际的项目中来看,使用typedef的用法居多,也更简洁,最终下面的函数代码改成如下后顺利运行
ListNode *addTwoNumbers(ListNode *l1, ListNode *l2)
{
ListNode *head = NULL;
ListNode *tail = NULL;
int carry = 0;
while (l1 || l2)
{
int n1 = l1 ? l1->val : 0;
int n2 = l2 ? l2->val : 0;
int sum = n1 + n2 + carry;
if (!head)
{
head = tail = (ListNode *)malloc(sizeof(ListNode));
tail->val = sum % 10;
tail->next = NULL;
}
else
{
tail->next = (ListNode *)malloc(sizeof(ListNode));
tail->next->val = sum % 10;
tail = tail->next;
tail->next = NULL;
}
carry = sum / 10;
if (l1)
{
l1 = l1->next;
}
if (l2)
{
l2 = l2->next;
}
}
if (carry > 0)
{
tail->next = (ListNode *)malloc(sizeof(ListNode));
tail->next->val = carry;
tail->next->next = NULL;
}
return head;
}
但是需要注意的是,使用了typedef时,如果结构体中包含自身结构体,如链表这种结构时,结构体中的结构体需要写成typedef struct后面的值,不能写成重定义名,否则会报错编译不通过,需要写成:
typedef struct _ListNode
{
int val;
struct _ListNode *next;
} ListNode;