파일명 : 1.c

파일명 : 0.c

파일명 : 4.c

파일명 : flexible_array.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
	int age;
	char *name;	//메모리에 낭비되지 않게 힙에다가 만듭신다.
} PERSON;	//힙에 만듭시다.

void main() {
	int age;
	char name[32];
	PERSON *p;

	printf("input name: ");
	scanf("%s", name);
	printf("input age: ");
	scanf("%d", age);

	p = (PERSON*)malloc(sizeof(PERSON));
	p->age = age;
	
	p->name=(char*)malloc(strlen(name)+1);	//strlen은 null을 포함하지않으니까 +1해준다.
	strcpy(p->name, name);

	printf("name: %s, age: %d\n", p->name, p->age);

	free(p->name);
	free(p);
}



ppt 8쪽

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
	int age;
	char name[1];	//개발자의 편법! 1글자도 아니고 null만 들어가는데?
} PERSON;	//힙에 만듭시다.

void main() {
	int age;
	char name[32];
	PERSON *p;

	printf("input name: ");
	scanf("%s", name);
	printf("input age: ");
	scanf("%d", age);

	p = (PERSON*)malloc(sizeof(PERSON)+ sizeof(char)*strlen(name));	//위에서 말한 개발자의 편법!
	p->age = age;
	
	p->name=(char*)malloc(strlen(name)+1);	//strlen은 null을 포함하지않으니까 +1해준다.
	strcpy(p->name, name);

	printf("name: %s, age: %d\n", p->name, p->age);

	free(p->name);
	free(p);
}

  • int arr[0];    //배열의 길이는 0을 설정할 수 없다.
  • typedef struct{
    int arr[0];
    } TYPE;

    void main() {
        TYPE type; 
        printf("%d\n", sizeof(type));    //4가 출력된다. 포인터의 타입에 따른..
    }

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
	int age;
					// 99년도에 표준 되었다. C99
	char name[];	//char name[0];	//->flexible array member
			//사이즈가 안 잡혀있는데 도대체 무슨 역할을하는걸까?(ppt10~11쪽)
} PERSON;

//반드시 flexible array member는 구조체의마지막에 와야한다.

