반응형
728x90
반응형

문자와 문자열

  • 입력과 출력

  • 스트림

프로그램과 입력 및 출력 장치를 연결해주는 소프트웨어적으로 구현되어 있는 도구, 입출력 장치와 프로그램을 연결해주는 가상의 다리이다. 운영체제가 이를 제공한다.

  • 문자 단위 입/출력 함수

EOF End Of File의 약자로 파일의 끝을 표현하기 위해 정의된 상수이다. 위의 함수가 파일이나 콘솔의 출력으로 EOF를 반환하게 되면 파일이나 콘솔로부터 더 이상 입력 받을 것이 없다 라는 의미를 갖는다. 그렇다면 EOF를 반환하는 시기는 다음과 같다.

함수 호출의 실패할 경우
컨트롤 + z / 컨트롤 + d 키가 입력될 경우

문자를 입력 받는 함수인데 반환 형이 정수 int 형인 이유는? 컴파일러에 따라 char unsigned char로 처리하는 경우가 존재한다. 그런데 EOF 라는 값은 -1로 정의되어 있는데 charunsigned char로 처리하는 컴파일러는 EOF에 대한 처리가 불가능하다. 그렇기 때문에 같은 정수 타입인 int로 반환한다.

 

  • 문자열 단위 입/출력 함수

기존의 scanf 함수 등은 공백을 포함한 문자열을 입력 받기에 있어서 크게 제한이 되었다. (공백을 기준으로 입력을 나누기 때문)

 

  • 표준 입/출력 버퍼

표준 입/출력 함수를 통해서 데이터를 입/출력하는 경우, 해당 데이터들은 운영체제가 제공하는 메모리 버퍼를 꼭 통과하게 되어 있다. 메모리 버퍼는 데이터를 임시로 저장해 놓는 메모리 공간인데, 이런 저장하는 작업을 버퍼링 이라고 한다.

키보드로 데이터를 입력하면(문자열 입력 후 엔터를 칠 경우) 해당 데이터들은 입력 버퍼로 전송되어 저장되고(버퍼링), 그 이후에 프로그램으로 데이터들이 전송이 된다.

 

버퍼링을 하는 이유?

프로그램 연산(CPU 연산)에 비했을 때 I/O 장치들 과의 I/O 작업은 상당히 시간이 걸리는 작업이다. , 데이터를 읽어오는데 걸리는 시간이 CPU의 연산 처리 속도보다 훨씬 느리다. 그렇기 때문에 CPU는 그러한 느린 데이터 입출력 처리를 기다리고 있어야 하는데 데이터를 읽을 때마다 조금씩 전송을 하는 구조로 진행되면 데이터 전송의 효율성이 떨어진다. 그렇기 때문에 중간에 메모리 버퍼를 두고 데이터를 한데 묶어서 보내면 빠르고 효율적인 데이터 전송이 될 수 있다.

 

  • 출력 버퍼와 입력 버퍼 비우기!

출력 버퍼를 비운다는 것은 출력 버퍼에 저장된 데이터가 버퍼를 떠나서 목적지로 이동되는 것을 이야기하는데, 이러한 역할을 하는 함수가 존재하는데 다음과 같다.

위 함수는 파일을 대상으로도 버퍼 비우기가 가능하고, 출력 버퍼를 비우는 일은 많이 존재하지는 않는다.

반면에, 입력 버퍼를 비운다는 것은 출력 버퍼와는 다르게 데이터의 소멸을 의미한다. fflush 함수를 이용하여fflush(stdin); 과 같은 형태로 호출하면 입력 버퍼는 비워지거나/비워지지 않거나 보장할 수 없는 결과를 나타낸다. (Windows 계열의 컴파일러의 경우는 입력 버퍼를 지워 준다고 한다.)

입력 버퍼를 비우기 이전에 입력 버퍼를 비워야 하는 경우에 대한 예제이다.

