반응형
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
반응형

포인터와 배열

l 배열 이름과 포인터의 관계

다음은 배열의 이름이 무엇인지를 나타내는 예제이다.

위의 소스에서 확인할 수 있는 부분은 배열의 이름 그 자체를 출력했을 때의 값과 배열의 [0]번째 요소의 주소 값이 같다는 점이다. , 배열의 이름은 해당 배열의 시작 주소 값을 의미한다.

결국 배열의 이름 또한 주소 값을 지니고 있다는 관점에서 포인터와 그 개념이 매우 유사하다. 그렇다면 포인터 변수처럼 배열의 이름 또한 주소를 대입해볼 수 없을까? 배열의 이름에 주소 값을 대입하는 예제이다.

8번 라인에 새로운 변수 number를 선언하고, 10번 라인에서 배열의 이름에 number의 주소 값을 넣었다. 왜 배열의 주소가 아니라 일반 변수의 주소를 넣었느냐? 왜냐하면 배열의 이름은 배열의 시작 주소하나를 저장하기 때문에 배열 이름의 입장에서 보면 어떤 하나의 변수의 주소 값을 대입한 것과 다를 바 없이 보이기 때문이다. 그렇기 때문에 배열의 이름에 하나의 변수 number의 주소 값이 대입되는 것은 문제가 되지 않는다. 이렇게 배열의 이름에 변수의 주소를 넣은 결과, 10번 라인에서 배열 타입의 표현 식에 할당하는 부분에서 에러가 발생한다. 그 이유는 배열의 이름은 주소 값을 저장하고 가리키지만 처음 정해진 배열 이름의 값은 변경이 불가능하다. , 배열의 이름은 상수 값이다. 그도 그럴 것이 특별하게 배열을 선언하여 만들었는데 그 배열의 이름을 대표하는 배열의 이름이 가리키는 요소를 마음대로 바꾸게 되면 무엇을 위해 배열 이름을 지정해가며 배열을 생성했겠는가?

다음은 위에서 배열과 포인터의 관계에 대해 내린 결론을 정리하여 나타낸 표이다.

배열 이름은 포인터 변수와 같은 특성들을 지니고 있지만 상수라는 차이점이 있다. 그래서 배열 이름을 포인터 상수라고도 표현한다. 포인터 변수와 배열 이름은 변수이냐, 상수이냐 의 차이점 밖에 없기 때문에 그 차이를 제외하면 포인터 변수와 배열 이름은 완전히 같다. 그렇기 때문에 다음의 예제가 가능하다.

10번 라인에서 배열 이름(포인터 상수)의 값을 포인터 변수에 대입시키고 있다. 이것이 가능한 이유는

1.     포인터 변수에 포인터 상수를 대입 -> 전혀 문제될 것이 없다.

2.     대입 연산자를 기준으로 l-valuer-value의 형(type)이 같아야 한다.
-> l-value : int * / r-value : int * == int
(시작) 주소 로 문제될 것이 없다.

배열 이름의 포인터 형은 배열의 이름이 가리키는 대상을 기준으로 결정되기 때문에 r-value 배열 이름의 자료형은 정수형 변수 공간의 시작 주소이므로 int * 가 맞다.

포인터 변수에 포인터 상수를 대입하게 되면 포인터 변수를 이용하여 배열 이름처럼 인덱스로써 접근하는 방법으로 각 요소에 접근을 할 수 있다. , 포인터 변수를 배열의 이름처럼 사용할 수 있다는 것이 결론.

그렇다면 그 반대로 배열 이름(포인터 상수)을 가지고 포인터 연산을 할 수 있을까? 다음은 이에 관한 예제이다.

11번 라인에서 배열 이름과 ‘ * ‘, 애스터리스크 연산자를 이용한 포인터 연산이 진행되고, 12번 라인에서는 배열 이름과 인덱스를 이용한 배열의 0번째 요소에 접근하여 출력을 한다. 11번 라인에서는 배열 이름이 가지고 있는 값 즉, 배열의 시작 주소에 접근하여 해당 값을 출력하기 때문에 0번째 요소를 출력한다.

  • 포인터 연산

포인터를 이용하여 참조 뿐만 아니라 증감 연산이 가능하다. 다만 일반 수를 이용한 연산에 비해서 연산이 많이 제한 된다.  -> 가능한 연산자 수의 제한

포인터 연산에서 중요한 포인트

1.     덧셈, 뺄셈, 참조 연산만 가능하다.
->
곱셈, 나눗셈 등의 연산을 불가능하다.

2.     덧셈, 뺄셈 연산은 일반 수를 통한 덧셈, 뺄셈 연산과는 다르다.
->
포인터 연산에서의 +1과 수에 대한 +1에서 1은 각각 의미가 다르다.

다음은 포인터에 + 연산자를 이용하여 1씩 더하는 예제이다.

int, char, double 자료형 별로 배열을 선언하고, 각각에 대한 포인터 변수를 선언하여 각 배열의 첫 시작 주소(배열 이름)를 대입시킨 상황에서 각각 포인터 연산을 진행하는 예제이다.

먼저, 자료형에 상관없이 배열 이름과 인덱스를 이용하여 요소별 주소 값을 출력한 결과와 포인터 연산에 대한 결과를 출력한 결과가 모두 동일함을 알 수 있다. 그렇다면 도대체 + 연산자를 이용하여 포인터 변수를 포인터 연산한 것이 어떤 의미가 있길래 각 요소의 주소를 출력한 결과와 같은 결과인가?

 

