2013. 11. 14. 21:07 C언어

c++ 공부 요점정리 4





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// =====================================================
// 11 구조체의 유용성
// =====================================================
// 구조체의 유용성
// : 관련있는 데이터를 하나의 자료형으로 묶을 수 있다.
//   따라서 프로그램의 구현 및 관리가 용이해짐
//   함께 움직이는 데이터들을 묶어주는 효과

// c언어는
// : 모든 사용자 정의 자료형을
//   기본 자료형으로 인식해 주지 않는다.
// ex
struct person{
	int age;
	char name[10];
}

int main(void)
{
	int a = 10;
	person p; 	// 에러발생
				// struct person p; 로 선언해야함
				// c에서는 사용자 자료형을 기본자료형
				// 처럼 선언할 수 없다.
}
// c++은 기본자료형이나 사용자 정의 자료형의 차이가 없다.
// 즉, person p;로 선언가능함




// =====================================================
// 12 함수에 넣으면 좋은 구조체
// =====================================================
// c에서는 구조체에 함수를 정의할 수 없지만
// c++에서는 구조체에 함수를 정의 할 수 있다.
// ex
#include <iostream>
using std::cout;
using std::endl;

struct Account {
	char accID[20];    // 구조체의 멤버 변수
	char secID[20];    // 구조체의 멤버 변수
	char name[20];     // 구조체의 멤버 변수
	int balance;       // 구조체의 멤버 변수

	void Deposit(int money){ // 구조체의 멤버 함수
		balance+=money; // 구조체 멤버 함수는 
						// 같은 구조체의 멤버 변수를
						// 참조할 수 있다.
						// 같은 이름으로 구조체 멤버 함수안에
						// 지역변수를 선언할 경우
						// 같은 이름의 구조체 멤버 변수는
						// 가려지게 되어 사용할 수 없다
						// 
	}
	void Withdraw(int money){ // 구조체의 멤버 함수
		balance-=money;
	}

};

int main(void)
{
	Account yoon={"1234", "2321", "yoon", 1000};

	yoon.Deposit(100); // 구조체의 변수에 접근하기 위해
						// 접근 연산자 "."을 사용하는 것처럼
						// 구조체의 함수에 접근하기 위해서도
						// 접근 연산자 "."을 사용한다
	cout<<"잔    액 : "<<yoon.balance<<endl;

	yoon.Withdraw(200);
	cout<<"잔    액 : "<<yoon.balance<<endl;

	return 0;
}




// =====================================================
// 13 함수에 넣으면 좋은 구조체
// =====================================================
// 클래스 : 멤버 변수 + 멤버 함수
//          클래스를 이용해 변수를 선언할 경우
//          그 변수는 객체라고 부른다
//          변수가 아니라 객체(object 완전한 대상체)


// c에서는
//
// 기본 자료형   : int, double, ...
// 사용자 자료형 : 구조체, 공용체, enum, ...
//               구조체 : 기본자료형과 기존에 만들어진
//                        사용자 자료형을 이용해만듬,
//                        변수만을 이용해서

// c++에서는
//
// 기본 자료형   : int, double, ...
// 사용자 자료형 : 클래스
//                 클래스 : 변수와 함수를 이용해 만듬
//
// c++에서 구조체는 클래스에 포함된다.
// 즉, 구조체는 클래스의 하위개념
// 특정 구조체 안의 함수를 호출하는 행위를 
// mesage passing이라고 부른다.

// 변수와 함수를 하나로 묶어서 하나의 자료형을 만드는데 있어서
// struct라는 자료형을 이용할 수도 있고
// class라는 자료형을 이용해 만들 수도 있다.
// 두가지 방법은 거의 일치하나 딱 한가지 차이가 있다
// 
//

// 왜 클래스가 나타났는가
// 왜 변수와 함수를 묶어서 자료형을 선언해야하는가
// : 

// 왜 변수가 아니라 객체라 부르는가
// : 


// =====================================================
// 14 구조체가 아니라 클래스
// =====================================================

// =====================================================
// 15 클래스와 객체
// =====================================================

// =====================================================
// 16 클래스의 내부 접근과 외부 접근
// =====================================================







'C언어' 카테고리의 다른 글

c++ 공부 요점 정리 6  (0) 2013.11.16
c++ 공부 요점정리 5  (0) 2013.11.15
c++ 공부 요점 정리 3  (0) 2013.11.13
c++ 공부 요점 정리 2  (0) 2013.11.11
리눅스(우분투 10.10) 공유 메모리 예제 2  (0) 2013.11.07
Posted by 뮹실이

2013. 11. 13. 21:25 C언어

c++ 공부 요점 정리 3






1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
// =====================================================
// 8 레퍼런스의 이해
// =====================================================
// 레퍼런스와 변수는 
// 생성되는 방법에 있어서만 차이를 보일 뿐
// 만들어지고 나면 완전히 같은 것

// 레퍼런스의 제약
// 1 이름이 존재하지 않는 대상을 레퍼런스 할 수 없다
int &ref2 = 10; // 상수가 올수 없으므로 에러
// 2 선언과 동시에 반드시 초기화 되어야 한다.
int &ref1; // 초기화 되지 않았으므로 에러


// =====================================================
// 9 레퍼런스 함수
// =====================================================
// 포인터를 이용한 call-by-reference
// : 함수 외부에 선언된 변수의 접근이 가능
// 포인터 연산에 의해서 가능한 것임
// 포인터 연산의 위험성 존재
// ex
void swap(int *a, int *b)
{
	int temp = *a;
	a++; // 실수로 입력하게 되면 치명적 오류 발생가능
		// 4바이트가 증가되어 원래 a가 가리키던 메모리
		//에서 4바이트를 건너뛰게 되어 어딘지 모르는
		// 곳의 메모리 값을 참조하게 되어 위험
	*a = *b;
	*b = temp;
}