먼저, 6번 라인에서 str1의 크기를 10 바이트로 지정해주었고, 10번 라인에서 str1에 문자열을 대입하는데 9자리의 문자를 대입한다. 9자리라고 함은 문자열 9자리와 NULL 문자 1바이트를 고려한 것이다. 그러나 입력될 때에는 “abcdefghi\0\n” 이 입력되고 입력 버퍼에 들어가게 된다. (fgets함수의 ‘\n’이 입력될 때까지 읽어 들이는 특성 상) 그래서 10번 라인에서는 입력한 “abcdefghi” 문자열에 ‘\0’ 문자가 합쳐져서 입력으로 str1에 저장된다. 그리고 13번 라인에서 fgets 함수가 호출되는데 이 때 입력 버퍼에 남은 ‘\n’ 문자를 읽어버리고 바로 호출이 끝나게 된다. 그렇기 때문에 실행 결과에서는 str2‘\n’만 저장된 결과가 나타난 것이다. 이러한 경우 str1의 저장 이후 입력 버퍼를 비웠더라면 다음 문자열 입력을 받을 수 있었다. 이것이 입력 버퍼 비우기의 필요성이다.

입력 버퍼를 비운다는 것은 문자들을 읽어 들이면 지워진다, 즉 비워진다. 다음과 같은 함수로 입력 버퍼를 지울 수 있다.

23번 라인에서 한 문자씩 읽는데 그 읽은 것이 ‘\n’ 개행 문자일 경우 탈출하게 된다. , 개행 문자까지 버퍼로부터 문자를 읽음으로써 버퍼가 비워진다.

 

  • 문자열의 길이를 반환 : strlen

일단, size_ttypedef unsigned int size_t; 로 자료형 재정의가 되어 있다.

 

  • 문자열의 복사 : strcpy

strcpysrc의 문자열을 dest에 복사한다. strncpy의 경우에는 src의 문자열을 dest에 복사하되, n 크기만큼 복사한다. , strncpy의 경우 마지막 문자가 NULL인지에 대한 검사는 하지 않고 주어진 n만큼만 복사를 한다. , 복사된 문자열의 끝에서 NULL에 대한 처리를 진행하지 않기 때문에 직접 NULL 처리를 해줘야 한다. 이후에 기재되는 모든 n이 들어가는 함수는 NULL처리가 진행되지 않는 공통점을 가지고 있다.

 

  • 문자열 연결 : strcat

Dest 문자열 뒤에 src 문자열을 붙이고 그 값을 dest에 저장한다. 앞 문자열의 NULL 문자를 없애고 그 자리부터 뒷 문자열이 시작된다.

 

  • 문자열 비교 : strcmp

  • 이외의 문자열/수 변환 함수

728x90
반응형

'컴퓨터 언어 정리 > C 언어' 카테고리의 다른 글

17 파일 입출력  (0) 2020.10.13
16 구조체  (0) 2020.10.12
14 함수 포인터와 void 포인터  (0) 2020.09.23
13 다차원배열 및 포인터의 관계  (0) 2020.09.21
12 포인터의 포인터  (0) 2020.09.15
728x90
반응형

함수 포인터와 void 포인터

  • 함수 포인터

함수 또한 메모리 상에 바이너리 형태로 올라가 호출 시 실행이 되는데, 메모리 상에 저장된 함수의 주소 값을 저장하는 포인터 변수가 함수 포인터 변수이다.

배열의 이름이 배열의 시작 주소 값을 의미하듯이 함수의 이름 또한 함수가 저장된 메모리 공간의 시작 주소 값을 의미한다.

함수 이름의 포인터 형은 반환 타입과 매개변수의 선언을 통해 결정 짓도록 약속. , 반환 타입과 매개변수의 선언이 일치하는 모든 함수들의 포인터 형은 모두 같다.

9번 라인과 10번 라인에서 볼 수 있듯이

반환 타입 (*포인터변수이름) (매개 변수) = 함수 이름

다음과 같은 형태로 함수 포인터 변수를 선언하고 함수의 주소를 받아서 12, 13번 라인처럼 함수 포인터 변수를 통한 함수 호출이 가능하다.

  • Void 형 포인터 ( 자료 형이 없는 포인터 )

다음과 같이 선언되는 포인터를 void 형 포인터 변수라고 한다.