void main() {
	// printf("%d\n", sizeof(PERSON));	//4가 나옴.

	int age;
	char name[32];
	PERSON *p;

	printf("input name: ");
	scanf("%s", name);
	printf("input age: ");
	scanf("%d", age);

	p = (PERSON*)malloc(sizeof(PERSON)+ sizeof(char)*strlen(name) + 1);	 

//null값 포함하기 위해서 +1 그럼 런타임 에러 안남. p->age = age; p->name=(char*)malloc(strlen(name)+1); strcpy(p->name, name); printf("name: %s, age: %d\n", p->name, p->>age); free(p->name); free(p); }

파일명 ; 3.c

#include <stdio.h>
#include <stdlib.h>	//for systme()

#define Q_MAX	(5)

int queue[Q_MAX];
int front, rear;

void put(int data) {
	queue[rear] = data;
	rear++;
}

int get() {
	int t = queue[front];
	front++;
	return t;
}

void display(){
	int i;
	system("cls");

	printf("%*s\n", (rear+1)*4, "rear");
	printf("%*s\n", (rear+1)*4, " | ");

	for(i=0; i<Q_MAX; i++){
		printf("[%2d]", queue[i]);
	}
	printf("\n");

	printf("%*s\n", (front+1)*4, " | ");
	printf("%*s\n", (front+1)*4, "front");

	getchar();
}

void main() {
	int i;
	display();
	for(i=0;i<6;i++){
		put(i+1);
		display();
	}

	for(i=0;i<6;i++){
		get();
		display();
	}
}

큐가 비어 있는 경우 : front == rear

큐가 가득 차 있는 경우 : front == rear

->큐가 가득 차 있는 경우와 비어 있는 경우를 구분할 수가 없다.

//큐는 full과 empty를 구분하기 힘들다는 단점이 있다.
#include <stdio.h>
#include <stdlib.h>	//for systme()

#define Q_MAX	(5)

int queue[Q_MAX];
int front, rear;

void put(int data) {
	queue[rear] = data;
	
	//if(rear != Q_MAX)
	//	rear++;
	//else
	//	rear = 0;

	rear = (rear+1)% Q_MAX;
}

int get() {
	int t = queue[front];

	//if(front != Q_MAX)
	//	front++;
	//else
	//	front = 0;
	front = (front+1)% Q_MAX;
}

void display(){
	int i;
	system("cls");

	printf("%*s\n", (rear+1)*4, "rear");
	printf("%*s\n", (rear+1)*4, " | ");

	for(i=0; i<Q_MAX; i++){
		printf("[%2d]", queue[i]);
	}
	printf("\n");

	printf("%*s\n", (front+1)*4, " | ");
	printf("%*s\n", (front+1)*4, "front");

	getchar();
}

void main() {
	int i;
	display();
	for(i=0;i<6;i++){
		put(i+1);
		display();
	}

	for(i=0;i<6;i++){
		get();
		display();
	}
}

큐 구현!!

#include <stdio.h>
#include <stdlib.h>

#define Q_MAX	(5)

int queue[Q_MAX];
int front, rear;

void put(int data) {
	queue[rear] = data;


	rear = (rear+1)% Q_MAX;
}

int get() {
	int t = queue[front];

	front = (front+1)% Q_MAX;
}

int is_full() { return front == (rear+1) % Q_MAX; }
int is_empty() { return front == rear; }

void display(){
	int i;
	system("cls");

	printf("%*s\n", (rear+1)*4, "rear");
	printf("%*s\n", (rear+1)*4, " | ");

	for(i=0; i<Q_MAX; i++){
		printf("[%2d]", queue[i]);
	}
	printf("\n");

	printf("%*s\n", (front+1)*4, " | ");
	printf("%*s\n", (front+1)*4, "front");

	getchar();
}

void main() {
	int i;
	display();
	for(i=0;i<6;i++){
		if(!is_full())
			put(i+1);
		display();
	}

	for(i=0;i<6;i++){
		if(!is_empty())
			get();
		display();
	}
}

큐의 문제점 : 큐가 전역에 존재한다. 그러므로 하나밖에 마들 수가 없다. 2개 이상을 만들려면 배열이 필요하다.

a

a

a

a

a




0.c

1.c

2.c

3.c

4.c

android_dynamic_array.c

flexible_array.c



Posted by 밍쫑
,

Last In First Out의 구조를 가진 " Stack "에 대해서 배워보자!

ex) 식당 아주머니는 식판을 아래에서부터 쌓아올리지만, 식판을 가져가는 우리는 위에서부터 가져간다!

     지역 변수의 사용

- 수직적인 구조이다.

- push : 스택이라는 메모리에 데이터를 저장하는 인터페이스

- pop :  스택이라는 메모리부터 데이터를 꺼내오는 인터페이스











프로젝트명 : 20140212

파일명 : 1.c


// 스택(Stack) : LIFO(Last In First Out)
// ex)식당에서의 식판, 지역 변수의 사용

// push : 스택이라는 메모리에 데이터를 저장하는 인터페이스
// pop : 스택이라는 메모리부터 데이터를 꺼내오는 인터페이스

#include <stdio.h>

#define MAX_SIZE	(5)

int arr[MAX_SIZE];
int idx;	//초기화해주지 않아도, os가 자체적으로 0으로 초기화

//push의 경우 뭘로 return할지 굳이 표시하지 않아도 된다.
void push(int data) {
	arr[idx++] = data;
	/* arr[idx] = data;	//최초의 push의 경우 0부터 시작한다고 했으니
	++idx; */
}

int pop() {
	return arr[--idx];
	/*
	--idx;
	return arr[idx]; */
}

//참(0 이외의 수)과 거짓(0)을 나타내려면 int 타입을 쓴다.
int is_full() {
	return (idx == MAX_SIZE);
	/*
	if(idx == MAX_SIZE)
		return 1;
	else
		return 0;
	*/
}

int is_empty() {
	return (idx ==0);
	/*
	if(idx ==0)
		return 1;
	else
		return 0;
	*/
}

