배열(Array)과 포인터(Pointer)

 

 제목을 배열과 포인터라고 한 이유는, 배열을 이용해 포인터를 사용하고 포인터를 이용해 배열을 사용하기 때문입니다. 포인터는 주소를 가리키는 것인데, 배열은 메모리 일정공간에 연속으로 존재하기때문에, 배열을 이용해 포인터를 사용할 수 있습니다.

 배열의 주소는 어떻게 표현할까요? 변수의 주소처럼 &를 붙여 &arr[0]이렇게도 표현할 수 있지만, 배열의 이름 자체가 배열의 첫번째 원소의 주소입니다. 배열의 이름을 포인터 상수 라고도 하는데, 포인터 상수는 주소값의 변경이 불가능합니다.


 아래 코드는 정수형 변수와 배열의 주소 비교입니다. 

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

#include <stdio.h>


int main()

{

int a, b, c;

int d[3];

printf("a : %d, b : %d, c : %d \n",&a,&b,&c);

printf("d[0] : %d d[1] : %d d[2] : %d \n", &d[0], &d[1], &d[2]);

return 0;

}

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

 배열의주소는 int형이라 4바이트씩 즉 4씩 차이가나고, int형 변수 a,b,c는 규칙없이 각기 다른 주소에 저장되었습니다.

 

 이제 배열을 이용해 포인터를 사용해 보겠습니다. 아래 코드는 배열에 hello 라는 문자열을 넣고 포인터 변수를 선언해 주소를 가리킨뒤에 포인터를 출력해보는 코드입니다.

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

#include <stdio.h>


int main()