1.     A의 결과에서 pArrpArr+1 값의 차이는 4이다.

2.     B의 결과에서 pCrrpCrr+1 값의 차이는 1이다.

3.     C의 결과에서 pDrrpDrr+1 값의 차이는 8이다.

 

단순히 포인터 변수에 +1 연산을 했을 뿐인데 그 증가의 차이는 자료형 별로 다른 결과가 나타났다. 포인터 연산은 피연산자로 오는 그 대상이 메모리 주소인 만큼 메모리 주소에 대한 연산이 이루어지는데 이 메모리는 무작정 작은 단위인 1바이트 별로 보는 것은 의미가 없다. int 형의 경우에는 4바이트 전부 참조해야 비로소 값이 의미가 있듯이 자료형 별로 최소 참조 바이트가 존재한다. 그렇기 때문에 주소에 대한 연산인 포인터 연산은 자료형 별 최소 참조 바이트를 반영하여 증감을 진행한다. 각 자료형 별로 포인터 연산에 대해서 1의 의미가 모두 다른 이유가 바로 이 때문이다. 1의 증감은 최소 참조 바이트 한 블록을 증감한다는 의미가 되기 때문이다.

포인터 연산에서 1의 의미는 sizeof(해당 자료형)*1 이 된다.
포인터 연산에서 2의 의미는 sizeof(해당 자료형)*2 이 된다.

포인터 연산에서 n의 의미는 sizeof(해당 자료형)*n 이 된다.

그렇다면 다음의 예는 무엇을 의미하는가?

*(p + 1)
p는 임의의 변수를 가리키고 있는 포인터 변수

이는 다음과 같이 해석할 수 있다.

P가 가리키고 있는 주소에 sizeof(해당 자료형) * 1만큼을 더한 주소를 참조(*)한다.

 다음은 그 예제이다.

위와 같은 포인터 연산에서의 성질과 예제를 통해서 알 수 있는 결론은 다음과 같다.

배열 이름[i] == *(배열 이름 + i)
혹은
포인터 변수[i] == *(포인터 변수 + i)

완전히 같다.

  • 문자열과 포인터

c언어에서 문자열을 표현할 때 두 가지 방법으로 표현한다.

1.     배열을 통한 문자열의 저장

2.     포인터 변수를 통한 문자열의 저장

먼저, 첫 번째 방법인 배열을 통한 문자열의 저장이다. 이 경우에는 str 배열의 길이가 자동 계산되어 각 인덱스 별로 문자를 하나씩 저장하여 해당 문자열의 끝에 ‘\0’을 저장함으로써 문자열의 저장이 비로소 완료되는 형태이다.

그러나 두 번째 방법인 포인터 변수를 통한 문자열의 저장의 경우이다.  c언어 프로그램 상의 모든 상수는 CPU를 이용한 연산의 대상이 되기 위해서는 해당 상수가 메모리 상에 적재되어야 한다. “hello, my name is yoo seung ho!” 문자열은 상수로서 메모리에 적재되고, 그 시작 주소인 ‘h’의 주소 값이 반환되어 pStr 포인터 변수에 대입이 된다.

대입 연산자를 기준으로 l-valuechar * 형이고, r-value는 문자열의 시작 주소 값 즉, char * 이기 때문에 대입 연산에는 아무런 문제가 없다.

각 두 경우는 위 그림의 왼쪽과 오른쪽 형태로 동작한다. 배열의 이름의 경우 포인터 상수이기 때문에 가리키는 타겟 문자열을 변경할 수는 없지만, 변수 형태, 배열에 값이 저장되어 있기 때문에 대상이 되는 문자열의 내용에 대해서는 변경이 가능하다. 포인터의 경우 포인터 변수이기 때문에 가리키는 타겟 문자열을 변경할 수 있다. 그러나 그 대상은 상수 형태의 문자열이기 때문에 대상이 되는 문자열의 내용에 대해서는 변경이 불가능하다.

사실은 아래와 같이 되는 것이다.

  • 포인터 배열

말 그대로 포인터 변수들로 배열을 이룬 형태를 말한다.

 

 

728x90
반응형

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

11 다차원 배열  (0) 2020.09.14
10 포인터와 함수  (0) 2020.09.13
08 포인터 기본  (0) 2020.09.11
07 1차원 배열  (0) 2020.09.11
06 함수와 변수의 생명주기  (0) 2020.09.10
728x90
반응형

포인터 기본

  • 포인터

포인터란 변수 형태의 포인터와 상수 형태의 포인터를 어우르는 표현

  • 포인터 변수

포인터 변수는 주소 값의 저장을 목적으로 선언되는 변수이다. c언어의 low 레벨 특성을 나타내는 요소이고, 이러한 포인터를 이용하여 메모리에 직접 접근이 가능하다.

  • c언어에서의 주소 표현

c언어에서는 메모리 상의 주소를 표현할 때 시작 번지만을 가지고 위치를 표현한다. 왜냐하면 각 자료형마다 지니는 바이트 값을 시작 주소로부터 더하여 계산하면 해당 변수의 끝 번지를 계산할 수 있기 때문이다.

  • 포인터 변수의 선언과 & 연산자

다음은 포인터 변수의 선언과 & 연산자의 활용 예를 나타낸다.