// 레퍼런스를 이용한 call-by-reference
// : 함수 외부에 선언된 변수의 접근이 가능
// 포인터 연산을 할 필요가 없으므로 보다 안정적임
// 함수의 호출형태를 구분하기 어렵다.
// ex
int main(void)
{
	int val1 = 10;
	int val2 = 20;
	
	swap(val1, val2); // 이것만 봐서는 call-by-value인지
					// call-by-reference인지 알수없다
					// swap함수의 매개변수를 확인해봐야
					// 알수 있다.
	return 0;
}

void swap(int &a, int &b)
{
	int temp = a;
	a = b;
	b = temp;
}
// 위 예제는 포인터를 사용하지 않는다.
// 포인터를 사용할 때는 오류를 발생시킬 위험성이 높음
// 따라서 레퍼런스를 이용해 구현하면 보다 안정적임

// call-by-value
// : 함수 호출 시 인자 전달 과정에서 발생
// 데이터를 복사하는 과정에서 발생
// ex
void main(void)
{
	showdata(man);
}
void showdata(person p)
{
// ...
}

// 대신할 수 있는 call-by-reference
// : 전달되는 인자를 레퍼런스로 받으면, 데이터의
// 복사 연산이 필요없다.
// 원본 데이터가 변경될수 있으므로, 
// const로 선언하면 원본 변경 방지 가
// ex
void showdata(const person &p)
{
// ...
}


// =====================================================
// 10 레퍼런스를 리턴하는 함수
// =====================================================
//
// ex
//
#include <iostream>
using std::cout;
using std::endl;

// 레퍼런스 타입으로 리턴
int& increment(int &val)
{
	val++; // 지역변수 val
	return val;
}// 이 함수 호출이 끝나면 val변수는 사라짐

int main(void)
{
	int n=10;
	int &ref=increment(n);
	// increment가 인수로 리턴하면 상수로 리턴하므로
	// 에러 발생
	// 레퍼런스는 상수에 이름을 붙일 수 없으므로.

	cout<<"n  : "<<n<<endl;
	cout<<"ref: "<<ref<<endl;

	return 0;
}

//
// ex 2
//
#include <iostream>
using std::cout;
using std::endl;

int& function()
{
	int val=10;
	return val;
}

int main(void)
{
	int &ref=function();
	cout<<ref<<endl; // 에러 발생가능
					// 권장하지 않음
					// 지역변수로 선언된 변수를 
					// 리턴하므로..........??

	return 0;
}

// new와 delete 연산자의 기능
//
// c에서는
//
// int 형 변수를 힙에다가 할당해주고
// 그 포인터를 리턴받는 형태
// malloc은 인자로 전달되는 인자의 크기만을
// 할당하고 
// 어떤식으로 사용될지 모르니 void 포인터 타입으로 
// 반환된다.
// 따라서 크기를 직접 계산해서 인자로 주고
// 리턴되는 포인터도 용도에 맞게 형변환해서
// 사용해야함
// 할당한 메모리 공간을 해제할때는 free함수 사용
int *val = (int *)malloc(sizeof(int));
free(val);
// 배열 동적할당
// 
int *arr = (int *)malloc(sizeof(int)* size);
free(arr);
//
// c++에서는
//
// new와 delete가 자동으로 할당해줌
// 인자에 크기계산과 포인터 형변환을 해줄 필요없음
// 힙에다가 int형 데이터 저장하기 위한 메모리공간 할당하라
// 4바이트 메모리 공간을 힙에다가 할당하고 
// 알아서 인트형 포인터로 반환해줌
// 할당한 메모리 공간을 해제할때는 
// 할당한 메모리 공간이 int인 경우에는 
// delete 사용하고
// 할당한 메모리 공간이 배열인 경우에는
// delete에 인덱스연산자를 붙여 arr이 가리키는 공간이
// 배열임을 명시적으로 선언해줘야함
int *val = new int;
delete val;
// 배열 동적할당
// 길이가 size인 인트형 배열을 힙에다가 할당하라
// 리턴될때 자동으로 인트형 포인터로 리턴됨
int *arr = new int[size];
delete []arr;

// 메모리 공간 할당에 실패할 경우
// NULL 포인터를 리턴한다.
// ex
int *arr = new int[size];
if (arr == NULL)
{
	cout<<"에러"<<endl;
	return -1;
}
// 이런식의 메모리 할당 실패 검사는 비효율적이므로
// 다음과 같은 방식으로 사용 추천
#include <iostream>

//#define DEBUG 1;
#define DEBUG  0;

using std::cin;
using std::cout;
using std::endl;

int main(void)
{
	int size;
	cout<<"할당하고자 하는 배열의 크기: ";
	cin>>size;

	int* arr=new int[size];  // 배열의 동적 할당.

#if DEBUG==1 
	cout<<"디버그 모드 입니다"<<endl;
	if(arr==NULL)
	{
		cout<<"메모리 할당 실패"<<endl;
		return -1; //프로그램 종료.
	}
#endif

	for(int i=0; i<size; i++)
		arr[i]=i+10;

	for(int j=0; j<size; j++)
		cout<<"arr["<<j<<"]= "<<arr[j]<<endl;

    delete []arr;  // 할당된 메모리 소멸.

	return 0;
}







'C언어' 카테고리의 다른 글

c++ 공부 요점정리 5  (0) 2013.11.15
c++ 공부 요점정리 4  (0) 2013.11.14
c++ 공부 요점 정리 2  (0) 2013.11.11
리눅스(우분투 10.10) 공유 메모리 예제 2  (0) 2013.11.07
리눅스(우분투 10.10) 공유 메모리 예제  (0) 2013.11.07
Posted by 뮹실이

2013. 11. 11. 20:20 C언어

c++ 공부 요점 정리 2






1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// =====================================================
// 5 편의를 위한 using 선언
// =====================================================

// A_COM이라는 이름공간안에 정의된 "func"함수를 콜
// 할때는 "A_COM::func" 대신 "func"으로만 사용
using A_COM::func;

// A_COM이라는 이름공간안에 정의된 변수 및 함수 전체를
// 그냥 사용하겠다
using namespace A_COM;

// 범위 지정 연산자 기반 전역변수 접근
int val = 100;

int main(void)
{
	int val = 100;
	::val += 1; // 지역변수는 가려지게됨
				// 이런식으로 전역변수에 접근 가능
	return 0;
}