{

char text[6] = "hello"; // 널값을 포함한 문자열의길이 6바이트

char *pointer; // 포인터 변수 선언

pointer = text; 


printf("text : %s \n", text); // 배열주소의 값 출력

printf("pointer : %s \n", pointer); // 포인터가 가리키는 주소의 값 출력

printf("--------------- \n");

int i;

for (i = 0; i < 5; i++){

printf("%.1s \n",pointer+i); // 맨 앞글자만 출력

}

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

 아래 결과를 보면 포인터 변수 역시 배열의 주소를 가리켜서 같은 hello가 출력이 됩니다. 원소를 한글자씩 출력하기위해서 반복문안에 출력문을 포맷을 %.1s로 지정했는데, %s로 지정 하면 포인터가 가리키는 주소도 1씩 증가해서 hello, ello, llo, lo, o가 출력이됩니다.


포인터 변수는 사용자의 입력을 받을때의 변수로도 사용할 수도 있습니다. 

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

#include <stdio.h>

#pragma warning(disable:4996)


int main()

{

int input;

int *pointer;

pointer = &input;


printf("정수 입력 : ");

scanf("%d", pointer);

printf("입력된 정수 : %d \n", *pointer);

}

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


 마지막으로, 포인터 변수를 이용해서 문자열을 입력받아 대문자는 소문자로 소문자는 대문자로 바꾸는 코드를 작성해 봤습니다. 포인터 변수로 입력을 받고, 출력은 배열로 했습니다.

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

#include <stdio.h>
#pragma warning(disable:4996)

int main(){

char change[10];
char *input;
input = &change;

printf("영문을 입력하시면 대소문자가 서로 변환됩니다. 입력 : ");
scanf("%s", input);

while (*input){ 
if (*input >= 'A' && *input <= 'Z') // 대문자일 경우
{
*input = *input + 32;
}
else if (*input >= 'a' && *input <= 'z') // 소문자일 경우
{
*input = *input - 32;
}
input++;
}
printf("변환된 문자 : %s \n", change);
}

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

조건문에서 왜 +32, -32 연산을 하는지 이해가 안되시는분은 조건문 게시글 http://parkdream.tistory.com/11 을 참고하시면 됩니다. 

 *input+32, -32 대신 *input-'A'+'a' *input-'a'+'A'를 사용하셔도 됩니다.

결과는 아래와 같이 대소문자가 서로 바뀌어서 출력됩니다.


* 출처 : 한국기술교육대학교 온라인평생교육원 C 프로그래밍_2 

          스타일 C프로그래밍 저.김종훈,김종진 출.WellBook




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

[C] 공용체  (0) 2016.12.27
[C] 구조체  (2) 2016.12.26
[C] 포인터  (0) 2016.12.23
[C] 배열  (0) 2016.12.23
[C] 디버깅  (0) 2016.12.21

포인터(Pointer)


 C언어가 고급 언어이면서, 저급 언어로도 불리는 가장 큰 이유는 메모리를 직접 제어할 수 있는 포인터 때문입니다. 포인터는 주어진 메모리를 가리키는 것으로, 메모리 공간에 대한 이해가 필요합니다. 우선 메모리 공간에 대해 알아보겠습니다. 


- 메모리 공간

 메모리 공간은 순서대로 정렬되어있는 연속된 값으로, 메모리 주소당 1바이트의 크기를 가집니다. 메모리는 여러 의미가 있지만, C언어에서는 변수가 사용하는 공간으로, 변수를 선언하게되면 일정 메모리 공간을 점유하게됩니다. 


- 포인터

 포인터는 "자료형 *변수이름;" 과 같이사용하며, 주소를 사용하는 것과 메모리 주소로 사용하는것이 있습니다. 아래 코드를 보면, 포인터는 변수 a의주소를 가리키므로, pointer를 출력하면 a의 주소가 출력되고, *pointer를 출력하면 변수 a의값인 10이 출력됩니다.

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

#include <stdio.h>


int main()

{

int a=10;

int *pointer;

pointer = &a;

printf("a : %d \n", a);

printf("&a : %d \n", &a);


printf("pointer : %d \n", pointer);

printf("*pointer : %d \n", *pointer);


return 0;

}

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

 

- 포인터 주소값 조작

포인터의 주소값을 이용해서, 주소값을 조작할 수 있습니다. 다음과 같이 정수형, 문자형, 부동소수형 변수를 선언한뒤에 주소값을 1씩 증가시켰습니다. 결과값이 어떻게 출력될까요?

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

#include <stdio.h> 

int main()
{
int a=10;
char b='a';
double c=3.14;

int *ptr1;
char *ptr2;
double *ptr3;

ptr1 = &a;
ptr2 = &b;
ptr3 = &c;

printf("ptr1 : %d \nptr1+1 :%d \n", ptr1, ptr1 + 1);
printf("ptr2 : %d \nptr2+1 :%d \n", ptr2, ptr2 + 1);
printf("ptr3 : %d \nptr3+1 :%d \n", ptr3, ptr3 + 1);

}

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

 결과를 보면 주소가 int형은 4만큼, 문자형은 1만큼, 부동소수형은 8만큼 증가했죠? 메모리공간에 각각 4,1,8바이트의 크기를 가지기 때문에 주소를 1증가하면, 자료형의 크기만큼 증가합니다.

 자료형의 크기가 기억 나지 않는분들은 http://parkdream.tistory.com/4 글을  참고하시면 됩니다.


* 출처 : 한국기술교육대학교 온라인평생교육원 C 프로그래밍_2 

          스타일 C프로그래밍 저.김종훈,김종진 출.WellBook




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

[C] 구조체  (2) 2016.12.26
[C] 배열과 포인터  (3) 2016.12.25
[C] 배열  (0) 2016.12.23
[C] 디버깅  (0) 2016.12.21
[C] 매개변수 전달 방식  (0) 2016.12.20

배열(Array)


 배열은 변수들을 연속으로 선언해서 일괄적으로 사용하는 자료형입니다. 배열은 일차원 배열과 다차원 배열로 나뉘며, 앞에서 공부할 때 몇번 활용한 적이 있습니다. 배열 없이 정수형 변수 5개를 선언할 경우 int a,b,c,d,e; 처럼 일일이 직접 선언해야하는데 배열을 사용하면 int a[5]; 처럼 한번에 선언할 수 있습니다. 배열을 전달할 경우 참조 전달이 되기 때문에 *이나 &를 붙이지 않아도 됩니다. 


- 배열

 배열의 사용은 아래와 같습니다. 인덱스는 0부터 시작하며, 변수도 사용 가능합니다. 한가지 주의할 점은 배열은 한가지 자료형으로만 구성해야하며, 선언된 배열의 길이를 초과하는 인덱스를 사용하면 안됩니다.

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

타입 변수명[인덱스]

int a[5]; 

int b[];

int c=5; 

int d[c]; 

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

 배열에 값을 넣을 때, 초기화하면서 선언할수는 있지만, 선언한뒤에 값을 한번에 넣지는 못합니다.

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

int a[3]={1,2,3};   (가능)

int b[3];

b={1,2,3};          (불가능)

→ b[0]=1; b[1]=2; b[2]=3; (가능) b[3]=4: // 배열의 길이를 초과하므로 불가능

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




- 다차원 배열

 다차원 배열은 배열을 원소로 가지는 배열을 뜻합니다. 아래와 같이 사용하며 부분적으로 초기화가 가능합니다.

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

 int a[3][3]={1,2,3,4,5,6,7,8,9}; 
위와 같이 초기화 하는 경우 배열에는 아래 표와같이 값이 들어갑니다. 
int a[][3]={1,2,3,4,5,6,7,8,9}로 초기화할 경우, 자동으로 초기화된 값을 보고, int[3][3]과 같은 배열의 길이를 가집니다.

구분 

 첫번째

두번째 

 세번째

 a[1]

 a[2]

4

5

 a[3]

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

 
아래와 같이 부분적으로 초기화할 경우 값이 순서대로 들어가는 것이 아니라 빈자리에는 0이 채워집니다.

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

int a[3][3]={{1},{4,5},{7,8,9}};

구분 

1번째

2번째 

 3번째

a[1]

0

a[2]

4

5

a[3]

7

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

 
문자열은 정수와 다르게, 문자열의 끝에 \0(널문자)를 넣어줘야 합니다. \0를 넣는 이유는 문자열의 끝을 구분하기 위해서 입니다. 문자열은 부분적으로 초기화 할경우에 0대신 \0가 채워집니다.

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

char a[3][8] ={"red","skyblue","mint"}

구분 

1번째 

2번째 

3번째 

4번째 

5번째 

6번째 

7번째 

8번째 

a[1] 

r

\0 

\0 

\0 

\0 

\0 

a[2]

\0 

a[3] 

\0 

\0 

\0 

\0 

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


 배열을 이용해 16진수를 입력받아 10진수로 변환해주는 소스코드를 작성해 봤습니다.

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

#include <stdio.h>

#pragma warning(disable:4996)


int main()

{

char a[] = { '0','1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E' ,'F'}; //16진수 배열

char input[3]; // 입력을 받는 배열 

int i, j;

int num = 0;

printf("10진수로 변환할 16진수를 입력하세요 : ");

scanf("%s", input);

for (i = 0; input[i] != '\0'; i++) // 입력한 배열의 문자가 널문자가 아닐때까지 반복

for (j = 0; j < 16; j++) // 0~16까지 같은수를 찾을때까지 반복  

if (input[i] == a[j])

num = num * 16 + j;


printf("십진수 : %d \n", num);


return 0;


}

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

위의 코드를 실행하면 아래와 같은 결과가 출력됩니다. A1을 입력했을때, 'A'는 배열 a의 10번째 이므로 j가 10이되고 num=0*16+10이되서 10이되고, '1'은 배열a의 1번째이므로 다시 num=10*16+1이되서 161이 출력됩니다.


* 출처 : 한국기술교육대학교 온라인평생교육원 C 프로그래밍_2 

          스타일 C프로그래밍 저.김종훈,김종진 출.WellBook




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

[C] 배열과 포인터  (3) 2016.12.25
[C] 포인터  (0) 2016.12.23
[C] 디버깅  (0) 2016.12.21
[C] 매개변수 전달 방식  (0) 2016.12.20
[C] 함수(2)  (0) 2016.12.20

디버깅(Debugging)


 디버깅은 de+bug의 합성어로는 "벌레를 없앤다" 에서 유래 되었습니다. 진공관을 사용하는 시절에 벌레가 들어가면 오류가 났었는데, 이때 벌레를 제거하면 정상적으로 동작하였다고 합니다. 버그가 프로그램 오류라는 의미를 가지게 되었고, 디버깅은 프로그램의 오류를 제거하는 행위라는 의미를 가지게 되었습니다. 프로그래밍에서의 오류는 문법적 오류와 논리적 오류 두 가지로 나뉩니다.


- 문법적 오류

  C언어 작성 과정에서 발생하며, 프로그램 문법상의 오류를 뜻합니다. 문법적 오류는 컴파일 되지 않습니다. 

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

#include <stdio.h>

#pragma warning(disable:4996)


int main()

{

int 1;

}

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

 위 코드와 같이 문법적 오류를 범하면 아래 사진과 같이 컴파일이 되지않고, 오류 메시지를 출력해줍니다. 오류 메시지는 문법적인 오류의 종류에 따라 다르게 출력됩니다.


- 논리적 오류

 프로그램 논리상의 오류로 컴파일은 되지만, 정상적으로 동작하지 않습니다. 프로그램을 분석해서 찾아야 합니다. 다음과 같은 코드를 작성했을때 정상적으로 동작할까요? 

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

#include <stdio.h>

#pragma warning(disable:4996)


int main()

{

int i;

int input;


input = 1;


for (i = 0; i < 5; i++)

{

printf("디버깅 테스트 \n");


printf("종료를 원하시면 0을 입력하세요 : ");

scanf("%d", &input);


if (input = 0)

{

break;

}

}

}

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

 결과는 아래 그림과 같이 정상적으로 동작 하지 않습니다. 이유는 if문 조건을 input=0을 써서 조건이 거짓이되어 if문이 동작하지 않습니다.


- 디버깅 도구

 여태까지 공부할 때는 컴파일을 할때, Ctrl+F5 버튼을 눌러 디버깅을 하지 않고 컴파일을 했습니다. Visual Studio에서는 디버깅도구를 이용해 디버깅하면, 한 줄씩 실행하면서 오류를 찾을 수 있습니다.
 Visual Studio에서는 F10키를 누르면 디버깅을 실행 할 수 있습니다. 종료는 Shift+F5키를 눌러주면 됩니다. 디버깅을 시작하면 아래와 같이 빈 콘솔창이 뜹니다.

 이때, 소스코드에는 아래 그림과 같이 왼쪽에 노란색 화살표가 생기는데, 진행 할 지점을 뜻합니다. 아래 그림에서 F10을 눌러 한줄을 더 실행하면 변수 선언부분은 건너뛰고 input=1; 으로 넘어갑니다. 변수 선언 처럼 실제 동작하는 과정이 아닌 부분은 건너 뛰게됩니다. 

 

 계속 한줄 씩 실행해서 scanf로 숫자를 입력하는 부분까지 실행하게되면, 처음에 떴던 콘솔창에 다음과같이 출력됩니다.

 

 콘솔 창에 0을 입력하게되면 input 변수에 0이 저장되는데, 아래 자동 탭을 보면 변수값이 정상적으로 들어간걸 확인할 수 있습니다.


 자동탭 옆에 보면 조사식이라는 탭이 있는데 조사식 탭에서는 이름을 입력하면 값이 출력됩니다. 이름에 input변수와 input=0이라는 값을 각각 입력해봤는데 둘다 결과값이 0인걸 확인할 수 있습니다.


 마지막으로, 반복해서 디버깅할때, 계속 처음부터 한줄씩 실행하려면 번거롭습니다. 이때 사용하는게 중단점입니다. 중단점을 설정하면, 디버깅을 시작할 때 중단점부터 디버깅을 수행하도록 할 수 있습니다. 아래 그림에서는 if(input=0)라인에 중단점을 설정 하였습니다. F9키로 설정/해제 가능합니다.


- 디버깅 관련 단축키

 단축

 의미

 Ctrl + F5

 디버깅 하지 않고, 컴파일 진행

 F5

 (디버깅 시작) 중단점 까지 프로그램을 진행

 F9

 중단점 삽입 / 제거

 F10

 (디버깅 시작) 프로그램을 한 단계씩 진행

 Shift + F5

 디버깅 종료


* 출처 : 한국기술교육대학교 온라인평생교육원 C 프로그래밍_2 

          스타일 C프로그래밍 저.김종훈,김종진 출.WellBook




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

[C] 포인터  (0) 2016.12.23
[C] 배열  (0) 2016.12.23
[C] 매개변수 전달 방식  (0) 2016.12.20
[C] 함수(2)  (0) 2016.12.20
[C] 함수(1)  (0) 2016.12.20

매개변수 전달 방식


 매개변수란, 함수에 전달된 값을 저장하고, 함수 안에서만 사용하도록 선언되어 있는 변수로 앞에서도 공부 한 적이 있습니다. 매개변수 전달방식에는 값 전달 방식(Call by Value)과 참조 전달 방식(Call by Reference)이 있습니다.


- 값 전달 방식(Call by Value)

 값 전달 방식은 함수를 호출할 경우 메인 함수의 변수를 인자로 호출한 함수에 전달하고, 호출한 함수의 매개변수에 메인 함수의 변수 값을 복사하는 방식입니다. 즉, 같은 변수 x를 선언하고 복사했을때, 같은 x지만 메인 함수의 변수와 호출한 함수의 매개변수는 서로 다른 변수입니다. 아래와 같은 코드를 작성했을 때 x의 값은 몇이나올까요?

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

#include <stdio.h>


add(int x);


int main()

{

int x = 10;

add(x);

printf("%d \n", x);

}


add(int x)

{

x = x + 1;

}

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

 main 함수의 x의 값인 10을 add함수에 매개변수 x에 복사합니다. 그리고 x값을 1증가 시킵니다. 하지만, add함수의 x와 main함수의 변수는 다르므로, main함수에서의 x는 그대로 10이 출력됩니다.

 다음과 같이 변수의 이름을 서로 다르게 바꿔도 main함수의 변수와, add함수의 매개변수는 다르므로 위의 코드와 결과가 같습니다.

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

#include <stdio.h>


add(int a);


int main()

{

int x = 10;

add(x);

printf("%d \n", x);

}


add(int a)

{

a = a + 1;

}

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


- 참조 전달 방식(Call by Reference)

 참조 전달방식은 함수의 매개변수에 참조 값을 전달하는 방식으로 함수가 참조를 받을 수 있게 *를 붙이고, 함수를 호출하는 곳에서 변수에 &를 붙입니다.
 아래의 코드를 실행하면 위코드와 같이 10이 나올까요?

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

#include <stdio.h>


add(int *a);


int main()

{

int x = 10;

add(&x);

printf("%d \n", x);

}


add(int *a)

{

*a = *a + 1;

}

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

 결과는 11이 출력됩니다. 참조 전달 방식은 값을 참조하기때문에 main 함수의 x와 *a가 같은값이됩니다.


 참조 전달 방식을 이용해 입력한 두 값을 바꾸는 코드를 작성해 봤습니다.

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

#include <stdio.h>
#pragma warning(disable:4996)

int change(int *x, int *y); // 참조 전달을 위해 변수앞에 *를 붙여줍니다.

int main()
{
int a, b;
printf("입력하는 두 값을 바꿔줍니다.\n");
printf("a 입력 : ");
scanf("%d", &a);
printf("b 입력 : ");
scanf("%d", &b);
printf("바꾸기 전 a : %d, b : %d\n", a, b);
change(&a, &b); // 참조 전달을위해 변수앞에 &를 붙여줍니다.
printf("바꾼 후   a : %d, b : %d\n", a, b);
}

int change(int *x, int *y)
{
int temp; 
temp = *x; // temp에 x값을 저장해놓고 
*x = *y;     // x값에는 y값을 넣고
*y = temp; // y값에는 x값을 저장해놓은 temp의 값을 넣어줍니다.
}

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

위 코드의 결과는 다음 그림과 같습니다.


* 출처 : 한국기술교육대학교 온라인평생교육원 C 프로그래밍_2 

          스타일 C프로그래밍 저.김종훈,김종진 출.WellBook




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

[C] 배열  (0) 2016.12.23
[C] 디버깅  (0) 2016.12.21
[C] 함수(2)  (0) 2016.12.20
[C] 함수(1)  (0) 2016.12.20
[C] 기타 제어문  (0) 2016.12.19

함수(Function)(2)


이번에는 헤더파일과 분할컴파일에 대해 알아보겠습니다. 


- 헤더파일

 우선 헤더파일은 시스템에 설치된 시스템 라이브러리 헤더파일이 있고, 함수처럼 직접 만들어 사용할 수 있습니다. 아래 위치는 헤더파일이 있는 위치입니다. 개발환경에 따라 다를 수 있습니다. 

C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include

 아래 그림처럼 include 폴더에는 수 많은 헤더파일이 있습니다.

수 많은 헤더파일 중에 제가 사용했었던 stdio.h를 visual studio로 열어 봤습니다. 아래 그림을 보면 stdio.h의 헤더파일에 printf 함수가 선언된걸 확인 할 수 있습니다. 이처럼 헤더파일을 직접 만들어서 직접 구현한 함수를 추가 해서 인클루드할 수 있습니다.


- 분할 컴파일

 분할 컴파일은 분리 컴파일 이라고도 하며, 하나의 프로그램을 여러 조각으로 나눠서 작성·관리 하는 기능입니다. 프로그램의 크기가 커지거나 같은 기능을 반복적으로 사용하는 경우  프로그램을 기능별로 나누면 관리 및 재활용이 용이합니다. 분할 컴파일은 컴파일 시간이 줄어들고, 여럿이서 동시에 프로그램 개발할 때 유용합니다.


아래 코드는 함수(1)게시글에서 정의 한 함수를 분할 컴파일한 코드입니다.

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

// cal.h 

// 헤더파일에는 함수의 정의만 해줍니다.

int plus(int a, int b); 

int multi(int a, int b);

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

// cal.c

#include "cal.h" 

// 동일한 이름의 c파일을 생성해서 헤더파일을 인클루드하고 함수를 구현합니다.

// 직접 만든 헤더파일은 <>가아닌 ""를 사용합니다.

int plus(int a, int b)

{

return a + b;

}


int multi(int a, int b)

{

return a * b;

}

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

// main.c
#include <stdio.h>
#pragma warning(disable:4996)
#include "cal.h" // cal.h헤더파일을 인클루드하면 cal.h헤더파일에 정의한 함수를 사용할 수 있습니다.

int main()
{
int a, b, result;
printf("a,b를 입력하시면 합과 곱이 출력됩니다. \n");
printf("a를 입력하세요 : ");
scanf("%d", &a);
printf("b를 입력하세요 : ");
scanf("%d", &b);

result = plus(a, b);
printf("%d + %d = %d \n", a, b, result);
result = multi(a, b);
printf("%d * %d = %d \n", a, b, result);

return 0;
}

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

분할 컴파일 결과 함수(1)게시글과 결과가 동일합니다.


* 출처 : 한국기술교육대학교 온라인평생교육원 C 프로그래밍_2 

          스타일 C프로그래밍 저.김종훈,김종진 출.WellBook




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

[C] 디버깅  (0) 2016.12.21
[C] 매개변수 전달 방식  (0) 2016.12.20
[C] 함수(1)  (0) 2016.12.20
[C] 기타 제어문  (0) 2016.12.19
[C] 반복문  (0) 2016.12.18

함수(Function)(1)


 함수는 입력된 값을 이용해 결과를 반환해 주는 프로그램 코드로, 앞에서 공부할때 썼던 main함수, scanf, printf 등도 함수에 속합니다. 함수의 종류는 시스템 정의 함수

(시스템 라이브러리)와 사용자 정의 함수가 있습니다.


- 반환값, 매개 변수

 반환값은 리턴값이라고 말하기도 하는데, 리턴할 값을 말합니다. 앞에서 공부하면서 거의 사용하지는 않았는데, 아래 처럼 int형으로 main함수를 사용했을때, "return 0;"이 함수 종료 후 0을 반환하겠다는 뜻입니다. 반환값이 필요없을때는 void로 써주면 됩니다.

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

int main() // 매개변수가 필요하지 않을때는 main 함수처럼 ()로 써주면 됩니다.
{
printf("hello \n");

return 0; // 함수 종료 후 0을 반환
}

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

 매개변수는 함수에서 사용할 인자값으로 쉽게 말해 형식이라고 생각하면 이해하기 쉽습니다. 아래 사용자 정의 함수의 코드에서 plus 함수와 multi 함수의 int a, int b가 매개변수입니다.

시스템 정의 함수 

 C언어에서 미리 정의해 놓은 함수로 scanf, printf 등이 있습니다. 헤더파일을 include하면 사용할 수 있습니다.


- 사용자 정의 함수

 사용자가 직접 정의하는 함수입니다. 함수의 모양을 선언하는 과정인 함수원형 선언과,  함수 구현 과정이 있습니다. 함수 원형 선언은 헤더파일 밑에, 함수 구현은 main 함수 밑에 하면됩니다. 아래 코드는 덧셈과 곱셈을 하는 함수 2개를 직접 정의해 구현해서 사용하는 코드입니다.

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

#include <stdio.h>
#pragma warning(disable:4996)

int a, b; // plus함수와 multi함수에서 쓸 a,b를 선언
int plus(int a, int b); // plus 함수 원형 선언
int multi(int a, int b); // multi 함수 원형 선언

int main()
{
int x, y; // 위에 a,b를 선언하지 않고 여기서 a,b로 선언해서 사용해도 무관
  int result; // 함수를 호출해 리턴값을 저장할 변수 선언

printf("x,y를 입력하시면 합과 곱이 출력됩니다. \n");
printf("x를 입력하세요 : ");
scanf("%d", &x);
printf("y를 입력하세요 : ");
scanf("%d", &y);
result = plus(x, y); // plus함수 호출 후 리턴값 저장
printf("%d + %d = %d \n", x, y, result);
result = multi(x, y); // multi함수 호출 후 리턴값 저장
printf("%d * %d = %d \n", x, y, result);

return 0;
} //close main()

int plus(int a, int b) // multi 함수 구현
{
return a + b; // 리턴값으로 a+b를 리턴
}

int multi(int a, int b) // multi 함수 구현
{
return a * b; // 리턴값으로 a*b를 리턴
}
------------------------------------------------------------------------------------------
 아래 그림이 위 코드의 결과입니다. 사실 아래 처럼 간단한 연산은 굳이 함수를 정의해서 사용할 필요가 없지만, 복잡한 연산이나 복잡한 처리는 사용자 정의 함수를 이용하면 좀 더 실용적인 코딩을 할 수 있을 것입니다.


* 출처 : 한국기술교육대학교 온라인평생교육원 C 프로그래밍_2 

          스타일 C프로그래밍 저.김종훈,김종진 출.WellBook




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

[C] 매개변수 전달 방식  (0) 2016.12.20
[C] 함수(2)  (0) 2016.12.20
[C] 기타 제어문  (0) 2016.12.19
[C] 반복문  (0) 2016.12.18
[C] 조건문  (0) 2016.12.17

기타 제어문

 

 기타 제어문은 주로 반복문에서 사용하는 제어문으로 break와 continue가 있습니다.


- break

 break문은 동작을 멈추고 끝내는 제어문으로, 앞에서 공부할 때 이미 사용한 적이 몇 번 있습니다.  break문은 반복문 외에도 switch문에서도 사용합니다. 사용 형태는 다음과 같습니다.

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

반복문 또는 switch문{

(중략)

break;

(중략) // break문 밑에 코드는 실행되지 않고 종료

}

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


- continue

 continue문은 반복문에서  현재 반복을 중단하고, 다음 반복을 계속할 때 사용하는 제어문입니다. continue문을 사용하면 continue문 밑에 코드는 실행되지 않고, 다음 반복으로 넘어갑니다. 사용 형태는 다음과 같습니다.

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

반복문{

(중략)

continue;

(중략) // continue문 밑에 코드는 실행되지 않고 다음 반복으로 넘어감

}

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


지금 까지 배운 조건문과 기타 제어문을 이용해 업 다운 게임을 만들어 보았습니다.

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

#include <stdio.h>
#pragma warning(disable:4996)

int main()
{
int okay; // 정답으로 설정할 변수 선언
int input; // 정답을 맞힐 변수 선언
int i; // 줄바꿈 문자에 사용할 변수를 선언
int count = 0; // 몇번만에 맞혔는지를 기록할 변수를 선언하고 초기화

printf("정답을 설정하세요 : "); 
scanf("%d", &okay);   // 정답(문제)을 입력
for (i = 0; i < 50; i++) // 정답을 입력받은 후 보이지않게 50번 줄바꿈 문자를 삽입
{
printf("\n"); 
}

while (1)
{
printf("정답을 입력하세요 : ");
scanf("%d", &input); // 답을 맞힙니다.
if (input == okay){ // 답을 맞힐경우 실행
count++; // count에 1을 더하지않으면, 정답을 맞힐경우 횟수가 증가하지 않기때문에 맞힐경우에도 1을 증가시킵니다.
printf("%d번만에 정답을 맞히셨습니다. \n", count);
break; // 종료
}
else if (input > okay)  // 정답보다 작을 경우 실행
{
printf("입력한 숫자보다 작습니다!\n");
count++; // 틀린 답을 입력할 경우 count를 1증가
}
else if (input < okay)  // 정답보다 클 경우 실행
{
printf("입력한 숫자보다 큽니다!\n");
count++; // 틀린 답을 입력할 경우 count를 1증가
}
}// close while
}

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

위의 코드를 실행하면 정답을 설정하라는 문자열이 출력되고 설정할 정답을 입력합니다.

정답을 설정하고나면, 50번 반복을 통해 출력된 줄바꿈 문자에의해 아래에 문자열이 출력됩니다.

정답을 입력하게되면 값을 비교해 큰지, 작은지 출력하고 정답을 맞히면 몇번만에 맞혔는지 출력하고 프로그램이 종료됩니다.


* 출처 : 한국기술교육대학교 온라인평생교육원 C 프로그래밍_1 

          스타일 C프로그래밍 저.김종훈,김종진 출.WellBook



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

[C] 함수(2)  (0) 2016.12.20
[C] 함수(1)  (0) 2016.12.20
[C] 반복문  (0) 2016.12.18
[C] 조건문  (0) 2016.12.17
[C] 연산자  (0) 2016.12.16

반복문


 반복문은 쉽게 말해 반복을 하기위해 사용하는 문장입니다. 예를들어 printf 함수로 같은문장 또는 1씩 증가하는 문장 10줄을 출력하고싶을 때 일일이 10번을 다 입력해줘야 하지만, 반복문을 이용하면 반복문안에 한번만 입력하면 됩니다. 반복문은 문자열 출력 뿐만아니라, 사용에 따라 다양하게 활용할 수 있습니다. C에서 사용하는 반복문은 for문 while문 do-while문 세 가지가 있습니다.


- for문

 for문은 일정 횟수를 반복하는 경우에 많이 사용합니다. 사용 형태는 다음과 같습니다.

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

for(초기화; 반복조건; 증감연산)
{
반복하면서 처리할 내용
}

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

사용 예)
int i; // for문에서 초기화를 하기때문에 변수 선언만 해줍니다.
for(i=0; i<9; i++)
{
printf("%d의 값 \n",i);
}

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