void main() {
	int i;

	for(i=0; i<10; i++) {
		if(!is_full())	//가득 차 있지 않아야 push가능
			push(i+1);	//1 2 3 4 5 6 7 8 9 10
	}

	for(i=0; i<10; i++) {
		if(!is_empty())
			printf("%d\n", pop());
	}
}



step 1. 가장 간단한 스택의 구현

#include <stdio.h>

#define MAX_SIZE	(5)

int arr[MAX_SIZE];
int idx;	//초기화해주지 않아도, os가 자체적으로 0으로 초기화

void push(int data) {arr[idx++] = data;}
int pop() {	return arr[--idx]; }
int is_full() { return (idx == MAX_SIZE); }
int is_empty() { return (idx ==0); }

void main() {
	int i;

	for(i=0; i<10; i++) {
		if(!is_full())	//가득 차 있지 않아야 push가능
			push(i+1);	//1 2 3 4 5 6 7 8 9 10
	}

	for(i=0; i<10; i++) {
		if(!is_empty())
			printf("%d\n", pop());
	}
}

step2. 하나 이상의 자료구조 구현

//step 2. 하나 이상의 자료구조 구현!
#include <stdio.h>

#define MAX_SIZE	(5)

// 데이터 추상화를 ADT(Abstract Data Type)
typedef struct __STACK {
	int arr[MAX_SIZE];
	int idx;
} STACK;

int arr[MAX_SIZE];
int idx;	//초기화해주지 않아도, os가 자체적으로 0으로 초기화

void push(int data, STACK *s) { s->arr[(s->idx)++] = data; }
int pop(STACK *s) {	return s->arr[--(s->idx)];}
int is_full(STACK *s) {	return (s->idx == MAX_SIZE);}
int is_empty(STACK *s) { return (s->idx ==0);}

void main() {
	int i;
	STACK s = {0, };	//이 데이터를 어떻게 처리할지는 라이브러리 개발하고 분석한 사람만 사용할 수 있다.
	//라이브러리 개발자가 저 스택을 초기화해줘야한다. -> step3

	for(i=0; i<10; i++) {
		if(!is_full(&s))	//가득 차 있지 않아야 push가능
			push(i+1, &s);	//1 2 3 4 5 6 7 8 9 10
	}

	for(i=0; i<10; i++) {
		if(!is_empty(&s))
			printf("%d\n", pop(&s));
	}
}

step3. 자료구조의 초기화를 위한 인터페이스 지급

// step 3 : 자료구조의 초기화를 위한 인터페이스 지급
// 스택의 크기가 고정되어있고,  사용자가 우너하는 시점에 메모리를 할당해야하기때문ㅇ ㅔ자료구조로...->step4
#include <stdio.h>

#define MAX_SIZE	(5)

// 데이터 추상화를 ADT(Abstract Data Type)
typedef struct __STACK {
	int arr[MAX_SIZE];
	int idx;	// =0;	//?
} STACK;

void init_stack(STACK *s) { s->idx = 0; }
void push(int data, STACK *s) { s->arr[(s->idx)++] = data; }
int pop(STACK *s) {	return s->arr[--(s->idx)];}
int is_full(STACK *s) {	return (s->idx == MAX_SIZE);}
int is_empty(STACK *s) { return (s->idx ==0);}

void main() {
	int i;
	STACK s;
	init_stack(&s);

	for(i=0; i<10; i++) {
		if(!is_full(&s))	//가득 차 있지 않아야 push가능
			push(i+1, &s);	//1 2 3 4 5 6 7 8 9 10
	}

	for(i=0; i<10; i++) {
		if(!is_empty(&s))
			printf("%d\n", pop(&s));
	}
}

step4. 자료 구조를 힙에 구현

// step 4.  자료구조를 힙에 구현
#include <stdio.h>
#include <stdlib.h>

typedef struct __STACK {
	#define MAX_SIZE	(5)
	int *arr;	//힙에 구현
	int idx;
} STACK;

void init_stack(STACK *s) { 
	s->arr = (int*)malloc(sizeof(int)*MAX_SIZE);
	s->idx = 0;
}
void push(int data, STACK *s) { s->arr[(s->idx)++] = data; }
int pop(STACK *s) {	return s->arr[--(s->idx)];}
int is_full(STACK *s) {	return (s->idx == MAX_SIZE);}
int is_empty(STACK *s) { return (s->idx ==0);}