위의 예에서 시사해야 할 점은 두 가지이다. 첫 번째는 포인터 변수의 선언 및 사용이고 두 번째는 포인터 변수와 일반 변수의 크기의 차이이다.

먼저 포인터 변수의 선언 및 사용에 관한 이야기이다.

7번 라인에서 일반 변수를 선언하였고, 8번 라인에서는 * (asterisk) 를 이용하여 ‘ int * ‘ (정수형 포인터 타입) 형 변수 pNum을 선언하고 num시작 주소 값을 대입한다. (char, int, double 등과 같이 char *, int *, double * 등 또한 새로운 자료형 타입으로 인정해야한다.) 그리고 12번 라인에서 pNumnum 변수의 주소 값을 출력해 보았을 때 결과가 같은 결과로 나왔는데 이는 당연한 것이다. pNum에는 num시작 주소 값을 대입했기 때문이다. 이처럼 포인터 변수인 pNum은 일반 변수의 주소 값을 저장한다! 그리고 13번 라인에서 * 연산자를 이용하여 pNum이 지니고 있는 주소 값으로 직접 찾아가 직접 접근을 하여 직접 접근한 메모리에 들어 있는 값을 출력했다. 그렇기 때문에 num과 마찬가지로 출력 값이 100으로 같은 결과를 보였다. , *(Asterisk) 연산자는 포인터 변수가 저장하고 있는 주소에 접근 혹은 참조(= 포인터가 가리키고 있는 메모리에 접근 혹은 참조)하는 연산을 수행한다.

다음으로는 포인터 변수와 일반 변수의 크기 차이이다.

12번 라인에 해당하는 결과 num4, pNum8이 나왔는데 int라는 유사점이 있는 변수인데 이렇게 다른 결과가 표출되는 이유로는 포인터는 주소를 표현하는 변수이기 때문에 컴퓨터 시스템이 표현할 수 있는 메모리의 크기 범위와 밀접한 연관이 있다. 64비트 시스템에서는 2^64 만큼의 메모리 번지 표현 경우의 수가 존재하기 때문에 포인터 변수는 자연스럽게 8바이트(=64비트)를 나타내는 것이다. 포인터 변수의 크기는 자료형에 상관없이 컴퓨터 시스템의 메모리 범위에 따라 4바이트(32비트 시스템) 혹은 8바이트(64비트 시스템)로 표현된다.

그렇다면 포인터 변수에서 자료형을 어떻게 일치시켜서 대입해야 하는지, 자료형은 왜 필요한지에 대해 알아보자. 다음은 포인터 변수에 일반 변수의 주소 값을 대입 연산 시 일치시켜야 할 타입들에 대한 정리 표이다.

먼저, 자료형을 어떻게 일치시켜서 대입해야 하는지에 대한 정리이다.

어차피 포인터 변수의 크기는 다 똑같은데 포인터 변수에 타입이 필요한 이유가 무엇인가? 그 이유는 해당 포인터 변수에 저장된 시작 주소로부터 몇 바이트를 읽어 들여야 하고, 그 읽어 들인 값을 정수로 해석해야 할지, 실수로 해석해야 할지를 결정한다. , 포인터의 타입()은 메모리 공간을 참조하는 기준이 된다.

int a = 10;
int * p = &a;
printf(“ %d “, *p); //
이 문장에서 p를 참조할 때 int * 는 참조의 기준이 된다.

  • 포인터의 잘못된 사용과 널 포인터

잘못된 초기화

int * ptr = 1234; // 1234 번지로 들어가게 된다.
*ptr = 100; // 1234
번지는 메모리 상에 중요한 프로그램이 적재되어 있을 수 있는데 해당 공간의 값을 변경 -> 에러

초기화 할 경우에는 NULL 포인터로 초기화를 한다. 아무 곳도 가리키지 않음을 의미한다. ( 0번지 의미가 아님 )

int * ptr = NULL; // 아무 곳도 가리키지 않는 포인터.


728x90
반응형

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

10 포인터와 함수  (0) 2020.09.13
09 포인터와 배열  (0) 2020.09.12
07 1차원 배열  (0) 2020.09.11
06 함수와 변수의 생명주기  (0) 2020.09.10
05 반복과 분기  (0) 2020.09.08
728x90
반응형

1차원 배열

  • 배열

둘 이상의 변수를 모아 놓은 것.

  • 배열의 선언

일반 변수의 선언과 같다.

‘ 자료형 + 배열 이름 + 길이 정보(인덱스) ‘ 형식.

위의 선언을 메모리 공간 상의 그림으로 표현하면 다음과 같이 나타낼 수 있다.

arr 배열

 

  • 배열의 접근

배열의 인덱스는 배열의 개수를 [n] 으로 두었을 때, 0부터 시작하여 n-1까지 존재하며 [0]은 첫 번째 요소를, [n-1]은 마지막 요소를 나타낸다.

  • 배열의 선언과 동시에 초기화

다음은 배열의 선언과 동시에 초기화하는 예이다.

여기에서 우리는 중괄호 내의 초기화 값 리스트를 ‘초기화 리스트’ 라 부른다. 8번 라인의 경우에는 일반적인 선언과 동시의 초기화 방법이다. 9번 라인의 경우는 배열의 길이 정보가 주어지지 않은 상태인데 이는 초기화 리스트를 보고 자동으로 계산하여 배열의 길이가 세팅 된다. (위의 예에서는 5) 마지막으로 10번 라인의 경우는 배열의 길이보다 적은 초기화 리스트가 오게 되는데 0번째 인덱스부터 순차적으로 초기화 리스트의 값들이 할당되고 할당할 초기화 값이 없는 인덱스 요소에 대해서는 전부 0으로 자동 초기화한다.

  • 배열 이름을 대상으로 하는 sizeof 연산자