- while문

 while문은 어떤 조건이 만족하는 동안 반복하는 반복문입니다. while문은 증감연산을 while문 안에 써줘야하고, 반복할 상수를 선언과 동시에 초기화를 해줘야합니다.  사용 형태는 다음과 같습니다.

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

while(조건식)

{
반복하면서 처리할 내용

}

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

사용 예)

int i=0; // for문과 다르게 반복에 이용할 변수 선언과 동시에 초기화

while ( i<10 ) // 조건

{

printf(“Hello World! \n”);

i++; // while문 내부에 써주는 증감연산자

}

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


- do-while문

  do-while문은 실행 후 while문을 실행하는 형태라고 생각하시면 됩니다. 조건에 상관없이 do에 있는 문장을 무조건 실행 한 뒤, 뒤에 있는 while문의 조건에 따라 반복합니다. 사용 형태는 다음과 같습니다. 이때, 주의할점은 while문 뒤에 세미콜론(;)이 붙는다는 겁니다. 세미콜론을 쓰지않을경우 구문 오류가 발생합니다.
------------------------------------------------------------------------------------------
do{
반복하면서 처리하거나 한번만 실행할 내용

}while(조건식);
------------------------------------------------------------------------------------------
사용 예)
int input;
do
{
printf(“Hello World!\n”);
printf(“종료를 원하시면 0을 입력하세요 : ”);
scanf(“%d”, &input);
}while(input!=0); // 0이 아닌경우만 반복
------------------------------------------------------------------------------------------

 지금까지 공부한 내용들을 바탕으로 원하는 구구단을 출력하는 코드를 간단하게 작성해보았습니다. scanf로 원하는 단을 입력받고, 0을 입력했을때 종료하는 코드입니다.
