[혼연C] 단순연결리스트 예제 컴파일이 안돼서...
혼자 연구하는 C/C++의 단순 연결 리스트를 혹시나 싶어서 코딩해봤는데 오류를 뿜으며 컴파일이 안되더라. OSX환경이라 그런 것인지 아니면 이곳의 예제가 C++ 컴파일러여야 하는것인지, 아님 내가 그저 gcc(Apple LLVM)로 컴파일을 해서 문제가 있는 것인지는 모르겠다. 아무튼 구조체 태그를 가지고 새로운 변수를 선언/정의할 때, C에서는 일일이 struct를 붙여줘야 한다. 그냥 데이터 타입처럼 바로 쓰는 건 C++이 허용하는 문법이라고.
그래서 다시 작성함. 도대체 어디가 문제인지 좀 헤맸는데 의외로 엄청 친절하고 꼼꼼한 선생님이 계셨으니… 바로 Xcode… vi로 코딩하다 머리 뜯으며 Xcode로 옮겨보니 바로 알려주시네. 다음 코드는 오류나 경고를 모두 제거하고 표준 C로 재작성된 코드.
// Simple Linked List
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Node {
int value;
struct Node *next;
};
struct Node *head;
void initList()
{
head = (struct Node*)malloc(sizeof(struct Node));
head->next = NULL;
}
struct Node* insertNextTo(struct Node* target, struct Node* newNode)
{
struct Node *new;
new = (struct Node*)malloc(sizeof(struct Node));
*new = *newNode;
new->next = target->next;
target->next = new;
//free(newNode);
return new;
}
unsigned int removeNextTo(struct Node* target)
{
struct Node *del;
del = target->next;
if(del==NULL) {
return 0;
}
target->next = del->next;
free(del);
return 1;
}
void releaseList()
{
while(removeNextTo(head)){;}
free(head);
head=NULL;
}
int main(int argc, const char *argv[])
{
initList();
struct Node *now, temp;
now = head;
int i;
for(i=1;i<=5;i++){
temp.value = i;
now = insertNextTo(now, &temp);
}
removeNextTo(head->next);
for(now=head->next;now;now=now->next)
{
printf("%02d ==>", now->value);
}
return 0;
}
다음과 같이 typedef를 쓰는 경우에 조금 애매한 부분이 있는데 typedef 로 구조체를 타입으로 만들 때 그 구조체가 자신을 가리키는 포인터를 멤버로 가지면, 그 때의 자신은 그냥 구조체의 포인터로 써야한다. (타입의 포인터를 쓰면 에러.)
아래와 같이 변경된다.
// Simple Linked List
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct __node {
int value;
struct __node *next;
} node;
node *head;
void initList()
{
head = (node*)malloc(sizeof(node));
head->next = NULL;
}
node* insertNextTo(node* target, node* newNode)
{
node *new;
new = (node*)malloc(sizeof(node));
*new = *newNode;
new->next = target->next;
target->next = new;
//free(newNode);
return new;
}
unsigned int removeNextTo(node* target)
{
node *del;
del = target->next;
if(del==NULL) {
return 0;
}
target->next = del->next;
free(del);
return 1;
}
void releaseList()
{
while(removeNextTo(head)){;}
free(head);
head=NULL;
}
int main(int argc, const char *argv[])
{
initList();
node *now, temp;
now = head;
int i;
for(i=1;i<=5;i++){
temp.value = i;
now = insertNextTo(now, &temp);
}
removeNextTo(head->next);
for(now=head->next;now;now=now->next)
{
printf("%02d ==>", now->value);
}
return 0;
}
p.s. 구조체를 타입으로 선언하고 그 속에서 구조쳬 자신의 포인터를 지칭할 때는 구조체 이름과 타입 이름이 같은 것으로 간주되나, 가능하면 내부적으로 구분하여 사용하는 것이 조금 더 낫고. (왜냐하면 뒤에서 구조체 태그인지 타입명인지를 구분해야 할 때가 있으므로) 이를 구조체 내에서 명시하는 것이 좋다.