sizeof(배열이름); 을 실행할 경우, ‘ 바이트 단위의 배열의 크기 ’가 반환된다.

  • 문자 배열과 문자열 배열

같은 ‘ hello ‘를 표현하는 배열인데 두 배열은 전혀 다른 배열이다. 9번 라인은 문자만을 저장한 문자 배열이고, 12번 라인은 문자열을 저장한 문자열 배열이다. c언어에서 배열에 문자열을 저장할 때에는 ‘\0’ 이라는 문자열의 끝을 나타내는 특수 문자인 널(null) 문자를 문자열의 제일 끝에 자동으로 삽입하여 대입 및 저장을 행한다. ( 이는 문자열을 입력 받는 라이브러리를 통한 변수로의 입력 시에도 마찬가지로 null 문자의 자동 삽입이 이루어진다. )
null문자를 이용하여 메모리 공간 상에서 배열 이름의 첫 번지부터 어디 까지가 의미 있는 문자열의 끝인지를 확인한다. 또한 이러한 문자열 배열에 대한 입출력 서식 문자는 ‘ %s ‘ 로 사용한다.

728x90
반응형

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

09 포인터와 배열  (0) 2020.09.12
08 포인터 기본  (0) 2020.09.11
06 함수와 변수의 생명주기  (0) 2020.09.10
05 반복과 분기  (0) 2020.09.08
04 상수와 자료형  (0) 2020.09.07
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
반응형

반복과 분기

  • 반복

반복을 명령하는 문장

While

왼쪽과 같은 형식으로 while문의 중괄호 속 내용을 반복하여 실행하는데 조건이 참인 경우에만 반복 내용을 실행하고, 조건이 거짓이 되는 순간을 꼭 만들어 주어야 한다. , 탈출 조건을 만들어 주어야 하는데 그 탈출 조건은 소괄호 속 조건과 반복 카운터 변수의 증감을 통해 이룰 수 있다.



For

역할은 while문과 완전히 같지만 형식이 주어져서 더욱 보기 깔끔하다 그러나 코딩의 유연성은 while문에 비해서 조금 떨어진다. for문의 동작 순서는 while문과 완전히 같다.

초기문 -> 조건문 -> 반복 내용 -> 증감문 -> 조건문 -> 반복 내용 -> 증감문 -> ~ -> 조건문 -> for문 종료

위와 같은 순으로 반복한다.



Do-While

위와 같은 형식으로 반복을 진행하는데, 다른 반복문과 다른 특이한 점은 반복 내용을 한 번은 무조건 실행하는 경우에 사용한다. Do~While 문은 조건과 상관없이 딱 한 번은 무조건 실행하게 되어 있다. 왜냐하면 조건을 밑에서 검사하는 형식이므로.

 

  • 분기

프로그램을 처음부터 끝까지 모두 실행하는 형태가 아닌 프로그램의 흐름을 원하는 형태로 제어하기 위한 구문.

If

아주 간단하게 소괄호 내의 조건이 만족하면 (참이면) 반복 내용을 실행하고, 만족하지 못하면 중괄호 속에 해당하는 내용은 통째로 실행하지 않고 뛰어 넘는다.

다음과 같이 중괄호의 생략도 가능한데 이러한 경우는 반복할 문장이 한 줄일 때만 가능하다.

다음과 같이 else 를 이용하면 위의 if 조건을 만족하지 않은 모든 경우를 다 받아들이는 구문이 존재한다. 여기서 기억해야하는 중요한 포인트는 else는 위의 if 조건에 부합한 모든 경우들을 수용하기 때문에 따로 조건 검사를 하지 않는다는 것이다. 위와 같은 포인트를 잘 기억하고 다음을 보도록 하자.

다음과 같이 여러 조건을 if문으로 채우는 경우에는 모든 조건을 하나하나 검사하게 된다. 예를 들어 사칙 연산을 택하는 프로그램이 존재할 때 더하기, 빼기, 곱하기, 나누기의 총 네 개의 연산이 존재하지만 결국 선택되는 연산은 하나이다. 그러므로 한 가지 연산이 선택되었을 때에는 나머지 연산에 대해서는 확인하는 작업은 필요로 하지 않다. 다만, if문으로 제시되는 조건들이 모두 연관이 있는 하나의 주제에서의 선택에 대한 조건임을 전제로 한다.

왼쪽의 경우가 하나의 주제에 대해서 선택을 할 때, 모든 조건을 다 검사하는 소스이고, 오른쪽의 경우는 어떤 조건을 만족하게 될 경우 그 조건보다 아래에 오는 조건들은 자연스럽게 무시하는 경우의 소스이다. 이것이 가능한 이유는 위에서 언급한 두 가지 조건으로 인해 가능해진다.

  1. 실행할 문장이 한 줄일 경우에는 중괄호를 생략할 수 있다.

  2. else는 위의 라인의 if 조건에 부합한 모든 경우들을 수용하기 때문에 따로 조건 검사를 하지 않는다

이 두 전제에 의해서 else if 라는 문장이 생긴다.