Void 형 포인터는 어떤 변수의 주소 값이든 함수의 주소 값이든 상관 없이 주소값의 경우는 무엇이든 전부 담을 수 있다. 다음 예는 void * 변수에 다양한 주소 값을 저장하는 예를 나타낸 것이다.

, void 형 포인터 p를 이용하여 참조를 하는 순간(=포인터 연산을 하는 순간) 컴파일 에러가 발생한다. 왜냐하면 void * 포인터는 포인터 연산 시 증감의 크기에 대한 정보가 단 한 부분도 없다. , 해당 주소로부터 어느 범위까지 연산을 하여 참조를 해야하는지에 대한 정보가 없기 때문에 참조(포인터 연산)가 불가능하다.

void형 포인터는 주소 값을 저장하는 것에만 의미를 두고 포인터 형은 나중에 결정한 참조하는 경우에 유용하게 사용된다 -> 동적 메모리 할당

  • Main 함수를 통한 인자 전달

위의 예제에서 argc는 파일 이름을 포함한 전달 되어온 인자의 수를 나타내고, argv는 더블 포인터 형태로 싱글 포인터 혹은 싱글 포인터 배열의 각 요소를 가리킨다. , argv는 두 번째 결과에서 “./t”, “yoo”, “seung”, “ho”의 주소 값인 char * 타입을 가리키기 때문에 더블 포인터 형태이다.

728x90
반응형

'컴퓨터 언어 정리 > C 언어' 카테고리의 다른 글

16 구조체  (0) 2020.10.12
15 문자와 문자열  (0) 2020.09.29
13 다차원배열 및 포인터의 관계  (0) 2020.09.21
12 포인터의 포인터  (0) 2020.09.15
11 다차원 배열  (0) 2020.09.14
728x90
반응형

이번엔 모든 컨테이너에서 공통적으로 지니는 멤버 함수들을 정리해 볼 것이다.

Container 대신에 해당하는 컨테이너 및 자료형 타입을 기입하여 사용하면 된다.

생성자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    vector<int> v1; // 1. Container(), 컨테이너를 생성.
    vector<int> v2(10); // 2. Container(size), 길이가 10개인(10*sizeof(type)) 컨테이너 생성.
    vector<int> v3(105); // 3. Container(size, value),  값이 5로 전부 채워진 길이 10개 컨테이너 생성.
    vector<int> v4(v3.begin(), v3.begin()+4); // 4. Container(iterator, iterator),  v3의 값을 복사하며 생성.
 
    vector<int>::iterator it;
 
    cout << endl << "v2---" << endl;
    for (it = v2.begin(); it < v2.end(); it++)
        cout << *it << ", ";
 
    cout << endl << "v3---" << endl;
    for (it = v3.begin(); it < v3.end(); it++)
        cout << *it << ", ";
 
    cout << endl << "v4---" << endl;
    for (it = v4.begin(); it < v4.end(); it++)
        cout << *it << ", ";
cs

실행 결과

empty()와 clear() 

1
2
3
4
5
6
7
8
9
10
11
12
vector<int> v1; 
vector<int> v2(10); 
vector<int> v3(105); 
vector<int> v4(v3.begin(), v3.begin()+4); 
 
vector<int>::iterator it;
 
cout << "vector<int> v1; : " << v1.empty() << endl// true 반환
cout << "vector<int> v2(10); : " << v2.empty() << endl// false 반환
cout << "vector<int> v3(10, 5); : " << v3.empty() << endl// false 반환
v4.clear(); // 모든 요소 제거
cout << "v4.clear(); : " << v4.empty() << endl// true 반환
cs

empty() 멤버 함수는 해당 콘테이너가 비어져있는지를 확인하는 함수이고, clear() 멤버 함수는 해당 콘테이너 속 요소를 모두 제거 한다.

begin(), end() 와 erase()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
vector<int> v1; 
vector<int> v2(10); 
vector<int> v3(105); 
vector<int> v4(v3.begin(), v3.begin()+4); 
 
vector<int>::iterator it;
 