void main() {
	int i;
	STACK s;
	init_stack(&s);

	for(i=0; i<10; i++) {
		if(!is_full(&s))	//가득 차 있지 않아야 push가능
			push(i+1, &s);	//1 2 3 4 5 6 7 8 9 10
	}

	for(i=0; i<10; i++) {
		if(!is_empty(&s))
			printf("%d\n", pop(&s));
	}
}

step5. 범용 타입에 대한 설계------------------------------

// step 5. 범용 타입에 대한 설계
#include <stdio.h>
#include <stdlib.h>

typedef struct __STACK {
	#define MAX_SIZE	(5)
	int *arr;	//모든 타입이 다 되게 해야 될 때는 void 포인터 타입으로
	int idx;
} STACK;

void init_stack(STACK *s) { 
	s->arr = (int*)malloc(sizeof(int)*MAX_SIZE);
	s->idx = 0;
}
void push(int data, STACK *s) { s->arr[(s->idx)++] = data; }
int pop(STACK *s) {	return s->arr[--(s->idx)];}
int is_full(STACK *s) {	return (s->idx == MAX_SIZE);}
int is_empty(STACK *s) { return (s->idx ==0);}

void main() {
	int i;
	STACK s;
	init_stack(&s);

	for(i=0; i<10; i++) {
		if(!is_full(&s))	//가득 차 있지 않아야 push가능
			push(i+1, &s);	//1 2 3 4 5 6 7 8 9 10
	}

	for(i=0; i<10; i++) {
		if(!is_empty(&s))
			printf("%d\n", pop(&s));
	}
}

------------------------------------


// 스택의 내부 자료구조를 리스트로 구현!
#include <stdlib.h>
#include <stdio.h>

typedef struct __NODE
{
	int data;
	struct __NODE *next;
} NODE;

typedef struct __STACK
{
	int idx;	// 스택에 저장된 위치
	int size;	// 스택의 크기
	struct __NODE *head;
} STACK;

void init_stack(STACK *s, int size)
{
	s->idx = 0;
	s->size = size;
	s->head = 0;
}

void push(int data, STACK *s) {
	NODE *cur;
	NODE *node = (NODE*)malloc(sizeof(NODE));
	node->data = data;
	node->next = 0;

	// 리스트가 비어 있는 경우
	if(s->head ==0) {
		s->head = node;
		++(s->idx);
		return;
	}

	// 리스트가 비어 있지 않은 경우
	cur = s->head;
	while(cur->next)
		cur = cur->next;

	cur->next = node;
        ++(s->idx);

}



int pop(STACK *s)
{
	int data;
	NODE *prev = s->head;
	NODE *cur = s->head;

	while(cur->next)
	{
		prev = cur;
		cur = cur->next;
	}

	data = cur->data;
	prev->next = 0;
	--(s->idx);
	free(cur);

	return data;
}

int is_full(STACK *s) { return s->size == s->idx; }
int is_empty(STACK *s) { return s> idx == 0; }

void main()
{
	int i;

	STACK s;
	init_stack(&s, 3);

	for(i = 0; i < 4; i++)
	{
		if(!is_full(&s)) push(i+1, &s);
	}

	for(i = 0; i < 4; i++)
	{
		if(!is_empty(&s)) printf("%d\n", pop(&s));
	}
}

------------------

파일명 : 2.c


//비트셋(Bitset, Bitmap
// LED 제어 프로그램 - 메모리의 낭비가 일어나고있다.
#include <stdio.h>
#include <stdlib.h>


enum { LED0 = 0, LED1, LED2, LED3, LED4, LED5, LED6, LED7 };
enum { LED_OFF = 0, LED_ON = 1 };
void main()
{
	int i;
	char mmio[8] = {0, };

	// LED ON
	mmio[LED1] = LED_ON;
	mmio[LED3] = LED_ON;

	// LED CHECK
	for(i=0;i<8;i++){
		if(mmio[i] == LED_ON)
			printf("LED%d ON\n", i);
		else
			printf("LED%d OFF\n", i);
	}
	getchar(); system("cls");

	// LED OFF
	mmio[LED3] = LED_OFF;

	// LED CHECK
	for(i=0;i<8;i++){
		if(mmio[i] == LED_ON)
			printf("LED%d ON\n", i);
		else
			printf("LED%d OFF\n", i);
	}
}

