//double_pointerEX.c
#include <stdio.h>
funcA(char* ptr[]);
int main()
{
char* ptr[] = { "kingdom test", "Advance C programming", "C++ programming",
"one two three", "multi campus",
"seoul 서울시 강남구 양재동 100번지",
"busan 부산시 해운대구 해운대동 바다 2 번지", NULL };
funcA(ptr);
return 0;
}
// ptr의 길이를 출력
funcA(char** ptr) // char *ptr[] / 포인터배열을 실인수로 전달한다면 가인수는 이중포인터로 받아야 함
{
// 방법1
int i;
while (*ptr) // NULL 주소가 아닐 때까지
{
printf("%u : ", ptr);
for (i = 0; *(*ptr + i); i++)
{
printf("%c", *(*ptr + i));
}
printf(" / length : %d \n", i);
ptr++;
}
// 방법 2
int len = 0;
char* tmp;
while (*ptr)
{
tmp = *ptr;
while (*tmp) // char 1바이트씩 읽어들임
{
len++;
tmp++;
}
printf("%u, %u : %s, Length : %d \n", ptr, *ptr, *ptr, len);
ptr++;
}
printf("End.");
}
//enum_pointerEx.c
#include <stdio.h>
#include <string.h>
typedef enum Season
{
SPRING,
SUMMER,
FALL,
WINTER,
} SEASON;
char* GetSeason(int season)
{
switch (season)
{
case 0:
return("봄"); // 데이터 세그먼트의 read-only data 영역에 들어감
case 1:
return("여름");
case 2:
return("가을");
case 3:
return("겨울");
default:
break;
}
// 방법2
static char ret[100];
switch (season)
{
case SPRING:
strcpy(ret, "봄");
break;
case SUMMER:
strcpy(ret, "여름");
break;
case FALL:
strcpy(ret, "가을");
break;
case WINTER:
strcpy(ret, "겨울");
break;
default:
break;
}
return ret;
}
int main()
{
char* ptr;
enum Season season = SPRING;
ptr = GetSeason(season);
printf("선택한 계절: %s \n", ptr);
return 0;
}
// pointer5.c
#include <stdio.h>
int main()
{
int num[5] = { 100,200,300,400,500 }, i;
int* ptr[5]; // 포인터 배열 => 배열 요소 개수만큼 메모리 할당 수행 20byte
//int(*ptr2)[5]; // 배열 포인터 변수 4 byte
char word[3][20] = { "kingdom", "prince", "princess" };
char* ptr2[3];
printf("ptr sizeof: %d \n", sizeof(ptr));
for (i = 0; i < 5; i++)
ptr[i] = num + i;
//ptr[i] = &num[i];
for (i = 0; i < 5; i++)
printf("%d ,", *ptr[i]);
printf("\n");
//문자열 출력
for (i = 0; i < 3; i++)
ptr2[i] = *(word + i);
//ptr2[i] = *(word + i); // *(*ptr2 + i) = *ptr2[i] //ptr[i][4] = *(*(ptr + i) + 4)
for (i = 0; i < 3; i++)
printf("%s, %c\n", ptr2[i], *ptr2[i]); // i=0 => *ptr2[0] : 'k' 지칭(1byte) // %s => 받은 문자열부터 \0까지 출력
printf("\n");
return 0;
}
//double_pointer2.c
#include <stdio.h>
#include <string.h>
int main()
{
char** ptr, tmp[100];
int x, y, i;
printf("\n문자열의 수 ? ");
scanf("%d%*c", &x); //3
ptr = (char**)malloc(x * sizeof(char*)); // sizeof(char*) => 4byte
if (ptr == NULL) // heap을 할당할 때마다 필요 -> 언제 고갈될 지 모르기 때문
{
perror("Error : ");
exit(1);
}
for (i = 0; i < x; i++)
{
printf("%d,input string ? ", i + 1);
gets(tmp);
*(ptr + i) = (char*)malloc(strlen(tmp) + 1);
strcpy(*(ptr + i), tmp);
}
printf("\n문자열 출력\n");
for (i = 0; i < x; i++)
printf("%p, %s \n", *(ptr + i), *(ptr + i));
printf("\n추가할 문자열의 수 ? \n");
scanf("%d%*c", &y); // 2
ptr = (char**)realloc(ptr, sizeof(char*) * (x + y));
if (ptr == NULL) // heap을 할당할 때마다 필요 -> 언제 고갈될 지 모르기 때문
{
perror("Error : ");
exit(1);
}
for (i = x; i < (x+y); i++)
{
printf("%d,input string ? ", i + 1);
gets(tmp);
*(ptr + i) = (char*)malloc(strlen(tmp) + 1);
strcpy(*(ptr + i), tmp);
}
printf("\n문자열 출력\n");
for (i = 0; i < (x+y); i++)
printf("%p, %s \n", *(ptr + i), *(ptr + i));
printf("\n");
for (i = 0; i < (x + y); i++)
free(ptr[i]); // heap은 사용하고 나면 깨끗하게 비워야 함
free(ptr);
ptr = NULL;
return 0;
}
free 함수 사용안하면 메모리 누수 발생
🔽
//s1_linked.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct EMP {
char name[20];
int salary;
float height;
char comAddr[50];
struct EMP* next;
};
int main()
{
//struct EMP empPtr; //이렇게 선언하면 구조체 변수 100바이트를 할당받는다
struct EMP* head, *tail;
struct EMP* empPtr; //이렇게 선언하면 구조체 포인터 4바이트를 할당받는다
head = tail = NULL; // heap segment 내 값 버리기
while (1)
{
empPtr = (struct EMP*)malloc(sizeof(struct EMP)); // size 바이트의 메모리를 힙에서 할당해 반환
// empPtr에는 할당된 메모리의 주소를 담음
if ((empPtr == NULL))
{
perror("Error :");
exit(1);
}
//데이터 입력
printf("성명 ? (입력종료:end) ");
gets(empPtr->name);
if (strcmp(empPtr->name, "end") == 0)
break;
printf("월급 ?");
scanf("%d", &empPtr->salary);
printf("키(신장) ?");
scanf("%f%*c", &empPtr->height);
printf("회사주소 ?");
gets(empPtr->comAddr);
empPtr->next = NULL;
if (head == NULL)
head = tail = empPtr;
else
{
tail->next = empPtr; // (*구조체_포인터).멤버"는 "구조체_포인터->멤버"와 완전히 동일한 연산문이다. // (*tail).next
tail = empPtr;
}
} // while (1)
empPtr = head;
//데이터 출력
while (empPtr) // while (empPtr != '\0')
{
printf("%s, %d, %.2f, %s \n", empPtr->name, empPtr->salary, empPtr->height, empPtr->comAddr);
empPtr = empPtr->next;
}
//메모리 해제
free(empPtr); // empPtr이 가리키는 메모리를 해제
empPtr = NULL;
return 0;
}
다음 노드의 주소를 포인터 변수에 저장해두고 연속 출력 수행
tail의 역할: 새로운 노드가 유입되면 기존의 노드와 맵핑해줌
단일 링크드 리스트 핵심 단계
struct EMP* head, * tail;
empPtr->next = NULL;
while (empPtr) //메모리 해제 while (empPtr != '\0')
{
x = empPtr;
empPtr = empPtr->next;
free(x); // 반복문을 통해 수 백개의 노드 데이터 삭제
}
-구조체 문자열 변수는 크기 확인 후 대입 필
// s2_linked.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct EMP {
char name[20];
int salary;
float height;
char comAddr[50];
struct EMP* next;
};
int main()
{
//struct EMP empPtr; //이렇게 선언하면 구조체 변수 100바이트를 할당받는다
struct EMP* head, * tail;
struct EMP* empPtr, * x; //이렇게 선언하면 구조체 포인터 4바이트를 할당받는다
char tmp[100]; //임시 배열 활용
head = tail = NULL; // heap segment 내 값 버리기
while (1)
{
empPtr = (struct EMP*)malloc(sizeof(struct EMP)); // size 바이트의 메모리를 힙에서 할당해 반환
// empPtr에는 할당된 메모리의 주소를 담음
if ((empPtr == NULL))
{
perror("Error :");
exit(1);
}
//데이터 입력 (구조체 문자열 변수는 크기 확인 후 대입 필)
do{
printf("성명 ? (입력종료:end) ");
gets(tmp);
} while (strlen(tmp) >= sizeof(empPtr->name));
strcpy(empPtr->name, tmp);
if (strcmp(empPtr->name, "end") == 0)
break;
printf("월급 ?");
scanf("%d", &empPtr->salary);
printf("키(신장) ?");
scanf("%f%*c", &empPtr->height);
printf("회사주소 ?");
gets(empPtr->comAddr);
empPtr->next = NULL; // 끝.(next 가 가리킬 부분이 없다.)
if (head == NULL)
head = tail = empPtr;
else
{
tail->next = empPtr; // (*tail).next // tail 안에 next라는 자기구조체 참조 포인터로 empPtr을 가리킨다.
tail = empPtr;
}
} // while (1)
free(empPtr); // empPtr이 가리키는 메모리를 해제
empPtr = head;
//데이터 출력
while (empPtr) // while (empPtr != '\0')
{
printf("%s, %d, %.2f, %s \n", empPtr->name, empPtr->salary, empPtr->height, empPtr->comAddr);
empPtr = empPtr->next;
}
empPtr = head;
while (empPtr) //메모리 해제 while (empPtr != '\0')
{
x = empPtr;
empPtr = empPtr->next;
free(x); // 반복문을 통해 수 백개의 노드 데이터 삭제
}
empPtr = NULL;
return 0;
}
//d1_linked.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct EMP {
char name[20];
int salary;
float height;
char comAddr[50];
struct EMP* before;
struct EMP* next;
};
int main()
{
struct EMP* head, * tail;
struct EMP* empPtr, * x;
head = tail = NULL; // heap에 아무것도 들어있지 않음
while (1) // 데이터 입력
{
empPtr = (struct EMP*)malloc(sizeof(struct EMP)); // size 바이트의 메모리를 힙에서 할당해 반환
// empPtr에는 할당된 메모리의 주소를 담음
if (empPtr == NULL)
{
perror("Error : ");
exit(1);
}
printf("\n성명 ? (입력종료: end) "); // kim
gets(empPtr->name);
if (!strcmp(empPtr->name, "end"))
break;
printf("월급 ? "); // 1000
scanf("%d", &empPtr->salary);
printf("키(신장) ? "); // 173
scanf("%f%*c", &empPtr->height);
printf("회사주소 ? "); // seoul
gets(empPtr->comAddr);
empPtr->before = NULL;
empPtr->next = NULL;
if (head == NULL)
head = tail = empPtr;
else
{
empPtr->before = tail;
tail->next = empPtr;
tail = empPtr;
}
} // while(1) end
free(empPtr); // 7000번지를 없애겠다
printf("============ head -> tail =============\n");
empPtr = head;
while (empPtr) // 데이터 출력
{
printf("%s, %d, %.2f, %s \n", empPtr->name, empPtr->salary, empPtr->height, empPtr->comAddr);
empPtr = empPtr->next;
}
printf("============ tail-> head =============\n");
empPtr = tail;
while (empPtr) // 데이터 출력
{
printf("%s, %d, %.2f, %s \n", empPtr->name, empPtr->salary, empPtr->height, empPtr->comAddr);
empPtr = empPtr->before;
}
printf("=========================\n");
empPtr = head;
// 반복문 통해 수많은 노드 삭제함으로써 메모리 해제
while (empPtr)
{
x = empPtr;
empPtr = empPtr->next;
free(x); // empPtr이 가리키는 메모리를 해제
}
empPtr = NULL;
return 0;
}
//s2_linked.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct EMP {
char name[20];
int salary;
float height;
char *comAddr; // 동적할당 멤버
struct EMP* next;
};
int main()
{
struct EMP* head, * tail;
struct EMP* empPtr, * x;
char tmp[250];
head = tail = NULL; // heap에 아무것도 들어있지 않음
while (1) // 데이터 입력
{
empPtr = (struct EMP*)malloc(sizeof(struct EMP)); // size 바이트의 메모리를 힙에서 할당해 반환
// empPtr에는 할당된 메모리의 주소를 담음
if (empPtr == NULL)
{
perror("Error : ");
exit(1);
}
do {
printf("\n성명 ? (입력종료: end) "); // kim
gets(tmp);
} while (strlen(tmp) >= sizeof(empPtr->name)); //name 할당량보다 길이가 길 경우
strcpy(empPtr->name, tmp); // 문자열 직접 받으면 안 되고 함수를 불러 처리 -> 구조체의 문자열 멤버는 확인하고 넣어야 함
if (!strcmp(empPtr->name, "end"))
break;
printf("월급 ? "); // 1000
scanf("%d", &empPtr->salary);
printf("키(신장) ? "); // 173
scanf("%f%*c", &empPtr->height);
printf("회사주소 ? "); // seoul
gets(tmp);
empPtr->comAddr = (char*)malloc(strlen(tmp) + 1); // * 붙어있는 경우 주소를 따로 동적할당
strcpy(empPtr->comAddr, tmp);
empPtr->next = NULL;
if (head == NULL)
head = tail = empPtr;
else
{
tail->next = empPtr;
tail = empPtr;
}
} // while(1) end
free(empPtr); // 7000번지를 없애겠다
empPtr = head; // 3000 번지, 4000 번지 두 개의 값 O
while (empPtr) // 데이터 출력
{
printf("%s, %d, %.2f, %s \n", empPtr->name, empPtr->salary, empPtr->height, empPtr->comAddr);
empPtr = empPtr->next;
}
empPtr = head;
// 반복문 통해 수많은 노드 삭제함으로써 메모리 해제
while (empPtr) // 특정 멤버가 동적할당 되면 그거 먼저 지우고 부모를 지워야 함
{
x = empPtr;
empPtr = empPtr->next;
free(x->comAddr);
free(x); // empPtr이 가리키는 메모리를 해제
}
empPtr = NULL;
return 0;
}