v3.erase(v3.begin(), v3.end() - 1); // 범위로 지우기 : v3.begin() 부터 (v3.end()-1)-1 까지 지운다.
for (it = v3.begin(); it < v3.end(); it++)
    cout << *it << ", ";
cout << endl;
 
v3.erase(v3.begin()); // 위에서 하나 남기고 모두 지웠으니, 시작 하나만 지우면 다 지워지는 꼴.
for (it = v3.begin(); it < v3.end(); it++)
    cout << *it << ", ";
cout << endl;
cs

begin() 함수와 end() 함수는 콘테이너의 시작과 끝 위치를 iterator 형으로 리턴한다. erase 멤버 함수는 컨테이너 내의 요소를 지우는 함수인데, 8번 라인처럼 범위로 지울 수 있고, 13번 라인처럼 해당 요소에 대해서 지울 수 있다.

insert()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
vector<int> v3(105); 
vector<int> v4(5100); 
vector<int>::iterator it;
 
v3.insert(v3.end() - 19999);
 
for (it = v3.begin(); it < v3.end(); it++)
    cout << *it << ", ";
cout << endl;
 
v4.insert(v4.end(), v3.begin(), v3.end());
 
for (it = v4.begin(); it < v4.end(); it++)
    cout << *it << ", ";
cout << endl;
cs

 

insert() 멤버 함수는 요소를 삽입하는 함수인데 마찬가지로, 5번 라인/11번 라인의 두 가지 형태로 삽입이 가능하다. 요소를 삽입하느냐, 범위로 삽입하느냐.

push_back(), pop_back()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
vector<int> v3(105); 
vector<int> v4(5100); 
 
vector<int>::iterator it;
 
v3.push_back(1000000);
for (it = v3.begin(); it < v3.end(); it++)
    cout << *it << ", ";
cout << endl;
 
v3.pop_back(); // 리턴 값이 없으며, 삭제만 가능하다.
for (it = v3.begin(); it < v3.end(); it++)
    cout << *it << ", ";
cout << endl;
cs

push_back 함수는 벡터의 가장 마지막에 요소를 추가, pop_back() 함수는 가장 마지막 요소를 삭제한다. 11번 라인에서의 주석처럼 pop_back()는 리턴 값이 없고 삭제만 가능하다.

operator=(),  operator()==, size()


1
2
3
4
5
6
7
8
9
10
11
12
vector<int> v1({ 1,2,3,4,5 });
vector<int> v2;
 
cout << "v1.size() : " << v1.size() << endl;
v2 = v1; // operator()=
cout << "v2.size() : " << v2.size() << endl;
 
if (v1 == v2)
    cout << "v1과 v2는 동일한 값을 지닙니다." << endl;
else
    cout << "v1과 v2는 동일한 값을 지니지 않습니다." << endl;
    
cs

 

이로써 공통 멤버함수들에 대한 정리 끝!

728x90
반응형

'프로그래밍응용 > Modern & STL' 카테고리의 다른 글

List  (0) 2020.09.14
Deque  (0) 2020.09.13
Iterator( With vector )  (0) 2020.09.13
Vector  (0) 2020.09.12
STL:Container, Iterator, Algorithm 개념  (0) 2020.09.10
728x90
반응형

포인터와 함수

  • 값의 복사 인자 전달 방식 ( 기본 인자 전달 방법 )

먼저, 기본적으로 함수에서 인자를 전달할 때는 값의 복사 방법으로 인자가 매개변수로 전달이 된다.

위의 예제에서 num 변수를 func 함수의 인자로 넣어 값을 전달하는데 이 때 전달되는 것은 num 변수가 아니라 num 변수의 값이 전달되어 arg 변수에 저장된 것이다. 결국, 지역 변수 num과 함수의 매개 변수 arg는 서로 전혀 관련 없는 별개의 변수이다. ( arg 매개 변수 값을 아무리 변경하더라도 num 지역 변수의 값의 변화는 일어나지 않는다. )

 

  • 배열을 함수의 인자로 전달하는 방법

배열을 기본 인자 전달 방법인 값의 복사 방법으로 통째로 복사하여 전달하는 방법은 존재하지 않는다.