// =====================================================
// 6 들어가기에 앞서서
// =====================================================

// const 키워드의 의미
// : 변수를 상수화 시킴
// 데이터 상수화, n이 가리키는 메모리 공간의 값을 상수화
// n이라는 포인터를 이용해 값을 변경하는 것을 막는것
const int* n; 
// 포인터 상수화, n이 가리키는 곳을 바꿀수 없다
int* const n;
// n이 가리키는 곳과 가리키는 곳의 값을 바꿀수 없다
const int* const n;

// ex
// 운영체제는 프로그램이 실행되면 메모리를 할당
// 메모리를 효율적으로 사용하기 위해 용도에 맞게 나눔 
// 데이터 영역, 힙(heap) 영역, 스택(stack) 영역
// 데이터 영역 : 프로그램 시작과 동시에 할당되어
//				프로그램 종료되어야지만 할당해제되는 영역
//				전역변수, static 변수가 여기에 해당됨
//				static 변수는 프로그램 시작과 동시에 
//				데이터 영역에 할당되고 static 이 선언된
//				함수가 콜되면 static 변수가 초기화 되는것임
// 힙(heap) 영역 : 런타임의 크기가 결정되는 변수나
//				 배열과 같은 것을 저장하기 위한 공간
//				and 프로그래머가 할당할 수 있음(관리)
//				(malloc, free함수를 이용해서)
// 스택(stack) 영역 : 컴파일 타임의 크기가 결정될수 있는
//					것들을 메모리 공간에 올리기 위한 공간
//					지역변수, 매개변수가 여기에 해당
void func(int);

// main 함수에서 요구되는 메모리는 int 형인 4바이트가 필요
// 즉 컴파일시에 요구되는 메모리 공간의 크기 결정가능
void main(void)
{
	int size; // 이렇게 일반적으로 선언하면
			  // stack에 올리라는 의미가 됨
	cin>>size;
	func(size);
}
// 컴파일시에 func에서 요구되는 메모리 공간의 크기를 
// 결정할 수 없음
// i 값은 입력에 따라 다르므로
// 컴파일시에 알수 없고 런타임시 알수 있음
// 즉 힙영역에 올라감
void func(int i)
{
	int array[i]; // 이렇게 일반적으로 선언하면
				  // stack에 올리라는 의미가 됨
				  // 그러나 지금과 같은 상황에서는 
				  // 스택에 올릴수 없다
				// 그래서 힙영역에 올리기 위해서
				// malloc, free 함수를 사용한다
				// malloc은 힙영역에 할당하기 위해 사용됨
				// free는 malloc으로 할당한 메모리를 해지
				// 하기 위해서 사용되는 함수
}
// end of ex




// =====================================================
// 7 자료형 bool
// =====================================================
// 자료형 bool : 기본 자료형
//				true(참), false(거짓) 중의 하나의 값을 지님
//				int 형으로 형 변환시 1 or 0이 됨

// 레퍼런스(reference)의 이해
// 이름을 지니는 대상에 별명을 붙여주는 행위
//
// 변수 : 메모리 공간에 붙은 이름
// 하나의 메모리 공간에 하나의 변수만 붙여줄수 있었지만
// c++에서는 하나의 메모리 공간에 둘이상의 변수를 붙여
// 줄수 있다. 이것이 레퍼런스의 기본 문법적 요소이다.

// & : c에서는 주소값을 얻기 위한 용도로 사용됨
//		c++에서는 레퍼런스 선언을 위한 용도로도 
//		사용될수 있음

// p를 포인터로 선언
int *p;
// p라는 포인터가 가리키는 값을 참조하겠다는 의미
*p;

// 레퍼런스 선언
int &p;
// p의 주소값을 반환하라는 의미
&p;

// int 형 변수를 참조할 수 있는
// ref를 레퍼런스로 선언하겠다.
// 즉 val가리키는 공간에 ref라는 이름을
// 하나 더 붙여라는 의미
int val = 10;
int &ref = val;

int *pVal = &val; // 주소값을 얻기 위해 & 연산자 사용
int &rVal = val; // 레퍼런스 선언을 위해 & 연산자 사용
				// val이 가리키는 값과 rVal이 가리키는 
				// 값은 같음

// b라는 이름을 가진 메모리에 c라는 이름도 부여해
// 한 메모리공간에 b, c의 이름을 가지게됨
char b;
char &c = b;








'C언어' 카테고리의 다른 글

c++ 공부 요점정리 4  (0) 2013.11.14
c++ 공부 요점 정리 3  (0) 2013.11.13
리눅스(우분투 10.10) 공유 메모리 예제 2  (0) 2013.11.07
리눅스(우분투 10.10) 공유 메모리 예제  (0) 2013.11.07
bind 에러 해결 방법  (0) 2013.10.31
Posted by 뮹실이





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
리눅스(우분투 10.10) 공유 메모리 예제 2

// 독립 프로세스가 공유메모리를 사용하는 예제


//==============================================================================
// 서버 코드
//==============================================================================
#include <stdio.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <string.h>
#include <unistd.h>
#include <time.h>

// 공유 메모리 key 정의
// 다른 프로세스와 공유메모리를 사용하기 위해 같은 메모리 key를 사용해야함
#define SHARED_MEMORY_KEY 1005 
#define MEMORY_SIZE 200

// 플래그에 대한 상수
// 서버와 클라이언트의 동기화를 위해 정의
// 클라이언트가 서버에 데이터를 보냈을 때 
// 서버가 데이터가 왔다는것을 알수있는 방법이 필요한데
// 여러가지 방법이 있지만 
// 여기서는 메모리의 첫번째 바이트를 동기화 플래그로 사용하여 해결
// 즉 메모리 200byte 중 첫번째 1바이트는 동기화 플래그 byte,
// 나머지는 데이터 199byte
#define READ_CLIENT_FLAG 0
#define READ_SERVER_FLAG 1
#define PRINT_CLIENT_FLAG 2