원래 형태의 소스이고, 이 부분에서 두 가지 전제를 적용하여 중괄호를 없애게 되면 else if 구문을 확인할 수 있다. else 바로 밑의 조건문은 모두 유기적으로 연관되어 있기 때문에 if 문과 함께 한 줄로 취급하는 것이다. 그렇기 때문에 else의 중괄호를 생략할 수 있는 것이다.

결국, if, else if, else 구문은 ifelse 구문을 중첩시킨 형태에 지나지 않는다.

조건 연산자(삼항 연산자)

If 조건문을 대체할 수 있는 조건 연산자이다. 다음과 같은 형식을 지니고 ‘?’, ‘:’ 두 개의 연산자와 세 개의 피연산자를 이용하여 조건에 대한 결과 반환을 수행한다.

다음은 위와 따른 예제이다.

Switch~Case

스위치~케이스문은 if문과 마찬가지로 분기를 통한 프로그램의 흐름을 제어해주는 방법 중 하나인데 if문과는 구조가 많이 다르고 조금은 제한적인 형태로 구성되어 있지만 간결하고 가독성이 좋아진다는 장점이 있다.

switch 키워드 옆 소괄호에는 분기 선택에 대한 정보가 담겨 있는 ‘정수형’ 변수가 인자로 전달되어야 한다. 그리고 그 전달된 값을 case 별로 나눈 것이 11, 14, 17번 라인이다. 여기서 짚어야 할 포인트는 분기의 조건으로 범위가 올 수 없고, 떨어지는 값의 형태로 분기가 일어난다는 것이다. 그리고 해당 case부터 break; 부분 사이의 실행 내용을 실행한다. breakswitch문 하나를 탈출하는 분기이며 반복문과는 관련이 없다. 만약 break를 생략하게 되면 전달되어온 인자의 값과는 상관없이 다음 case 영역의 break문 전까지 모조리 실행하게 된다. 그리고 마지막으로 default는 위에서 정의된 모든 case 분기에 빠지지 못한 경우는 모두 이 default 영역으로 분기된다. else와 같은 역할이라고 보면 된다.

goto

레이블을 이용하여 분기를 제어하는 형태이다.

‘ 레이블: ’ 형식으로 레이블을 마킹한 후, ‘ goto 마킹한_레이블명; ‘ 명령어를 통해 프로그램의 흐름을 마킹한 레이블 라인으로 변경한다.

goto문은 절차지향의 패러다임에 위배되는데 그 이유는 위에서 아래로의 순차적인 실행이 아니라, 뒤죽박죽 어느 라인의 위치이든 간에 상관없이 흐름 변경이 가능하다. , 프로그램의 자연스러운 흐름을 방해하기 때문이다.

Continue & Break

먼저, continue문이다.

위와 같은 형식을 갖추며 continue를 감싸고 있는 가장 가까운 반복문의 조건 검사 위치로 이동한다. 단순히 반복문의 상단으로 프로그램의 흐름이 이동하는 것이 아니라, 조건을 찾아가는 것이다. , do~while문에서는 위로 가는 것이 아닌 하단의 조건 위치로 프로그램의 흐름이 변경된다. 그리고 for문에서 continue문을 실행하게 될 경우에는 조건문을 실행하기 이전에 증감문 또한 실행한 뒤 조건문을 실행하러 상단으로 위치한다.

다음은 break문이다.

위와 같은 형식을 갖추며 break를 감싸고 있는 가장 가까운 반복문 하나를 탈출한다. 중첩된 반복문에서도 마찬가지로 break를 감싸고 있는 가장 가까운 반복문 1개’만 탈출한다.

728x90
반응형

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

07 1차원 배열  (0) 2020.09.11
06 함수와 변수의 생명주기  (0) 2020.09.10
04 상수와 자료형  (0) 2020.09.07
03 수의 표현 방식  (0) 2020.09.06
02 변수와 연산자  (0) 2020.09.06
728x90
반응형

자료형과 상수

  • 자료형

자료형은 데이터를 표현하는 기준이고, 변수와 상수는 이 자료형에 근거하여 선언된다.

변수를 선언하기에 앞서 자료형을 결정하는 방법

  1. 어떤 정보를 저장할지 정보의 타입을 결정
    EX)
    정수를, 문자열을, 실수를 저장

  2. 어느 정도의 크기를 저장할 것인지 적절한 크기를 결정
    EX) (
    정수) 4바이트 정도, (문자열) 20바이트 길이 정도

예를 들어, 정수를 저장할 것이고, 크기는 4바이트 정도로 할께요 -> int

다음은 자료형의 저장 가능한 타입과 크기, 표현 범위를 나타낸 표이다.

이토록 다양한 자료형을 제공하는 이유는?

  1. 데이터의 표현 방식이 정수와 실수로 나뉘므로 최소 두 개의 종류가 보장되어야 한다.

  2. 메모리 공간의 효율적인 사용을 위해 같은 데이터 방식(정수 혹은 실수)이더라도, 다양한 크기로 제공되어야 한다.

sizeof 연산자를 이용한 자료형의 크기 확인

다른 자료형에도 마찬가지로 똑같이 적용되고, 10번 라인의 경우처럼 변수의 이름이 전달될 경우 해당 변수의 전체 크기를 계산한 결과를 반환한다. , 배열의 경우 자료형 x 배열의 개수를 구하고, 반환한다는 의미.

  • 정수 표현에서의 일반적인 자료형의 선택