위와 같은 소스는 컴파일 가능하지 않다. 왜냐하면 매개 변수로 배열을 선언하는 것은 허용되지 않기 때문이다. 그러나 gcc 컴파일러 6.4.0 version을 기준으로 위의 소스가 실행이 되고 정확한 결과가 나와서 가능한 것처럼 보였으나, 

위와 같이 지역 변수의 배열과 매개 변수의 배열의 배열 이름의 값을 출력해 보았다. 그 결과는 다음과 같다.

두 배열 이름이 같은 주소를 지니고 있다. 이 뜻은 지역 변수의 배열 arr는 문제 없이 정상적인 방법으로 메모리 할당이 이루어져 배열을 이루고 있는 것이지만, 매개 변수의 배열 arg는 외형과 다르게 포인터 변수로서 선언되어 있다.

포인터 변수이기 때문에 arg의 값의 변경이 가능하다. 그리고 다음은 그 결과이다.

아파트를 보고 싶어 하는 사람 앞에 아파트를 통째로 복사해 놓을 수 없다면, 아파트를 직접 찾아가도록 주소를 알려주듯이 배열을 통째로 복사가 불가능하다면 배열의 시작 주소 값을 전달하고, 그에 맞는 포인터 형을 매개 변수를 이용하여 포인터 연산으로 각각의 배열 요소에 접근하여 원하는 값을 참조하면 된다.

18번 라인에서 넘겨주는 배열 이름(배열의 시작 주소)5번 라인에서 포인터 변수를 통하여 받고 포인터 연산을 통하여 ( arg[i] = *(arg+i) ) 각각의 요소를 참조하여 출력을 한다. 매개 변수 한정으로 5번 라인에서 주석 친 부분과 같은 형식으로 매개 변수를 선언하고 주소를 받을 수 있다.

  • Call by value 그리고 Call by reference

두 방법에 대해 정리하기 이전에 두 변수의 값을 서로 교환하는 “SWAP” 문제에 대해서 두 방법을 적용해보고 해결하는 과정으로 두 방법을 정리할 것임.

먼저 call by value이다. 이 방법은 함수 인자 전달의 기본 방식이다.

 swap 함수 내에서는 값이 변경되었으나, 정작 바뀌어야 할 main 함수 내의 변수들은 swap이 이루어지지 않았다 이는 복사에 의한 인자 전달이기 때문에 변경이 되지 않는 것은 당연한 일이다. 변경된 것은 swap 함수 내의 매개 변수끼리 값이 변경된 것이다. 이러한 swap은 진정한 의미의 swap이라고 할 수 없다. 이를 해결하기 위해선 주소가 주어지고 해당 주소를 직접 참조하여 값을 변경하는 방식으로 전개를 해야 한다.

다음은 call by reference이다.

주소를 전달하고, 전달된 주소를 참조하여 값을 변경하는 방법으로 값이 성공적으로 swap 되었음을 확인할 수 있다. scanf 함수 또한 call by reference 방법으로 인자를 전달하는 형태이고, 문자열(%s)을 입력 받을 때 ‘&’ 를 붙이지 않는 이유와 그 외의 값을 받을 때 ‘&’ 를 붙이는 이유를 call by reference 방법으로부터 알아낼 수 있다.

 

  • 포인터에서의 const 키워드

다음과 같은 변수가 선언되어 있는 상황이다.

이러한 상황에서 const 키워드를 어느 위치에 사용하는지에 따른 결과들을 분석할 것.

1.     포인터 변수가 참조하는 대상을 상수화(const )한다.

포인터 변수 p를 통하여 number의 값이 변경되는 것을 허용하지 않는다.

2.     포인터 변수를 상수화(const )한다.

포인터 변수 p를 상수화 하여 포인터 변수 p의 값이 변경되는 것을 허용하지 않는다.

3.     둘 다 상수화(const )한다.

p를 통한 number의 값의 변경, p의 값 변경 모두 허용하지 않는다.

4.     일반 변수를 상수화(const ) 한다.

변수 n을 상수화 하여 n의 값을 변경할 수 없다.