int main()
{
    int shmid; // 공유 메모리 아이디를 저장할 변수
    char *buffer; // 공유 메모리 전체를 가리킬 포인터 변수
    char *string; // 문자열 부분을 가리킬 포인터 변수

    // make space that shared-memory
	// 공유 메모리 생성
	// 서버에서 공유 메모리를 생성하므로
	// shmget 함수에서 IPC_CREAT 옵션을 사용해
	// 공유메모리가 없는 경우 생성하도록 설정
    shmid = shmget((key_t)SHARED_MEMORY_KEY, (size_t)MEMORY_SIZE, 0777 | IPC_CREAT);
    if(shmid == -1)
    {
            perror("shmat failed : ");
            exit(0);
    }

    // attach shared memory
	// buffer 포인터 변수에 공유메모리를 가리키도록 하고
	// 문자열은 사용할 메모리 구조에서 1바이트 이후에 부분이므로
	// string = buffer + 1 의 지점을 가리키게 됨
    buffer = (char *)shmat(shmid, NULL, 0);
    if(buffer == (char *)-1){
        perror("shmat failed : ");
        exit(0);
    }
    string = buffer + 1;

	// buffer[0]의 위치는 동기화 플래그를 나타내므로
	// 클라이언트가 사용자의 정보를 읽는 READ_CLIENT_FLAG로 셋팅
    buffer[0] = READ_CLIENT_FLAG;

	// 클라이언트의 메시지(데이터)를 기다리는 부분
	// 동기화 플래그(buffer[0])가 READ_CLIENT_FLAG에서 
	// READ_SERVER_FLAG로 값이 변할 때까지 무한루프를 돌며 대기
	// 메시지가 오면 1.화면에 출력하고
	// 2.읽은 공유 메모리 메시지에 "by server"를 붙이고
	// 3.동기화 플래그를 PRINT_CLIENT_FLAG로 바꿔
	// 클라이언트가 메시지를 화면에 출력하도록 함 
	//
    while(1)
    {
        if(buffer[0] == READ_SERVER_FLAG)
        {
            puts(string);
            strcat(string, " by server");
            buffer[0] = PRINT_CLIENT_FLAG;
        }
        sleep(1);
    }
}



//==============================================================================
// 클라이언트 코드
//==============================================================================
#include <stdio.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <string.h>
#include <unistd.h>
#include <time.h>

// 각 상수를 서버와 동일하게 설정해야함
#define SHARED_MEMORY_KEY 1005

#define READ_CLIENT_FLAG 0
#define READ_SERVER_FLAG 1
#define PRINT_CLIENT_FLAG 2

int main()
{
    int shmid;
    char *buffer;
    char *string;

    // make space that shared-memory
	// 서버와 다를 부분은 shmget 함수의 인자 부분
	// 이미 생성된 메모리에 접속하므로 shmget 세번째 인자에
	// 공유 메모리의 사이즈가 아닌 0을 입력
	// 네번째 인자 또한 같은 이유로 NULL 입력
	// NULL은 컴파일시 워닝 발생하므로 0으로 대체
    //shmid = shmget((key_t)SHARED_MEMORY_KEY, 0, NULL);
	shmid = shmget((key_t)SHARED_MEMORY_KEY, 0, 0);
    if(shmid == -1)
    {
            perror("shmat failed : ");
            exit(0);
    }

    // attach shared memory
    buffer = (char *)shmat(shmid, NULL, 0);
    if(buffer == (char *)-1){
        perror("shmat failed : ");
        exit(0);
    }

    buffer[0] = READ_CLIENT_FLAG;
    string = buffer  + 1;

	// 무한루프를 돌며
	// 동기화 플래그가 READ_CLIENT_FLAG 인 경우
	// 사용자의 입력을 받아 공유메모리 문자열 부분에 저장
	// 동기화 플래그가 PRINT_CLIENT_FLAG 인 경우
	// 서버가 변경한 공유메모리의 문자열을 화면에 출
    while(1)
    {
        if(buffer[0] == READ_CLIENT_FLAG)
        {
            printf("message : ");
            // gets 함수는 특정메모리에 정해지지 않은 사이즈를 넣기 때문에
			// 오버플로우 에러를 발생 시킬 소지가 있다
			// 문자열의 사이즈를 정할 수 있는 fgets 함수로 변경
			// fgets 함수 세번째 인자를 stdin으로 하면 키보드로 부터 입력을 받음
			//gets(string);
			fgets(string, 199, stdin);
			// 줄바꿈 문자(enter) 값을 없애기 위해 다음 줄 추가
			// fgets 함수는 gets 함수와 달리
			// 지정한 사이즈만큼 문자열을 읽기 때문에
			// 문자열에 리턴값이 포함되어 있다
			// 문자열 끝부분에 값을 '\0'으로 문장의 끝을 표시함
			string[strlen(string)-1] = '\0';

            buffer[0] = READ_SERVER_FLAG;
        }
        else if(buffer[0] == PRINT_CLIENT_FLAG)
        {
            puts(string);
            buffer[0] = READ_CLIENT_FLAG;
        }
        sleep(1);
    }
}








'C언어' 카테고리의 다른 글

c++ 공부 요점 정리 3  (0) 2013.11.13
c++ 공부 요점 정리 2  (0) 2013.11.11
리눅스(우분투 10.10) 공유 메모리 예제  (0) 2013.11.07
bind 에러 해결 방법  (0) 2013.10.31
다중 입출력 함수 select  (0) 2013.10.28
Posted by 뮹실이
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
리눅스(우분투 10.10) 공유 메모리 예제

// 부모, 자식 프로세스간 공유 메모리 사용 예제

// shmget() 함수로 공유메모리를 생성
// shmat() 함수로 공유메모리에 접근
// shmdt() 함수로 공유메모리와의 접속을 끊음
// shmctl() 함수로 공유메모리를 제어

#include <stdio.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <string.h>
#include <unistd.h>
#include <time.h>