short, char 형으로 선언한 변수를 이용하여 계산을 하였는데도 불구하고(10라인) 덧셈을 한 결과가(11라인) 1바이트, 2바이트가 아닌 4바이트 형태로 계산되었다.

-> CPU가 정수 연산을 할 때 가장 적합한 크기의 정수 자료형을 int 로 정의하였고, 그로 인해 다른 자료형의 연산 속도보다 같거나 빠르기 때문에 int 형 연산으로 변환하면서까지 연산을 진행한다.

-> 연산의 속도는 int형이 효율적이고 빠르지만, 데이터의 크기를 중요시하는 곳에서는 char, short를 사용하는 것이 중요하다.



  • 실수 표현에서의 일반적인 자료형의 선택

실수에서 중요한 요소는 ‘정밀도’이다. 실수에서는 부동 소수점 오차가 발생하기 때문에 정확하게 값을 표현해낼 수 있는 소수점 이하의 자릿수가 존재하는데 이것이 바로 ‘정밀도’ 이다.

다음은 실수 자료형에서 정밀도를 나타내는 표이다.

실수 자료형에서는 doubleint와 같은 역할로 선택되어진다.

Doublefloat 자료형 변수를 선언한 후, 값을 각각 입력 받고 출력하는 예제인데 floatdouble 자료형의 출력 시 서식 문자는 같음을 알 수 있지만 입력 시 서식 문자는 다름을 확인할 수 있다.

  • 문자의 표현 방식

문자를 표현할 때는 아스키(ASCII) 코드를 이용한다. , 정수 값과 문자를 매칭하여 내부적으로는 정수로 연산하지만 이를 표현할 때에는 해당 정수 값에 맵핑 되어 있는 문자를 출력 및 표현을 한다.

8번 라인을 봤을 때 문자는 작은 따옴표( ‘ )로 감싸져 표현이 되고, 이 때 ch 변수에 값이 저장될 때에는 ‘a’라는 문자 형태의 값이 들어가는 것이 아니라 ‘a’의 아스키 코드 맵핑 값이 저장됨을 10번 라인을 통해 알 수 있다.

  • unsigned 0과 양의 정수 표현

    - 정수 자료형의 이름 앞에만 unsigned를 붙일 수 있다.

    - Unsigned 키워드가 붙을 시에는 부호 비트(MSB) 도 데이터를 표현하는데 사용이 된다. (부호가 사라짐)

    - 표현할 수 있는 값이 0 이상의 범위로 두 배가 된다.

  • 상수

상수는 이 자료형에 근거하여 선언되며, 리터럴(literal) 상수와 심볼릭(symbolic) 상수로 나뉘어진다. 자료형에 근거 되어 선언되는 이유는 CPU의 연산 대상이 되려면 메모리 상에 적재되어 CPU가 접근할 수 있는 주소를 할당 받아야 하기 때문이다. -> 모든 상수는 메모리에 할당된다.

먼저 이름을 지니지 않는 리터럴 상수이다.

위와 같은 예가 리터럴 상수의 예이다. 8번 라인에서는 1020int, 10.120.2double형으로 메모리에 적재된다.

앞서 일반적으로 연산 효율이 좋고, 넓은 정밀도로 인해 선택되어 지는 int형과 double형으로 상수의 자료형이 될 수 있고 자료형이 결정되는 요인은 대입 연산자 왼편의 자료형에 따른 것이 아니라 상수 자체의 종류에 따라서 결정되는 것이다.

두 자료형 이외의 값을 이용하여 자료형을 할당하기 위해서는 형 변환 혹은 접미사를 이용한다. 다음은 접미사를 활용하여 상수 자료형을 할당하는 예이다.

다음은 이름을 지니는 심볼릭 상수이다.

심볼릭 상수는 이름이 존재하는 상수이기 때문에 상수가 존재하는 해당 라인을 넘기더라도, 재 사용이 가능하며 이름을 활용하여 대입 연산자를 통해서 값의 변경을 방지하여 값을 변경하면 에러가 발생하도록 하는 특징을 지니고 있다.

심볼릭 상수 선언의 첫 번째 방법은 const 키워드를 이용한 변수의 상수화다.

위와 같이 const 키워드를 이용하여 변수를 상수화 하게 될 경우에는 선언과 동시에 초기화를 해야 하고, 이름을 통한(혹은 그 외의 어떤 방법으로도) 값의 변경은 금지된다.

두 번째 방법은 매크로를 이용한 방법이다.

  • 자료형의 변환

자료형에서 가장 중요한 것은 모든 연산은 완벽하게 같은 자료형끼리 연산이 가능하다는 점이다. 특히 대입 연산 시에도 대입 연산자를 기준으로 왼편(l-value)과 오른편(r-value)의 형(type)이 일치해야 한다. 다른 연산자의 경우에도 마찬가지이다. 자료형이 다름에도 불구하고 오류 없이 연산이 가능한 이유는 자료형의 형 변환(자동, 묵시적)이 이루어졌기 때문이다.

자동 형 변환(묵시적 형 변환)

먼저, 대입 연산 시 값을 전달하는 과정에서 자동으로 발생하는 형의 변환이 존재한다.

10번 라인에서 실수형 변수에 정수형 값을 넣었고, 11번 라인에서 정수형 변수에 실수형 값을 넣었다. 다음은 이에 대한 출력 결과이다.