------------------------------------------------------------------------------------------
#include <stdio.h>
#pragma warning(disable:4996)

int main()
{
int num=1; // 구구단은 1단부터 시작해서 1로 초기화
int i;         // for문에서 사용할 변수
while (num != 0) // 0이 아닐경우 반복
{
printf("출력하고싶은 단을 입력하세요(0은 종료) : ");
scanf("%d", &num);
if (num == 0){ // 0을 입력했을경우 실행
printf("0을 입력하셔서 종료됩니다. \n");
break; // 종료
// close if
else{
printf("*****%d단*****\n", num);
for (i = 1; i < 10; i++){ // 1부터 1씩 증가하면서 9까지 반복
printf("%d * %d = %d\n", num, i, num*i);
} // close for
// close else
// close while
} // close main
------------------------------------------------------------------------------------------
 추가로 함수나 반복문 뒤에 주석으로 // close를 일일이 써준 이유는 코드가 복잡해지면 어디가 끝인 지, 어디가 무슨 함수까지인지 등등 헷갈릴 수 있기 때문입니다. 프로그래밍을 처음 시작하시는분들은 추천하는 방법입니다. 주석으로 끝을 표시해주는 게 코드를 보기도 좋고, 괄호를 빼먹는 실수도 줄어들 것입니다.

 아래 그림은 위 코드를 실행 했을때의 결과입니다. 0을 입력하기 전까지는 계속 입력하는 단을 출력하다가, 0을 입력하면 0을 입력했다는 문자열을 출력하고 종료됩니다.


* 출처 : 한국기술교육대학교 온라인평생교육원 C 프로그래밍_1 

          스타일 C프로그래밍 저.김종훈,김종진 출.WellBook




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

[C] 함수(1)  (0) 2016.12.20
[C] 기타 제어문  (0) 2016.12.19
[C] 조건문  (0) 2016.12.17
[C] 연산자  (0) 2016.12.16
[C] 입출력함수, 기본자료형, 형변환  (0) 2016.12.15

조건문

 조건문은 조건에 따라서 동작이 달라지는 문장으로, if-else문과 switch-case문이 있습니다. 상황에 따라서 두 조건문을 이용하면 여러가지를 구현할 수 있습니다.


- if-else문

 if의 뜻은 만일에,만약에 라는 뜻이잖아요? 그 "만일,만약"이라는 조건에 맞으면 실행하는 조건문입니다. if문은 if절과 else절, else if절로 구성됩니다. else if절은 다른 조건의 if라고 보시면 됩니다. 그리고 if절만 사용할 수 있고, else절과 else if절은 무조건 사용해야만 하는건 아닙니다. if괄호안에 조건이 참일 때 if문을 수행하고, else 절은 조건이 거짓일때 수행합니다.

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

if(조건){
조건이 참일 때 할 동작들
}

else if(if와는 다른 조건){

조건이 참일 때 할 동작들

}
else{
if의 조건도 else if들의 조건이 모두 거짓일 때 할 동작들
}

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


 저번에 했던 알파벳 출력을 if-else문을 이용 해 구성해보았습니다. 아래코드는 if문은 대문자를 소문자로 변환, else if문은 소문자를 대문자로 변환, else는 영문이 아닌 문자를 입력했다고 출력해주는 코드입니다.

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

#include <stdio.h>

#pragma warning(disable:4996) // viusal studio에서 scanf 함수를 사용하기위해 사용


int main()

{

char ch; //입력받을 변수선언

printf("영문 대문자는 소문자로, 소문자로는 대문자로 변환합니다.\n문자를 입력하세요 : ");

scanf("%c", &ch); // 입력받는 함수 

if (ch >= 65 && ch <= 90) // 대문자를 입력했을 때

{

printf("소문자로 변환 : %c\n", ch + 32); 

}

else if (ch >= 97 && ch <= 122) // 소문자를 입력했을 때

{

printf("대문자로 변환 : %c\n", ch - 32);

}

else{ // 대문자도 소문자도 아닌 문자를 입력했을 때

printf("영문이 아닌 기타 문자를 입력하셨습니다. \n");

}

}

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

각각 문자를 입력했을 때, 출력되는 결과는 다음과 같습니다.


- switch-case문
switch문은 다중선택구조라고 불리는 조건문입니다. if-else문으로 여러 조건을 부여할 경우 코드가 복잡해지는데, switch문을 이용하면 보다 쉽게 구현할 수 있습니다. 정수식을 입력받아 동작하며, case문의 숫자에따라 실행이됩니다. default는 case문으로 정한 조건을 모두 벗어나는 경우 실행됩니다. 
-------------------------------------------------------------------------------------------
switch(정수식)
{
case <정수값1>:
  할일1;
  break;
case <정수값2>:
  할일2;
  break;
   …
default:
  할일n;
}

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


 break를 쓰지않으면 case를 여러개 묶어서 사용할 수 있습니다.

-------------------------------------------------------------------------------------------
switch(정수식)
{
case 1 :
  할일1;
case 2 : // case 2까지 실행
  할일2;
  break;
   …
default:
  할일n;
}

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


switch문을 활용해 두 수를 계산하는 간단한 계산기를 만들어봤습니다. 소수점 계산을 위해 계산할 두 수를 double형으로 선언하고 소수점 두자리까지만 출력되게 설정하였습니다. 마지막 default절에 main으로 return한 이유는 잘못입력했을 때 다시 처음으로 되돌아가기 위합입니다. 
-------------------------------------------------------------------------------------------
#include <stdio.h>

#pragma warning(disable:4996) // viusal studio에서 scanf 함수를 사용하기위해 사용


int main()

{

int num; // switch문에 사용할 정수값 변수선언

double x, y; // 계산에 사용할 dobule형 변수선언


printf("1)'+' 2)'-' 3)'*' 4)'/' \n계산하고싶은 항목의 번호를 입력해주세요 : ");

scanf("%d", &num); // switch문에 사용할 정수값을 입력받음


switch (num)

{

case 1:

printf("계산할 x,y를 입력하세요 : ");

scanf("%lf %lf", &x, &y); //계산할 x,y를 입력받음

printf("%.2lf + %.2lf = %.2lf \n", x, y, x + y); // 입력받은 x,y와 계산된 결과값 출력

break;

case 2:

printf("계산할 x,y를 입력하세요 : ");

scanf("%lf %lf", &x, &y); //계산할 x,y를 입력받음

printf("%.2lf - %.2lf = %.2lf. \n", x, y, x - y); // 입력받은 x,y와 계산된 결과값 출력

break;

case 3:

printf("계산할 x,y를 입력하세요 : ");

scanf("%lf %lf", &x, &y); //계산할 x,y를 입력받음

printf("%.2lf * %.2lf = %.2lf. \n", x, y, x*y); // 입력받은 x,y와 계산된 결과값 출력

break;

case 4:

printf("계산할 x,y를 입력하세요 : ");

scanf("%lf %lf", &x, &y); //계산할 x,y를 입력받음

printf("%.2lf / %.2lf = %.2lf \n", x, y, x / y); // 입력받은 x,y와 계산된 결과값 출력

break;

default:

printf("잘못된 값을 입력하셨습니다. 1~4번 항목을 선택해주세요. \n");

return main(); // main 함수로 return

}

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

아래 그림은 실행결과입니다 처음에 항목의 번호를 입력하면 switch문의 case 4가 실행이됩니다. x,y를 입력받고 계산을 마친뒤에 break에 의해 프로그램이 종료가 됩니다.

아래그림은 1~4가 아닌 다른값을 입력했을 때 default절이 실행이되고, 메인함수를 리턴해서 다시 처음부터 실행되는걸 확인할 수 있습니다.


* 출처 : 한국기술교육대학교 온라인평생교육원 C 프로그래밍_1 

          스타일 C프로그래밍 저.김종훈,김종진 출.WellBook




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

[C] 기타 제어문  (0) 2016.12.19
[C] 반복문  (0) 2016.12.18
[C] 연산자  (0) 2016.12.16
[C] 입출력함수, 기본자료형, 형변환  (0) 2016.12.15
[C] C 기본개념(2) 라이브러리와 변수  (0) 2016.12.12

+ Recent posts