// sys/shm.h에 공유메모리와 관련된 구조체와 함수들이 정의되어 있음
// 공유메모리를 shmid_ds 라는 구조체로 관리
// struct shmid_ds
// {
//     struct         ipc_perm shm_perm;    // 퍼미션
//     int            shm_segsz;            // 메모리 공간의 크기
//     time_t         shm_dtime;            // 마지막 attach 시간
//     time_t         shm_dtime;            // 마지막 detach 시간
//     time_t         shm_ctime;            // 마지막 변경 시간
//     unsigned short shm_cpid;             // 생성프로세스의 pid
//     unsigned short shm_lpid;             // 마지막으로 작동한 프로세스의 pid
//     short          shm_nattch;           // 현재 접근한 프로세스의 수
// };
// shm_perm   공유메모리는 여러 개의 프로세스가 동시접속 하므로
//            접근권한을 분명히 명시하여야 한다.
// shm_segsz  할당된 메모리 바이트의 크기
// shm_atime  가장 최근의 프로세스가 접근한 시간
// shm_dtime  가장 최근의 프로세스가 접속을 끊은 시간
// shm_ctime  마지막으로 이 구조체가 변경된 시간
// shm_cpid   이 구조체를 생성한 프로세스의 pid
// shm_lpid   마지막으로 작동을 수행한 프로세스의 pid
// shm_nattch 현재 접근되어 있는 프로세스의 수


#define SHARED_MEMORY_KEY 1234
#define INIT_VALUE 5 // 공유 메모리의 초기값
#define MAX_VALUE 10 // 공유 메모리의 최대값
#define MIN_VALUE 0  // 공유 메모리의 최소값
#define RAND_DISTANCE 5 // 프로세스가 쉴 시간
//                      // 즉, rand 함수의 범위를 지정하기위해
//
// 공유 메모리를 사용하기 위해서는 고유의 key 가 필요
// 공유 메모리를 생성할 때 특정한 key 값을 주어 생성하고
// 접근할 때에도 같은 key 값으로 접근 가능
// key 값은 공유 메모리를 구분하기 위해서도 필요

int main()
{
    int shmid; // 공유메모리의 id를 저장하기 위한 변수
    int pid;   // 자식 프로세스와 부모프로세스를 구분하기 위한 변수
    int *cal_num;
    int sleep_time=0;
    int status;
    int seed1, seed2; // 각 프로세스마다 rand() 함수의 시드값이 달라야 하기 때문에
					  // seed 변수를 두개로 선언

    srand(time(NULL));
    seed1 = rand();  // rand() 함수 초기화
    seed2 = rand();  // rand() 함수 초기화

    // make space that shared-memory
	// 공유 메모리 생성 부분
	//
	// int shmget(key_t key, int size, int shmfig)
	//
	// key :     Shared Memory를 접근하기 위한 Key값
	// size :    메모리의 최소 사이즈.
	//           새로운 메모리를 생성한다면 크기를 반드시 명시해야함
	//           이미 존재하는 메모리를 참조하는 것이라면, 0으로 명시
	//
	// shmfig :  공유 메모리의 접근 권한과, 생성방식을 명시하기 위해
	//           파일 권한과 동일하게 읽기, 쓰기 권한 지정 가능
	//           사용 가능한 생성 방식은 다음과 같다.
	//           
	//           IPC_CREAT : 생성하려는Key 값의 공유메모리가 없는 경우
	//                      새로운 공유 메모리를 만든다.
	//           IPC_EXCL : IPC_CREAT 와 같이 사용되며, 
	//                     공유메모리 공간이 이미 존재하는 경우
	//                      error 를 돌려주고, 메모리에 접근할 수 없게 됨
	//  
	// 반환 값 : 메모리 생성 성공하는 경우 공유메모리의 id 반환.
	//           메모리 생성 실패하는 경우 -1 반환.
	//           shmfig IPC_EXCL 인 경우, 메모리가 존재할 경우 error 반환.
	//
	// int 형의 사이즈만큼
	// 권한은 모두 접속가능하고, 
	// 만약 메모리가 생성되지 않은 경우 새로 생성하는 옵션 사용
	// 
    shmid = shmget((key_t)SHARED_MEMORY_KEY, sizeof(int), 0666 | IPC_CREAT);
    if(shmid == -1){
        perror("shmget failed : ");
        exit(0);
    }

	// 공유메모리 접속하는 부분
	//
	// void * shmat(int shmid, const void *shmaddr, int shmfig)
	//
	// int shmid :           shmget 함수를 이용해 얻은 공유메모리 ID
	//
	// const void *shmaddr : 메모리가 붙을 주소를 명시하기 위해 사용.
	//                       0을 사용하면 커널이 알아서 지정.
	//                       보통의 경우 0을 사용.
	//
	// int shmfig :          해당 공유메모리에 대하여 읽기전용 혹은
	//                       읽기/쓰기 모드를 지정 할 수 있다.
	//                       SHM_RDONLY 를 넘길 경우 읽기 전용으로 열고,
	//                       아무 값도 지정하지 않는 경우 
	//                       읽기/쓰기 가능 모드로 열게 된다
	//
	// 반환 값 :             성공한 경우 해당 메모리의 포인터 반환.
	//                       실패한 경우 -1 반환.
	//
	// 다음은 void 포인터 형의 메모리를 int 포인터 형으로 캐스팅
	//
    cal_num = (int *)shmat(shmid, NULL, 0);
    if(cal_num ==(int *)-1){
        perror("shmat failed : ");
        exit(0);
    }
    *cal_num = INIT_VALUE;

    // make child process
    pid = fork();

    //child process
	// 자식 프로세스가 동작하는 부분
	// rand 함수로 생성된 시간을 쉬었다가 공유메모리에 값을 1증가시킴
	// 프로세스가 끝나면 shmit 함수를 이용해 공유메모리와의 접속을 끊음
	//
	// int shmdt(const void* shmaddr)
	//
	// shmaddr : 공유메모리와의 연결을 끊을 Local 메모리의 포인터
	// 반환 값 : 성공할 경우 0 반환
	//           실패한 경우 -1 반환
	//
    if(pid == 0){
        srand(seed2);
        while(1){
            if((*cal_num) >= MAX_VALUE || (*cal_num)<= MIN_VALUE){
                break;
            }
            *cal_num = *cal_num + 1;
            printf("child : I'm %d sec sleep. plus 1. current value %d\n", sleep_time, *cal_num);
            sleep_time = (rand()%RAND_DISTANCE) +1;
            sleep(sleep_time);
        }
        if((*cal_num) >= MAX_VALUE){
            puts("child : I'm winner\n");
        }
        else{
            puts("child : I'm looser\n");
        }
        shmdt(cal_num);
    }
    // parent process
    // 부모 프로세스
    // 자식 프로세스와 다른점은 shmctl 함수를 사용해
    // 공유메모리를 제거
    // 
    // int shmctl(int shmid, int cmd, struct shmid_ds *buf)
    // 
    // shmid :   공유 메모리의 ID
    // cmd :     원하는 제어작업 명시.
    // 
    //           IPC_STAT : 공유메모리 공간에 관한 정보를
    //                      가져오기 위해 사용. 
    //                      정보는 buf 에 저장된다.
    // 
    //           IPC_SET : 공유메모리 공간에 대한 사용자 권한을
    //                     변경한다. 
    //                     사용자 권한을 변경하기 위해서는
    //                     슈퍼유저, 혹은 사용자 권한을 가지고
    //                     있어야 한다.
    // 
    //           IPC_RMID : 공유메모리 공간을 삭제하기 위해서 사용
    //                      이 명령을 사용한다고 해서 곧바로 
    //                      공유메모리가 삭제되는 것은 아니며,
    //                      공유메모리에 접속되어 있는 프로세스가
    //                      0 일 때까지 기다렸다가 삭제.
    // 
    // *buf :    공유 메모리의 정보를 구하고 싶은 경우,
    //           정보를 저장할 포인터를 같이 넘긴다.
    //           buf 에 공유 메모리의 정보가 저장된다.
    // 반환 값 : 성공할 경우 0 반환.
    //           실패한 경우 -1 반환
    // 
    // 
    // 
    else{
        while(1){
            srand(seed1);
            if((*cal_num) >= MAX_VALUE || (*cal_num)<= MIN_VALUE){
                break;
            }
            *cal_num = *cal_num - 1;
            printf("parent :  I'm %d sec sleep. minus 1. current value: %d\n", sleep_time, *cal_num);
            sleep_time = (rand()%RAND_DISTANCE) +1;
            sleep(sleep_time);
        }
        if((*cal_num) >= MAX_VALUE){
            puts("parent : I'm looser\n");
        }
        else{
            puts("parent : I'm winner\n");
        }
        shmdt(cal_num);
        shmctl(shmid, IPC_RMID, NULL);
        waitpid(pid, &status, 0); // 자식 프로세스를 기다리기 위해서
    }
    return 0;
}