위의 소스코드는 메모리의 낭비라는 문제점이 있다. 다음 소스코드는 그를 수정하였다.

// 문제점: 메모리의 낭비
#include <stdio.h>
#include <stdlib.h>

enum { LED0 = 0, LED1, LED2, LED3, LED4, LED5, LED6, LED7 };
enum { LED_OFF = 0, LED_ON = 1 };

// 비트 연산으로 변경해보세요!

// 시프트 연산자

// 데이터 << 이동할 비트 수
// 데이터 >>  이동할 비트 수

// LED 제어 프로그램 - 메모리의 낭비가 일어나고있다.

void main()
{
	int i;
	char mmio = 0;	// // char mmio[8] = { 0, };

	// LED ON
	mmio = mmio | (LED_ON << LED1);	// 0000 0000 mmio = 0
									// 0000 0010 LED_ON	<< LED1
									// --------- |(OR)
									// 0000 0010
	
	mmio |= LED_ON >> LED3;			// 복합 대입 연산자의 사용
	// 규칙 1. 특정 비트를 설정하려면 OR 연산자를 사용해야 한다!


	// 0000 1010
	// 0000 0010	// 마스크 비트
	// --------- &
	// 0000 0010

	// LED CHECK
	for(i=0; i<8; i++)
	{
		if(mmio & (LED_ON << i))	// 0000 1010 & 1 << i
			printf("LED%d ON\n", i);
		else
			printf("LED%d OFF\n", i);
	}
	// 규칙 2. 특정 비트를 검사하려면 &연산자를 사용해야 한다.

	getchar(); system("cls");

	// LED OFF
	//mmio[LED3] = LED_OFF;	// 0000 1010
							// 1111 0111	~(LED_ON << LED3)
							// --------- &
							// 0000 0010
	mmio &= ~(LED_ON << LED3); //비트를 끈거다.

	// 규칙 3. 특정 비트를 초기화하려면 &연산자와 비트 반전 연산자(~)
	// 를 사용해야 한다.

	// LED CHECK
	for(i=0; i<8; i++)
	{
		if(mmio & (LED_ON << i))
			printf("LED%d ON\n", i);
		else
			printf("LED%d OFF\n", i);
	}
}

c

#include <stdio.h>
#include <stdlib.h>

#define BIT_SET(i , x)  ((x[i/32]) |= (1>>(i%32)))
#define BIT_ISSET(i , x) ((x[i/32]) & (i >>(>i%32)))
#define BIT_CLR(i , x)  ((x[[i/32]) &= ~(i <>>(i%32)))

enum { LED0 = 0, LED1, LED2, LED3, LED4, LED5, LED6, LED7 };
enum { LED_OFF = 0, LED_ON = 1 };

// 비트 연산으로 변경해보세요!

// 시프트 연산자

// 데이터 << 이동할 비트 수
// 데이터 >> 이동할 비트 수

void main()
{
	int i;
	//char mmio = 0;	// 32비트 -> 128비트
	int mmio[32] = {0,};
	// LED ON

	BIT_SET(LED1, mmio);
	BIT_SET(1000, mmio);
	//mmio = mmio | (LED_ON <<LED1);	// 0000 0000 mmio = 0
	// 0000 0010 LED_ON	<< LED1
	// --------- |(OR)
	// 0000 0010

	// 복합 대입 연산자의 사용



	for (i = 0; i<1024; i++)
	{
		if (BIT_ISSET(i, mmio))	// 0000 1010 & 1 << i
			printf("LED%d ON\n", i);
		else
			printf("LED%d OFF\n", i);
	}

	getchar(); system("cls");


	mmio &= ~(LED_ON << LED3);


	// LED CHECK
	for (i = 0; i<128; i++)
	{
		if (BIT_CLR(i, mmio))
			printf("LED%d ON\n", i);
		else
			printf("LED%d OFF\n", i);
	}
}

e

f

파일명 : 3.c