Const 키워드는 C++에서만 제공했던 키워드, 표준을 재정립하는 과정에서 C언어서도 지원을 해준다. Const 키워드는 값이 바뀌어서는 안 되는 변수의 변경을 막아준다. 이러한 경우는 프로그램을 실행하는데 있어서는 치명적인 오류로 작용할 수 있지만 문법 상으로는 문제가 없기 때문에 컴파일 오류 하나 받아볼 수 없다. 그렇기 때문에 효율적이고 현명한 프로그램을 원한다면 const 키워드를 자주 사용하는 습관을 들여놓아야 함.

728x90
반응형

'컴퓨터 언어 정리 > C 언어' 카테고리의 다른 글

12 포인터의 포인터  (0) 2020.09.15
11 다차원 배열  (0) 2020.09.14
09 포인터와 배열  (0) 2020.09.12
08 포인터 기본  (0) 2020.09.11
07 1차원 배열  (0) 2020.09.11
728x90
반응형

함수와 변수의 생명주기

  • 함수

문제를 해결하는데 앞서 문제를 작은 단위로 나누는 과정에서 그 작은 단위의 문제를 해결하는 하나 이상의 기능을 지닌 부 프로그램.

함수 정의의 기본 틀

  1. ‘ 함수_이름 ‘ 에는 말 그대로 함수의 이름을 정의한다.

  2. ‘ 출력_타입 ’ 에는 해당 함수가 값을 반환할 경우 반환하는 값의 자료형을 기재한다.
     -> 왜냐하면 함수의 값을 받을 때, 어떤 자료형 변수로 받을지 결정할 수 있어야 하기 때문이다.

  3. ‘ 입력_형태 ‘ 에는 함수가 실행될 때 입력 값으로 받는 인자를 기재한다. 여러 타입, 여러 개의 인자를 받을 수 있다.

  4. ‘ 함수의 내용 ‘ 에는 함수가 수행할 연산 명령들이 정의 된다.

  5. ‘ 출력_타입에_따른_반환_값 ‘ 에는 함수가 종료 하면서 반환하는 값을 기재하는데, 조건문에 의하여 여러 번 기재될 수 있으며 ‘ 출력_타입 ‘ 에 맞춰 값을 반환한다.

함수의 정의와 호출 및 선언

함수의 정의와 호출

<입력 X / 출력 X func 함수의 정의와 호출>

<입력 O / 출력 X func 함수의 정의와 호출>

<입력 X / 출력 O func 함수의 정의와 호출>

<입력 O / 출력 O func 함수의 정의와 호출>

함수의 선언

위와 같이 함수를 main 함수 밑에서 정의할 때, main 함수 내에서 함수의 호출이 정의보다 앞서는 이유로 함수가 존재 하지 않는다는 에러가 발생하는데 이 때 main 함수 상단의 선언을 통해서 정의가 밑에 있음을 컴파일러에게 명시하여 문제를 해결한다.

  • 변수의 생명주기

<지역 변수( = 자동 변수 )>

중괄호 내에 일반적인 형태(자료형 + 이름)로 선언 되는 모든 변수

  • 해당 지역(해당 변수를 감싼 가장 가까운 중괄호 내의 영역)에서만 유효

  • 해당 지역을 벗어나면 자동으로 소멸

  • 선언된 이름이 같아도 지역이 다르면 중복 선언이 가능

  • 선언 시 메모리의 ‘스택’ 영역에 ‘쌓이는’ 형태로 할당 된다. (LIFO)

  • 조건문 혹은 반복문 내에서 선언된 변수 그리고 함수에서의 매개 변수 또한 지역 변수이다.

  • 지역 변수는 외부에서 선언된 동일한 이름의 변수를 가리게 된다. -> 변수의 이름을 통해 메모리에 접근 시 해당 지역에서 먼저 찾은 후 지역의 외부에서 찾는다.

  • for문이나 while문의 소괄호 내부가 아닌 중괄호 내에서 선언된 변수는 생성과 소멸을 반복한다. -> 반복은 중괄호의 진입과 탈출의 반복이기 때문