'C언어' 카테고리의 다른 글

c++ 공부 요점 정리 2  (0) 2013.11.11
리눅스(우분투 10.10) 공유 메모리 예제 2  (0) 2013.11.07
bind 에러 해결 방법  (0) 2013.10.31
다중 입출력 함수 select  (0) 2013.10.28
c++ 공부 요점정리 1  (0) 2013.10.26
Posted by 뮹실이

2013. 10. 31. 17:20 C언어

bind 에러 해결 방법

close 함수로 소켓을 소멸 시켜도 커널은 바로 소멸 시키지 않고 몇초정도 유지시킴


클라이언트와 처리되지 않은 전문을 마저 처리하도록


bind 된 소켓이 아직 소멸되지 않았는데 같은 주소, 같은 포트로 또 다른 소켓이 bind 요청하니 


에러 발생


해결 방법 : 소켓에 옵션 설정


option = 1;          // SO_REUSEADDR 의 옵션 값을 TRUE 로


setsockopt( server_socket, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option) );


SO_REUSEADDR을 지정해 주면 같은 포트에 대해 다른 소켓이 bind()되는 것을 허락해 주기 때문에 bind() 에러 발생 안함

Posted by 뮹실이

// 다중 입출력 함수(select(), pselect(), poll(), ppoll())

// 

// 다중 입출력은 여러 fd 를 동시에 차단하면서 fd 중 하나가 차단 없이 읽고 쓸 준비가 될 때 알려주는 기능

// 다중 입출력을 위한 기본 방식

// 1. fd 중 하나가 입출력이 준비될 때를 알려준다.

// 2. 하나 이상의 fd 가 준비될 때까지 잠든다.

// 3. 어떤 fd 가 준비되었는지 확인 후 준비가 되면 깨어난다.

// 4. 차단 없이 모든 fd 가 입출력을 준비하도록 관리한다.

// 5. 1단계로 돌아가서 다시 시작한다.

// 

// select()

// 한 곳에 모아 놓은 여러 file descriptor를 동시에 관찰할 수 있음

// 수신한 데이터를 지니고 있는 file descriptor가 어떤 것들인지,

// 데이터를 전송할 경우 blocking 되지 않고 바로 전달 가능한 file descriptor는 어떤 것들인지,

// 또한 예외가 발생한 file descriptor는 어떤 것들인지 정도가 관찰 내용이 됨

//

// 함수 호출 과정

// descriptor 설정, 검사 범위 설정, time out 설정

// => select 함수 호출

// => 결과 확인

//

// select 함수는 지정된 file descriptor의 변화를 확인함, 

// 즉, file descriptor를 통하여 테이터 송,수신 가능 여부를 체크하는것

// 또한, I/O 버퍼를 생성했다는 것과 같은 말이자,

// file descriptor의 변화는 I/O 버퍼에 변화가 생겼다는말

// 만약 file descriptor에 변화가 생기지 않았다면 변화가 발생할 때까지 select 함수가 돌아가니

// 그 동안에는 blocking에 걸리게 됨, 이점을 해결하기 위해서 time out을 걸어줌

// time out을 설정해 놓으면 그 시간만큼 시간이 지나 return 되기 때문에 bloking 상태를 피할 수 있음

//

// 관찰 항목이 세가지 이므로 file descriptor의 묶음도 세가지로 준비해야함

// file descriptor를 세묶음으로 모아 놓기 위해서 사용되는 것이 fd_set 데이터 타입의 자료형