//Dynamic Array
#include <stdio.h>

#define ARR_SIZE(x)	(sizeof(arr)/sizeof(*arr))

int sum_arr(int arr[]) {
	int i, sum = 0;
	for(i=0;i<ARR_SIZE(arr);i++) {
		sum += arr[i];
	}
	return sum;
}

void main() {
	int i, sum = 0;
	int arr[] = {1,2,3,4,5,6,7,8,9,10};

	//for(i=0;i<ARR_SIZE(arr);i++)
	//	sum += arr[i];

	printf("sum=%d\n", sum_arr(arr));
}

a

//이 소스코드의 단점 : 배열에 있는 컨텐츠를 저장하는데, 저장되는 타입이 int이다. 
//근데 앞으로 double, float, char타입의 배열이 만들수도있는거다. 
//즉 모든 것이 성립하는 void 타입으로 바꿔야 할것이다.
//즉 int타입만 저장 가능하다
#include <stdio.h>
#include <stdlib.h>	//calloc 사용하기 위해서 선언한다.

typedef struct __Array {
	int capacity;
	int *content;
} Array;

Array* createArray(int capacity) {
	Array *arr = (Array*)calloc(1, sizeof(struct __Array));
	arr->content = (int*)calloc(capacity, sizeof(int));
	arr->capacity = capacity;

	return arr;
}

int setElement(Array *arr, int index, int data) {
	int capacity = arr->capacity;
	if(index <0 || index >=capacity)
		return -1;

	arr->content[index] = data;
	return 0;
}

int getElement(Array *arr, int index) {
	int capacity = arr->capacity;
	if(index <0 || index >capacity) {
		fprintf(stderr, "out of index");
		exit(-1);
	}

	return arr->content[index];
}

int getCapacity(Array *arr) { return arr->capacity; }

int sum_arr(Array *arr) {
	int i, sum = 0;
	for(i=0;i<getCapacity(arr);i++)
		sum +=getElement(arr, i);
	return sum;
}

void main() {
	int i;
	Array *arr = createArray(5);	//int arr[5];만든것과 동일

	for(i=0;i<getCapacity(arr);i++) {
		setElement(arr, i, i+1); //arr[i] = i+1;
	}

	printf("sum = %d\n", sum_arr(arr));

	/*for(i=0;i<getCapacity(arr);i++)
		printf("arr[%d] = %d\n", i, getElement(arr, i));
		printf("arr[%d] = %d\n", i, arr[i]);	//이건 안된다. 왜냐하면 arr은 배열이아니라 구조체니까 */
 }


// 문제점: 특정 타입만을 저장할 수 있음!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct __Array
{
	int capacity;
	void **content;
} Array;

Array* createArray(int capacity)
{
	Array *arr = (Array*)calloc(1, sizeof(struct __Array));
	arr->content = (void**)calloc(capacity, sizeof(void*));
	arr->capacity = capacity;

	return arr;
}

void* setElement(Array *arr, int index, void *pointer)
{
	void *old;
	int capacity = arr->capacity;
	if(index < 0 || index>= capacity)
	{
		fprintf(stderr, "out of index");
		exit(-1);
	}


	old = arr->content[index];	// backup
	arr->content[index] = pointer;
	return old;
}

void* getElement(Array *arr, int index)
{
	int capacity = arr->capacity;
	if(index < 0 || index > capacity)
	{
		fprintf(stderr, "out of index");
		exit(-1);
	}

	return arr->content[index];
}

int getCapacity(Array *arr) { return arr->capacity; }

typedef struct
{
	char name[32];
	int  age;
} PERSON;


void main()
{
	int i;
	PERSON *p;
	Array *arr = createArray(5);	// int arr[5];
									// int[] arr = new int[5];
	for(i = 0; i < getCapacity(arr); i++)
	{
		p = (PERSON*)malloc(sizeof(PERSON));
		strcpy(p->name, "kkk");
		p->age = i+1;

		setElement(arr, i, p); // arr[i] = i+1;
	}

	for(i = 0; i < getCapacity(arr); i++)
	{
		p = (PERSON*)getElement(arr, i);
		printf("arr[%d] = %s, %d\n", i, p->name, p->age);
	}


	// printf("sum = %d\n", sum_arr(arr));

	//for(i = 0; i< getCapacity(arr); i++)
	//	printf("arr[%d] = %d\n", i, getElement(arr, i));	// printf("arr[%d] = %d\n", i, arr[i]);
}