결과에서 알 수 있듯이 11번 라인에서의 대입은 0.14에 해당하는 값이 모두 손실되었다. 정수형 자료형은 실수를 표현할 수 없기 때문이다.
또한, 바이트 크기가 큰 변수를 바이트 크기가 작은 변수로 형 변환하는 경우에는 상위 바이트의 손실로 인해 부호가 변경되거나, 값이 훼손될 수 있다.



다음은 정수의 승격에 의한 자동 형 변환이다.
정수형 연산에서 일반적인 자료형의 선택 시 int형으로 변환되어 연산이 진행되기 때문에 shortchar 등의 자료형으로 연산을 진행하더라도 int 형으로 변환 되어 연산이 진행된 후 다시 원래 자료형으로 다시 변환이 이루어 진다.

다음은 연산 시 피연산자의 자료형 불일치로 발생하는 자동 형 변환이다.

이와 같은 경우에서 double <- int + double의 형태인데 연산을 진행함에 있어서 두 피연산자의 자료형이 서로 다를 때에는 자료형을 통일시켜주어야 하는데 이 경우에 강제적으로 형 변환을 하지 않는 이상 피연산자의 자동 형 변환이 발생한다.
이 때, 어느 자료형을 어떤 자료형으로 변환시켜줄 것인지를 정해야 한다. 변환할 자료형, 변환될 자료형의 선택은 다음과 같은 규칙으로 진행하면 된다.

데이터의 손실을 최소화하는 방향으로 자료형을 선택

int형과 double형이 피연산자로 오는 경우에는 int형을 double형으로 변경하는 것이 데이터의 손실이 최소화하는 방향이다.

그리고 다음은 최소화하는 방향의 우선 순위를 나타낸 것이다.

우선 순위의 기준은 단순히 바이트 크기가 아니라, 정수와 실수 즉 ‘소수부의 손실’을 고려한 순위 기준이다. long long형과 float형을 보면 알 수 있다.



강제 형 변환(명시적 형 변환)

명시적인 형 변환은 형 변환 연산자를 이용하여 강제로 자료형을 변환하는 방법이다.

위와 같은 예에서 num1num2의 자료형은 서로 같기 때문에 정수형으로써 나눗셈이 진행되므로 결과 값은 0이 되고 대입 시 일어나는 자동 형 변환으로 인해 실수형 0num에 저장된다. 이러한 경우에 강제 형 변환을 이용하게 되면 다음과 같다.

위와 같이 num1을 강제로 double형으로 형 변환시키면 피연산자 불일치와 연산자 변환 우선 순위에 의거하여 num2 또한 double형으로 자동 형 변환이 이루어져 실수 연산이 이루어지고 그 값이 그대로 num으로 대입된다.

, 강제 형 변환 연산은 다음과 같은 형태로 이루어진다.

(자료형) 형 변환할 변수 혹은 상수

728x90
반응형

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

06 함수와 변수의 생명주기  (0) 2020.09.10
05 반복과 분기  (0) 2020.09.08
03 수의 표현 방식  (0) 2020.09.06
02 변수와 연산자  (0) 2020.09.06
01 C언어의 첫 기본 예제  (0) 2020.09.06
728x90
반응형

수 표현 방식

  • 컴퓨터의 연산

컴퓨터는 2진수를 기반으로 데이터를 표현하고 연산을 진행한다.

16진수는 2진수를 간단하게 표현할 수 있기 때문에 편의 상 사용함.
이러한 2진수로 데이터를 표현하는데, 데이터 표현에는 단위가 존재함.

 

  • c언어에서의 진수의 표현

각 진수에 해당하는 서식 문자 및 접두어는 다음과 같다

  • 정수와 실수의 표현 방식

먼저, 정수의 표현 방식은 다음과 같다.

정수의 가장 왼쪽에 존재하는 비트는 ‘부호비트(MSB)’.
양수일 때는 부호 비트를 제외하면 일반 2진수 수 표현과 같다. 그러나 음의 정수를 표현할 때에는 2의 보수를 취한다. ( 2의 보수 방법 : 1의 보수 -> +1 )

실수의 표현 방식은 조금 다르다.

위와 같은 식을 정의하여 넓은 범위의 실수를 표현함.
그러나 지수 형태의 식을 이용하여 실수를 표현하는 것이기 때문에 오차가 존재한다. 단적인 예로 me에 적절한 값을 넣어서 0.0을 만들어보면 실감함.

이러한 오차를 ‘부동 소수점 오차’ 라고 한다. 다음은 부동 소수점 오차의 예를 보여주는 예이다.



728x90
반응형

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

06 함수와 변수의 생명주기  (0) 2020.09.10
05 반복과 분기  (0) 2020.09.08
04 상수와 자료형  (0) 2020.09.07
02 변수와 연산자  (0) 2020.09.06
01 C언어의 첫 기본 예제  (0) 2020.09.06
728x90
반응형

연산자와 변수

  • c언어에서의 연산

c언어에서 연산에 사용되는 모든 값은 변수 혹은 상수 등의 형태로 메모리 상에 저장된 후, 연산이 진행됨. (연산이라 함은 단순 사칙연산 뿐만 아니라, 출력, 입력 등도 포함)

위와 같은 예에서 11은 메모리 상에 상수의 형태로 저장된 후, 그 저장된 메모리를 이용하여 연산을 진행
위와 같은 경우에는 값이 고정된 상수이기 때문에 다른 라인에서 값의 변경이 불가능함. -> 변수 개념으로 해결

  • 변수