// fd_set은 0, 1 을 나타내는 배열이라 생각하면 됨

typedef struct fd_set{

u_int fd_count;

SOCKET fd_array[FD_SETSIZE]

} fd_set;


// fd_count : 설정하는 socket 번호.

// fd_array : 설정된 socket 배열.

//

// fd 가 입출력을 수행할 준비가 되거나 정해진 시간이 결과할 때까지 차단


#include <sys/select.h>

#include <sys/time.h>

#include <sys/types.h>

#include <unistd.h>

  int select(int mafdl, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

// 성공 시 반환 값 : 준비된 fd 개수

// 준비된 fd가 있을 때 준비된 fd 갯수를 반환

// fd 집합은 준비된 fd에 해당하는 비트들만 켜진 상태가 됨

// 시간 만료시 반환값 : 0

// 지정된 fd 중 하나가 준비되기 전에 시간이 만료되면 0을 반환

// 이 경우 fd 세 집합 비트들은 모두 0이 됨

// 오류 시 반환 값 : -1

// 지정된 fd 중 하나가 준비되기 전에 신호가 잡혀서 select 호출이 가로채여 -1이 반환

// 이 경우 fd 세 집합의 비트들은 모두 수정되지 않음

// ===========================================================================================================

// timeout : 만료 시간을 담은 구조체

// NULL 로 설정하면 무한정 기다림, fd 중 하나가 준비되거나 신호가 잡힐 때까지 차단

// 0 으로 설정하면 전혀 기다리지 않음, 차단없이 fd 상태만 확인하는 경우에 쓰임

// 0 이 아닌 경우 지정된 sec나 usec 만큼 기다림, fd 중 하나가 준비되거나 시간이 만료되면 반환

// 만약 time out을 설정하지 않을 경우 NULL값을 포인터 인자로 넘겨 주면 됨


#include <sys/time.h>

 

struct timeval {

long tv_sec;  // 초

long tv_usec; // 마이크로 초

};

// ===========================================================================================================

// readfds : 자료 읽기가 준비되었는지 확인할 fd

// 즉, 입력 스트림에 변화가 발생했는지 확인(수신할 데이터가 있는가)

//

// writefds : 자료 쓰기 연산을 끝낼 수 있는지 확인할 fd

// 즉, 데이터 전송시 blocking 되지 않고 바로 전송이 가능한가

//

// exceptfds : 예외가 발생했는지 확인할 fd

// ===========================================================================================================

// fd 집합의 자료 형식은 fd_set으로, fd_set에 fd들을 할당하고 확인하는 방법은 다음의 매크로를 사용해야함

// 즉, fd_set 변수를 조작하는데 사용되는 함수

#include <sys/select.h>

int FD_ISSET(int fd, fd_set *fdset);

// fd 가 집합에 있을 경우의 반환 값 : 0 이 아닌 값

// fd 가 집합에 없을 경우의 반환 값 : 0

void FD_CLR(int fd, fd_set *fdset);

void FD_SET(int fd, fd_set *fdset);

void FD_ZERO(fd_set *fdset);

//

// FD_ZERO  : 주어진 fd_set의 모든 비트를 0으로 초기화, select() 함수를 호출하기 전에 매번 FD_ZERO를 불러야함

// FD_SET   : 집합의 특정 비트를 켤 때 사용, fd 를 집합에서 추가할 때 사용

// FD_CLR   : 집합의 특정 비트를 끌 때 사용, fd 를 집합에서 제거할 때 사용

// FD_ISSET : 특정 비트가 켜져 있는지 확인 할 경우 사용, select() 호출이 반환된 후 fd 가 입출력 준비가 끝났는지 점검하기 위해 쓰임

//

// readfds, writefds, exceptfds 집합에는 감시할 fd 가 없으면 NULL 을 넣을 수 있고,

// 세 집합 모두 NULL 로 하면 sleep 보다 해상도가 높은 타이머를 사용할 수 있게 됨

// sleep 함수는 초 단위 시간만 대기 할 수 있지만 select 함수는 마이크로 초 단위까지 대기할 수 있기 때문

struct timeval tv;

tv.tv_sec = 0;

tv.tv_usec = 500;

select(0, NULL, NULL, NULL, &tv);

// ===========================================================================================================

// mafdl : 점검할 fd의 갯수, fd 집합에서 가장 높은 fd 번호에 1을 더한 값을 넣어줘야함

// 최대 fd 번호에 1을 더하는 이유는 fd 번호가 0부터 시작하기 때문

// <sys/select.h>에 가장 큰 fd 번호로 FD_SETSIZE가 정의되어 있음

// 보통 1024가 정의되어 있는데 이 값은 너무 크므로 최대 fd 번호에 1을 더한 값을 넘겨주는게 좋음

// mafdl 인자가 클수록 select 함수가 감시할 fd가 많아지는 것이기 때문

// ===========================================================================================================

// ex

#include <sys/select.h>

#include <sys/time.h>

#include <sys/types.h>

#include <unistd.h>

#include <fcntl.h>

#include <stdio.h>

#include <errno.h>

#include <string.h>

#include <signal.h>


#define buf_length 1024


int main()

{

struct timeval tv;

fd_set readfds, tmpfds;

int select_result;

int read_result;

char buf[buf_length + 1];


FD_ZERO(&readfds);

FD_SET(STDIN_FILENO, &readfds);


while(1)

{

tmpfds = readfds;


tv.tv_sec = 3;

tv.tv_usec = 0;


select_result = select(STDIN_FILENO + 1, &tmpfds, NULL, NULL,&tv);


if (select_result == -1)

{

perror("select");

}

else if (select_result == 0)

{

printf("3 sec\n");

}

else

{

if (FD_ISSET(STDIN_FILENO, &readfds)

{

read_result = read(STDIN_FILENO, buf, buf_length);

if (read_result == -1) perror("read"), return(1);

if (read_result) buf[read_result] = '\0', printf("read : %s\n",buf);

if (strncmp(buf, "quit",4) == 0) break;

}

}// end of if

}// end of while

}// end of main

Posted by 뮹실이

2013. 10. 26. 23:18 C언어

c++ 공부 요점정리 1








1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
// ==========================================
// 1. 입출력
// ==========================================
//
// 과거 표준 출력
//
#include <iostream.h> // 과거 표준 헤더

cout << 출력대상;
cout << 출력대상1 << 출력대상2 << 출력대상3;
cout << 1 << 'a' << "string" << endl;

// endl : 줄바꿈(버퍼비움)
// << : shift 연산

//
// 현재 표준 출력
//
#include <iostream> // 새 표준 헤더

std::cout << 출력대상;
std::cout << 출력대상1 << 출력대상2 << 출력대상3;
std::cout << 1 << 'a' << "string" << std::endl;

//
// 과거 표준 입력
//
#include <iostream.h>

int val1, val2;

cin>> val1;
cin>> val2;

int result = val1 + val2;
// c++은 변수선언이 함수의 중간에 올 수 있다.
// c에서는 함수의 윗부분에 변수 선언해야한다.

cout<< "덧셈 결과 : " << result << endl;

//
// 현재 표준 입력
//
#include <iostream.h>

int val1, val2;

std::cin>> val1;
std::cin>> val2;
// 같은 의미 : std::cin>> val1 >> val2;


int result = val1 + val2;
// c++은 변수선언이 함수 어디서든지 가능
// c에서는 함수의 윗부분에 변수 선언해야함

std::cout<< "덧셈 결과 : " << result << std::endl;

// ==============================================
// 2 함수 오버로딩
// ==============================================

// c는 함수 이름 중복 불가
// c++은 함수 이름 중복 가능
// 같은 함수이름을 가지는 함수로
// 전달하는 매개변수(인자값) 갯수 or 타입이 달라야함
int func(void);
int func(int a, intb);

// or 

int func(int a);
int func(char a);

//
// 디폴트 매개 변수
//

int func(int a = 0);
// func함수 호출시 매개변수 전달이 없으면
// 0이 전달된것으로 처리

// 함수 선언과 정의를 분리할 경우
// 디폴트 매개 변수 선언은 함수 선언부에 한번만 정의해야함
int func(int a, int b = 0);

int main()
{
	std::cout<<func(1)<<std::endl;
	// a= 1, b = 0;
	// 결과 : 1;
}
int func(int a, int b)
{
	return a+b;
}

// 함수 오버로딩과 디폴트 매개변수를 동시에 사용할 경우
// 에러 발생 가능
int func(int a = 0);
int func(void);

int main(void)
{
	func();
	// func가 어떤 func를 호출해야할지 에러 발생 가능
}

// 함수오버로딩할 경우는 디폴트 매개변수 사용하지 않는게 좋음

// ======================================================
// 3 인라인(in line(source code)) 함수
// ======================================================
// 대표적 인라인화 : 매크로

// c 에서는 전처리기에 의해 처리
#define add(x) ((x)+(x))
// 하지만 복잡한 경우에는 구현하기 어려움

// c++ 에서는 컴파일러에 의해 처리(디버깅이 쉬움)
// 컴파일러에게 최적화의 기회 제공
// inline 키워드를 사용해서 성능이 떨어질 경우
// 컴파일러가 inline 키워드를 무시하고 
// 일반 함수로 처리해버림
// 구현 하기 쉬움
inline int add(int x);

// =====================================================
// 4 이름공간(namespace)
// =====================================================
// 이름 충돌을 막기위해서
// 공간에 이름을 주는 행위

//
// 이름공간 설정 전
//
void func(void);
void func(void);

void main(void)
{
	func(); // 에러 발생
}

//
// 이름공간 설정
//
namespace a
{
	// 변수 선언도 가능
	// 여러개의 함수 선언 가능
	void func(void);
}

namespace b
{
	// 변수 선언도 가능
	// 여러개의 함수 선언 가능
	void func(void);
}

void main(void)
{
	a::func(); // 에러 발생하지 않음
	b::func(); // 에러 발생하지 않음
	// :: -> 범위지정 연산자
}

// std 란 namespace !!!
namespace std
{
	//cout??
	//cin??
	//endl??
}

//
// 편의를 위한 using 선언
//
using a::func;
// a 라는 이름공간안의 함수(또는 변수)를 호출할 때는
// 그냥 func라는 이름으로만 사용하겠다는 의미
// 즉
a::func();

using a::func;
func();
// 위 두개가 같은 의미

using namespace a;
// a 라는 이름공간안의 함수나 변수를 그냥 사용하겠다는 의미
 
using namespace std;
// 를 선언함으로써 std:: 를 생략할 수 있지만
// 이름 충돌이 발생할 수 있으므로

using std::cout;
using std::cin;
using std::endl;
// 이렇게 쓰는것을 추천

//
// 범위 지정 연산자 기반 전역 변수 접근
//
int val = 100;

int main(void)
{
	ing val = 100;
	val += 1; // 지역변수 val을 사용하게 됨
	// 전역 변수 val이 지역변수 val에 가려진 상황
}

// 문제 해결 방법

int val = 100;

int main(void)
{
	ing val = 100;
	::val += 1; // 전역 변수 val을 사용하게 됨
	// :: (범위지정연산자)가 아무 범위도 지정하지 않는경우
	// 전역에 접근함
}





Posted by 뮹실이





Console.WriteLine("aaaaa {0:D}", count++);


-> aaaaa 정수 출력(count)


Console.WriteLine("aaaaa {0:G}", count++);


-> aaaaa 정수나 소수 출력(count)

'C언어' 카테고리의 다른 글

리눅스(우분투 10.10) 공유 메모리 예제 2  (0) 2013.11.07
리눅스(우분투 10.10) 공유 메모리 예제  (0) 2013.11.07
bind 에러 해결 방법  (0) 2013.10.31
다중 입출력 함수 select  (0) 2013.10.28
c++ 공부 요점정리 1  (0) 2013.10.26
Posted by 뮹실이
이전버튼 1 2 3 4 이전버튼

최근에 달린 댓글

08-02 03:49
Yesterday
Today
Total