// append 기능 추가
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct __Array
{
	int capacity;
	int size;	//배열의 현재 크기
	void **content;

} Array;

Array* createArray(int capacity)
{
	Array *arr = (Array*)calloc(1, sizeof(struct __Array));
	arr->content = (void**)calloc(capacity, sizeof(void*));
	arr->capacity = capacity;

	return arr;
}

void* setElement(Array *arr, int index, void *pointer)
{
	void *old;
	int capacity = arr->capacity;
	if(index < 0 || index >= capacity)
	{
		fprintf(stderr, "out of index");
		exit(-1);
	}


	old = arr->content[index];	// backup
	arr->content[index] = pointer;
	return old;
}

int addElement(Array *arr, void *pointer) {
	int size = arr->size;
	int capacity = arr->capacity;

	if(size == capacity)
		return -1;

	arr->content[size] = pointer;
	arr->size++;

	return 0;
}

void* getElement(Array *arr, int index)
{
	int capacity = arr->capacity;
	if(index < 0 || index > capacity)
	{
		fprintf(stderr, "out of index");
		exit(-1);
	}

	return arr->content[index];
}

int getCapacity(Array *arr) { return arr->capacity; }
int getSize(Array *arr) {return arr->size; }

typedef struct
{
	char name[32];
	int  age;
} PERSON;

void display(Array *arr){
	PERSON *p;
	int i;

	system("cls");
	for(i=0;i<getSize(arr);i++){
		p = (PERSON*)getElement(arr, i);
		printf("arr[%d] = %s, %d\n", i, p->name, p->age);
	}
	getchar();
}

void main()
{
	int i;
	PERSON *p;
	Array *arr = createArray(5);

	display(arr);
	for(i = 0; i < getCapacity(arr); i++)
	{
		p = (PERSON*)malloc(sizeof(PERSON));
		strcpy(p->name, "kkk");
		p->age = i+1;

		addElement(arr, p);

		display(arr);
	}

	for(i = 0; i < getCapacity(arr); i++)
	{
		p = (PERSON*)getElement(arr, i);
		printf("arr[%d] = %s, %d\n", i, p->name, p->age);
	}
}



1.c

2.c

3.c



Posted by 밍쫑
,

이 날은 아이디어 생각하고 수강신청 도와주려다가 밤을 새는 바람에....많이 졸아서 필기가 영 부족하다 ㅠㅠ..

그래서 대신 강사님의 소스 파일을 공유하고자 합니다.



1일차에 이어서 동일하게 프로젝트를 생성합니다.


프로젝트명 : 20140211


1일차 복습하고 시작합니다.

파일명 : 1.c



파일명 : 2.c

// void 포인터
#include <stdio.h>

void swap(int *a, int *b) {
	int t = *a;
	*a = *b;
	*b = t;
}

void swap(int *a, int *b) {
	short t = *a;
	*a = *b;
	*b = t;
}

void swap(int *a, int *b) {
	char t = *a;
	*a = *b;
	*b = t;
}

void main() {
	int a = 30, b = 1000;
	swap(&a, &b);
	printf("a = %d, b = %d\n", a, b);
}

c언어에서는 동일한 이름의 함수이름들을 전부 swap이 _swap으로 바뀐다.


그래서 swap_xx함수 이름을 바꿔준다. -> swap_int

a

// void 포인터
#include <stdio.h>

void swap_int(int *a, int *b) {
	int t = *a;
	*a = *b;
	*b = t;
}

void main() {
	int a = 30, b = 1000;
	swap(&a, &b);
	printf("a = %d, b = %d\n", a, b);
}

전처리 기능은 문자열을 단순히 치환만 하기 때문에 .....

// void 포인터
#include <stdio.h>

#define SWAP(x,y,T) do { 
T t = a; 
a - b; 
b= t; 
} while(0)

void main() {
	int a = 30, b = 1000;
	//swap(&a, &b);
	SWAP(a, b, int);
	printf("a = %d, b = %d\n", a, b);
}