변수란? 값을 저장할 수 있는 메모리 공간에 붙은 이름, 혹은 메모리 공간 그 자체를 나타낸다.

이러한 변수라는 개념을 이용하여 변수에 값을 저장하고 그 값을 이용하여 연산을 진행한다. 다만, 상수와 다른 점은 변수가 선언된 아래 라인에서 변수가 지는 값을 변경하고, 변경된 값을 토대로 재연산이 가능하다는 점.

먼저, 변수의 선언이다.

자료형 + 변수의 이름

위와 같은 형태로 변수의 선언이 이루어진다. 여기서 자료형에 대한 기재는 내가 생성할 변수에 어떤 타입(Type)의 값이 올 것인지를 컴파일러에게 명시해주는 것이고, 변수의 이름에 대한 기재는 말 그대로 메모리 공간에 붙여줄 이름을 명시해주는 것이다.

자료형의 종류와 변수의 이름을 지을 때의 명명 규칙에 대해 아래에 기재

<자료형>

<명명 규칙>

다음은 변수의 선언 및 초기화이다.

6번 줄부터 9번 줄까지 총 5개의 변수가 선언되었는데, 각각 여러 문법적인 요소를 지닌다. line 7에서는 정수형 자료형으로 변수를 선언하였고, 선언함과 동시에 2라는 값을 대입 연산자(=, 대입)를 통하여 초기화를 시켜주었다. 이를 ‘선언과 동시에 초기화 한다’ 라고 표현한다. 그리고 line 8에서는 선언과 동시에 초기화를 하되, 콤마 연산자( , )를 통하여 정수형 변수 num3num4를 한번에 선언하고 동시에 초기화를 진행한다. 또한 line 6에서는 num1을 선언만 하고 초기화는 행하지 않았으나 line 11에서 첫 대입이므로 초기화가 이루어졌고, 그 이후 line 12에서 일반 대입이 이루어졌다. 그리고 마지막 line 9에서는 선언만 진행하고 초기화가 이루어지지 않았는데 이런 경우에는 num4의 메모리 공간에는 쓰레기 값이 자동으로 채워진다. 사실 채워지는 것이 아니라 해당 메모리 공간에 원래 존재하고 있던 어떤 값이 보여지는 것이다.

변수 선언 시 주의 사항 : 중괄호 내에 변수를 선언할 경우에는 중괄호의 앞부분에 변수의 선언을 위치시킨다.

  • 연산자

  • 키보드로부터 값을 입력 받기

프로그램이 번역된 후 실행하는 중에 값을 변수에 저장할 수 있는 방법.

scanf 함수에서 첫 번째 인자, 큰 따옴표 사이의 Format으로 입력을 받는데, 나타낸 서식 문자 순서대로 이후 인자들에 차례로 값이 저장된다. %c, %d, %f, %lf 는 변수 명 앞에 &를 붙인다. 포인터와 관련된 이야기.

scanf 함수는 스페이스, 엔터 등의 공백으로 입력과 입력을 구분 지으며, 첫 번째 인자로 주어진 형식으로 입력을 받는다. 형식을 지키며 입력하라는 말이다.

728x90
반응형

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

06 함수와 변수의 생명주기  (0) 2020.09.10
05 반복과 분기  (0) 2020.09.08
04 상수와 자료형  (0) 2020.09.07
03 수의 표현 방식  (0) 2020.09.06
01 C언어의 첫 기본 예제  (0) 2020.09.06
728x90
반응형

기본

  • Hello, C-World 프로그램

2번 라인에서 “stdio.h” 라고 하는 Header File을 포함시키는 역할을 하는데, stdio.h 파일 안에는 표준 입출력 라이브러리 함수들이 정의 및 선언이 되어 있다.

4번 라인의 경우 main 함수이다. C언어로 만들어진 프로그램이 실행될 때에는 운영체제가 제일 먼저 main 함수를 호출하고, main 함수의 내용이 실행되면서 프로그램이 구동된다.

함수는 다음과 같은 구조를 갖는다.

< 함수의 정의와 개략적인 함수 >

입력 타입에는 함수가 입력 값으로 인자를 받는 매개 변수들을 나열할 수 있고, 출력 타입에는 return 다음에 올 수 있는 반환 값의 타입을 기재한다.

6번 라인의 경우 stdio.h 헤더 파일 안에 정의 및 선언되어 있는 printf 함수를 이용하여 큰 따옴표로 둘러 쌓인 문자열을 출력한다. C언어에서는 큰 따옴표로 둘러 쌓인 것을 문자열, 작은 따옴표로 둘러 쌓인 것은 문자를 나타낸다.

8번 라인에서 출력 타입에 맞는 반환 값을 반환한다. Main 함수에서 값을 반환하는 이유는 함수를 호출한 운영체제에게 함수가 정상적으로 종료됐음을 알리기 위해서 0 값을 반환한다. 일반 함수의 경우에는 마찬가지로 정상 종료 및 값의 전달을 위해서 반환 값을 지정한다.

 

728x90
반응형

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

06 함수와 변수의 생명주기  (0) 2020.09.10
05 반복과 분기  (0) 2020.09.08
04 상수와 자료형  (0) 2020.09.07
03 수의 표현 방식  (0) 2020.09.06
02 변수와 연산자  (0) 2020.09.06

+ Recent posts