<전역 변수>

  • 중괄호 내에 선언 되지 않는다.

  • 프로그램의 시작과 동시에 메모리 공간에 할당되어 프로그램의 종료 시까지 존재한다.

  • 초기화를 직접 하지 않더라도 0으로 자동 초기화 된다.

  • 프로그램의 전체 영역 어디서든 접근이 가능하다.



<Static 정적 변수>

  • static 지역 변수

지역 변수에 static 키워드를 붙임으로써 생성되는 정적 변수.
선언된 중괄호 내에서만 접근이 가능( 지역 변수의 특성 )
1회 초기화되고(직접 초기화 하지 않을 경우 0), 프로그램 종료 시까지 메모리 공간에 존재( 전역 변수의 특성 )

  • static 전역 변수

전역 변수에 static 키워드를 붙임으로써 생성되는 정적 변수.
정적 전역 변수는 파일 외부에서 extern 키워드를 이용한 접근이 불가능함. -> 변수의 접근 범위를 해당 파일로 변경

<Register 변수>

지역 변수에 register 키워드를 붙임으로써 생성되는 변수.

Register로 선언된 변수는 CPU 내에 존재하는 ‘레지스터’ 라는 메모리에 공간이 할당될 ‘확률’이 높다. 레지스터 영역은 작고, 중요한 영역으로 상당히 제한이 있는 메모리 공간이기 때문에 register 키워드를 붙인다고 해서 무조건적으로 레지스터 영역에 할당이 되는 것이 아니다. 컴파일러에게 요청을 하는 명령이다.

전역 변수에 register 키워드를 붙이는 요청은 컴파일러에 의해 거절 된다. 중요한 메모리 영역을 전역 변수로 계속 해서 할당을 시키는 것은 명백한 자원 낭비이기 때문이다.



  • 재귀 함수

함수 내에서 자기 자신(함수)을 다시 호출하는 함수.

재귀 함수의 간단한 예이다. 재귀 함수의 필수 구성 요소는 다음과 같다.

  1. 빨간색에 해당하는 1번 원의 ‘ 재귀 호출 ‘ -> 자기 자신에서 자신을 다시 호출하는 것(복사본)

  2. 파란색에 해당하는 2번 원의 ‘ 탈출 조건 ‘ -> 재귀 구조의 무한 루프에 빠지지 않도록 한다.

728x90
반응형

'컴퓨터 언어 정리 > C 언어' 카테고리의 다른 글

08 포인터 기본  (0) 2020.09.11
07 1차원 배열  (0) 2020.09.11
05 반복과 분기  (0) 2020.09.08
04 상수와 자료형  (0) 2020.09.07
03 수의 표현 방식  (0) 2020.09.06
728x90
반응형

인라인 함수

  • C언어 기반의 매크로 함수

매크로 함수의 장점은 일반적인 함수에 비해서 실행 속도의 이점이 있다. 또한 매크로 함수의 단점으로는 정의하기가 어렵고 복잡한 함수를 매크로 형태로 정의하는데 한계가 있다.

매크로 함수의 몸체 부분이 매크로 함수의 호출 부분을 완전히 대체하여 SQUARE(2) -> ((2)*(2)) 형태로 대체되어 컴파일 된다. 이렇게 함수의 몸체 부분이 함수의 호출 문장을 완전히 대체했을 때 함수가 인라인화 되었다 라고 표현한다.

그렇지만 매크로 함수는 정의하기가 복잡하니 일반 함수처럼 정의 가능하도록 함. 그것이 C++의 인라인 함수이다.

  • C++ 언어 기반의 인라인 함수

함수를 정의한 후 inline 키워드만 붙여 넣어주면 인라인 함수가 정의 된다.

  • C언어 기반의 매크로 함수와 C++언어 기반의 인라인 함수의 비교

728x90
반응형

'컴퓨터 언어 정리 > C++ 언어' 카테고리의 다른 글

07 참조자(Reference)  (0) 2020.09.08
06 이름 공간(namespace)  (0) 2020.09.08
04 디폴트 매개변수(Default Parameter)  (0) 2020.09.07
03 함수 오버로딩(Function Overloading)  (0) 2020.09.06
02 Bool 자료형  (0) 2020.09.06

+ Recent posts