하나의 함수를 여러 타입을 핸들링하고 싶은 것의 문제이다..!

함수가 어떤 타입이 되든지 간에 모두 SWAP을 하려면 중간에 있는 임시 변수를 char로 한 바이트를 주고

아래 소스 코드는 타임에 의존적이지 않는 generic swap을 만든것이다.


#include <stdio.h>

/*#define SWAP(x,y,T) do { 
T t = a; 
a - b; 
b= t; 
} while(0) */
void swap(void *a, char *b, int size) {
	char t;
	char *aa = (char*)a;
	char (bb = (char*)b;
	int i;

	for(i=0;i


파일명 : 3.c






파일명 : 4.c









알아둡시다!!

구조체와 포인터


구조체 포인터 연산자: (*)., / ->

// 자기 참조 구조체 : 자기 자신의 타입에 대한 포인터


파일명 : 5.c



메모리를 보통 노드라고 한다.

리스트 자료구조 : 데이터를 저장하기 위한 메모리 -> 노드(node)

본인의 마지막 노드를 터미널이라고 한다. 종료 노드와 시작 노드를 구분하기 위해서 마지막 노드에 null을 넣어 놓는다.

끝을 tail이라고 한다.

리스트 자료구조 구현 방법은 여러개 있다.


파일명 : 6.c






한 방향으로 연결된 노드의 경우!

만약 3000개가 연결되었다.. 근데 찾고자하는게 마지막에 있다면??? 최악이지 않은가...

그래서 배울게 바로!! reverse() - PPT 13p : 기존의 display()는 head부터 시작한다. 따라서 tail부터 시작하는 reverse용 display를 따로 만들어야 된다.

void reverse(NODE *head, NODE *tail){
	NODE *prev = head;
	NODE *curr = head->next;
	NODE *next;

	while(cur != tail) {
		next = curr->next;
		curr->next = prev;
		prev = curr;
		curr = next;
	}

	curr->next = prev;
}

a

문제점이 있다면, 어떤게 reverse로 보고 어떤것을 reverse_display로 봐야 할지 모른다. 근데 별 쓸모없는 기능이다.

그리고 이 함수는 역방향(reverse)에 대한 순방향 복원이 안된다. 오버헤드가 크다!!

#include <stdio.h>
#include <stdlib.h>

typedef struct __NODE
{
	int data;
	struct __NODE *next;
	struct __NODE *prev;	//double linked list!
} NODE;

void init_list(NODE *head)
{
	head->next = head;
	head->prev = head;
}

//PPT 17p
void insert_front(NODE *head, NODE *node)
{
	node->next = head->next;
	head->next = node;

	node->prev = node->next->prev;
	node->next->prev = node;
}

void insert_end(NODE *head, NODE *node)
{
	NODE *cur = head;

	while(cur->next != head)
		cur = cur->next;

	node->next = cur->next;
	cur->next = node;
}

void reverse(NODE *head)
{
	NODE *prev = head;
	NODE *curr = head->next;
	NODE *next;

	while(curr != head)
	{
		next = curr->next;
		curr->next = prev;
		prev = curr;
		curr = next;
	}

	curr->next = prev;
}

void display(NODE *head)
{
	NODE *node;

	system("cls");
	printf("\n[head]->");
	for(node = head->next; node != head; node = node->next)
		printf("[%d]->", node->data);
	printf("[head]");
	getchar();
}



void main()
{
	int i;

	NODE head;

	NODE arr[5];

	init_list(&head);

	display(&head);
	for(i = 0; i < 5; i++)
	{
		arr[i].data = i+1;
		//insert_front(&head, &arr[i]);
		insert_end(&head, &arr[i]);
		display(&head);
	}

	reverse(&head);
	display(&head);

	reverse(&head);
	display(&head);
}

// 역방향에 대한 순방향 복원이 안된다!

양방향 노드를 이용하면 라이브러리의 최고 동력을 살릴 수 있지만, 메모리는 2배 희생이 필요하다.

이 양방향 노드를 더블 링크라고 한다.




1.c


2.c


3.c


4.c


5.c


6.c







Posted by 밍쫑
,