안녕하세요. YKK입니다.
어제에 이어 C프로그래밍 워크숍 3일 차에 다룬 내용을 복습해 보겠습니다.
오늘은 C언어 프로그래밍에서의 함수와 배열인데요.
C언어 포함 프로그래밍 언어에 대한 기초지식이 부족한 분들은 오늘 내용부터 조금 버거울 수도 있겠다는 느낌이 강하게 들었습니다. 저 또한 상당히 힘들었습니다.
*함수
: 프로그래밍에서 함수(function)란 하나의 특별한 목적의 작업을 수행하기 위해 독립적으로 설계된 프로그램 코드의 집합으로 정의할 수 있습니다.
-함수를 사용하는 가장 큰 이유는 반복적인 프로그래밍 작업을 피할 수 있기 때문입니다. 특정 작업을 여러 번 반복해서 수행해야 할 경우 함수를 호출함으로써 간단히 처리할 수 있습니다. 특정 작업이 필요할 때마다 해당 함수를 호출하여 사용하기만 하면 됩니다. 또한 함수는 유지 보수 및 확장에 용이하고 분할과 정복을 통해 문제를 해결하는데 유용하게 사용될 수 있습니다.
-함수의 기본 형태
제가 따로 언급하지 않았지만 지금까지 올린 글들에 모두 함수가 존재했습니다.
바로 이 형태인데요.
int main(int i, int j)
{
result = i + j;
return result;
}
/*
int(여기선 정수형, 다른 형도 올 수 있음): 반환 자료형, 함수의 결과값에 대해 출력 형태를 나타내는 자료형
main: 함수의 이름
(int i, int j): 매개 변수, 함수가 입력받을 형태
{ }: 함수 몸체, 함수의 고유기능을 수행하는 명령문의 집합
return result: 결과 값의 반환
*/
C프로그래밍에서 함수는 '반환 자료형 함수의 이름(매개변수)' 형태를 항상 유지합니다.
C언어에서는 함수를 선언할 때 그 위치가 매우 중요합니다. 다음 예제를 통해 보겠습니다.
#include <stdio.h>
int main(void)
{
int result;
result = bigNum(3, 5); // 함수의 호출
printf("두 수 중 더 큰수는 %d입니다.\n", result);
result = bigNum(3, 1); // 함수의 호출
printf("두 수 중 더 큰수는 %d입니다.\n", result);
result = bigNum(7, 5); // 함수의 호출
printf("두 수 중 더 큰수는 %d입니다.\n", result);
return 0;
}
int bigNum(int num01, int num02) // 함수의 정의
{
if (num01 >= num02)
{
return num01;
}
else
{
return num02;
}
}
//출처: https://tcpschool.com/c/c_function_basic
C언어에서는 main() 함수가 컴파일러에 의해 가장 먼저 컴파일됩니다. 위 예제에서 컴파일러는 main() 함수에 등장하는 bigNum() 함수를 아직 알지 못하기 때문에 컴파일 오류가 발생합니다. 이를 해결하기 위해선 컴파일러에 bigNum() 함수는 나중에 정의되어 있다고 인식시켜야 합니다.
위와 같이 순차적으로 한 번에 컴파일하는 방식을 단일 패스(one pass) 컴파일 방식이라고 합니다. 그러나 하드웨어의 발달로 컴파일러에 따라 여러 번에 걸쳐 컴파일하는 다중 패스(multi-pass) 방식도 많아지고 잇습니다. 그러나 오래된 컴파일러는 대부분 단일 패스 방식으로 컴파일하기 때문에 C 표준에선 여전히 함수의 원형을 선언합니다.
다음 예제는 앞서 살펴본 예제에 함수의 원형 선언을 추가한 예제입니다.
이렇게 함수의 원형은 main() 함수 앞에 미리 선언되어야 합니다.
#include <stdio.h>
int bigNum (int, int); // 함수의 원형 선언
int main(void)
{
int result;
result = bigNum(3, 5); // 함수의 호출
printf("두 수 중 더 큰수는 %d입니다.\n", result);
result = bigNum(3, 1); // 함수의 호출
printf("두 수 중 더 큰수는 %d입니다.\n", result);
result = bigNum(7, 5); // 함수의 호출
printf("두 수 중 더 큰수는 %d입니다.\n", result);
return 0;
}
int bigNum(int num01, int num02) // 함수의 정의
{
if (num01 >= num02)
{
return num01;
}
else
{
return num02;
}
}
*함수의 형태(전달 인자와 반환 값에 따라)
함수는 또한 전달 인자와 반환 값의 유무로 총 4 가지 형태로 구분되는데요.
전달 인자有, 반환 값有
void main(void)
{
int i = 5, j = 7;
int result = sum(i, j);
printf("결과: %d", result);
}
int sum(int i, int j)
{
return i + j;
}
전달 인자有, 반환 값無
void main(void)
{
int i = 5, int j = 7;
sum(i, j);
}
void sum(int i, int j)
{
printf("결과: %d", i + j);
}
전달 인자無, 반환 값有
void main(void)
{
printf("결과: %d", sum());
}
int sum()
{
int i = 5, int j = 7;
return i + j;
}
전달인자無, 반환 값無
void main(void)
{
sum();
}
void sum()
{
int i = 5, int j = 7;
printf("결과: %d", i + j);
}
이처럼 같은 기능을 수행하는 함수도 다른 형태 4가지로 표현될 수 있음을 알아두시면 좋을 거 같습니다.
함수 호출의 이해는 아래 사진을 참고하세요.
예제 1. 지금까지 학습한 내용을 바탕으로 간단하게 factorial 계산 함수를 구현해 보겠습니다.
Factorial은 1부터 n까지의 곱을 계산하는 것입니다. 아래 main 코드를 참고하여 완성해 보세요.
int main(void){
int val;
printf("계산하려는 값 입력: ");
scanf("%d", &val);
printf("%d의 factorial: %d, factorial(val));
}
실습 답안은 게시물 가장 마지막에 남겨두겠습니다. 꼭 한번 해보세요!
*배열(Array)
배열 (Array) 이란, 어떤 한 가지 자료형을 연속적으로 나열하는 것을 말합니다. 만약 100명의 이름을 저장하여 사용하고자 한다면, 100개의 변수를 선언해서 각각 저장하고 사용해야 하는데, 배열을 사용하면 변수 하나로 아주 쉽게 사용할 수 있습니다.
배열을 사용하면 둘 이상의 변수를 동시에 선언하는 것과 같은 효과를 내고, 위의 예시처럼 많은 양의 데이터를 일괄적으로 처리해야 하는 경우에 유용합니다.
파이썬에서는 배열 대신에 리스트를 사용합니다. 파이썬을 다뤄보신 분들은 리스트를 생각하시면 이해가 편하실 거 같습니다.
배열은 아래와 같은 형태로 선언됩니다.
int array[10];
int: 배열 요소 자료형, 배열을 구성하는 변수의 자료형
array: 배열의 이름, 배열에 접근할 때 사용되는 이름
10: 배열의 길이, 배열을 구성하는 변수의 개수(반드시 상수를 사용해야 함)
위 코드를 실행하면 그림처럼 배열을 생성하는데요. 파이썬에서 리스트에 접근할 때 리스트의 인덱스를 이용하는 것처럼, C언어에서 배열 또한 인덱스를 이용하여 접근합니다. 인덱스는 0부터 시작합니다.
다음은 배열의 선언과 접근입니다.
int main(void)
{
int array[10]; //배열 선언
array[0] = 10; //첫 번째 요소에 접근
array[1] = 20; //두 번째 요소에 접근
array[2] = 30; //세 번째 요소에 접근
:
return 0;
}
array[s] = 10; //s+1번째 요소에 10을 대입하라는 뜻
다음은 배열의 초기화와 문자 배열에 관련된 내용입니다.
이 파트는 사용하고 있는 교재 자료만으로 설명드리기에는 한계가 있어 다른 분이 깔끔하게 정리하신 자료 첨부합니다.
배열의 초기화
- 배열을 선언하면 처음에 쓰레기값이 존재합니다.
int num[5]; int i, tot=0; for(i=0; i<5; i++){ tot+=num[i]; } printf("total: %d\n", tot); //쓰레기값의 합이 출력
- 배열은 기억공간의 수가 많으므로 중괄호를 사용하여 초기값을 나열합니다.
배열의 초기화 int num[5] = {1, 3, 5, 7, 9}; //순서대로 저장됨
배열의 초기화의 자동기능
- 배열요소의 수보다 초기화 값이 적으면 남는 기억공간은 0으로 채워집니다.
int num[5] = {1, 3); -> 1 3 0 0 0
- 배열을 선언할 때 초기화하면 배열요소의 개수를 생략할 수 있습니다.
int num[] = {1, 3, 5, 7, 9}; -> 1 3 5 7 9 //숫자 생략가능
출처: https://velog.io/@swk_x/C%EC%96%B8%EC%96%B4-%EB%B0%B0%EC%97%B4
[C언어] 배열
같은 형태의 자료형이 많이 필요할 때 배열을 사용하면 효과적이다.배열은 배열명과 변수의 개수, 변수의 자료형으로 선언한다.배열을 선언하면 변수의 개수만큼 연속된 기억공간을 할당한다.
velog.io
문자열을 저장하는 문자배열
문자열의 선언과 사용
- 문자배열은 기본적으로 여러 개의 문자를 저장하기 위한 char형 배열입니다.
-4개의 문자를 저장할 수 있는 문자배열의 선언char word[4]; -> char char char char //전체 4바이트 기억공간 할당
- 배열요소 문자를 저장하면 문자열이 만들어집니다.
word[0] = 'H'; word[1] = 'I'; //HI
문자열은 널문자가 완성한다.
- 문자배열의 마지막에 널문자('\0')가 없으면 저장된 문자열의 끝을 알 수 없습니다.
- 문자배열에 문자열을 저장할 때는 항상 마지막에 끝을 표시하는 널문자('\0')를 넣어줘야 합니다.
char word[50]; word[0]='H'; word[1]='I'; word[2]='\0'; //문자열의 끝을 널문자로 표시해준다. printf("%s", word);
scanf함수를 사용한 문자열의 입력
- 문자배열에 문자열을 입력받을 때는 %s 변환문자열과 배열명을 scanf함수의 전달인자로 줍니다.
scanf("%s", word); -> 배열에 문자열을 입력합니다.
- scanf함수로 문자열을 입력받으면 널문자를 자동으로 채워줍니다.
-word배열에 hello를 입력받은 경우printf("문자열을 입력하세요 : "); scanf("%s", word); //문자열이므로 &는 생략
마무리하기 전 배열에 관해 학습한 내용을 바탕으로 간단한 예제를 풀어보면 마무리하겠습니다.
예제 2. 다섯 개의 숫자를 입력받아 배열에 저장하고 이 숫자들의 평균을 출력하는 프로그램을 만들어보자.
예제 3. 배열에 저장된 문자열이 palindrome 검사 함수를 작성해 봅시다. (반드시 배열을 사용할 것)
- Palindrome의 예 : maddam, abcddcba,…
- 문자열의 사이즈 (문자의 개수)는 짝수라 가정 문자열의 사이즈는 변할 수 있음
- 문자열에는 공백이 없다고 가정
위 조건을 충족하면서 아래 주어진 코드를 바탕으로 palindrome 검사 함수를 생성해 봅시다.
#include <stdio.h>
#include <string.h>
palindrome(char ch[]);//아래 주어진 함수를 보고 palindrome 검사 함수 만들면 됩니다.
int main(void) {
char check[100]; // 문자열 저장용 배열, 최대 길이를 100으로 가정
printf("검사를 진행할 문자열을 입력해주세요: ");
scanf("%s", check); // 사용자로부터 검사할 문자열 입력받기(좀 더 범용성을 위해 지정 포기)
//사용자에게 입력 받는 대신에 아래 코드처럼 palindrome 지정도 가능(더 쉬운 방법)
//char check[] = "maddam";
int result = palindrome(check);
if (result == 0)//Hint, result값이 0이 되면 palindrome이므로 이를 고려해야 함
printf("%s is a palindrome\n", check);
else
printf("%s is not a palindrome\n", check);
return 0;
}
예제 해답들.
//예제1. factorial 함수 구현
#include <stdio.h>
int factorial(int val);
int main(void) {
int val;
printf("계산하려는 값 입력: ");
scanf("%d", &val);
printf("%d의 factorial: %d\n", val, factorial(val));
return 0; // 효과적인 실행을 나타내기 위해 0을 반환했습니다.
}
int factorial(int val) {
int i;
int res = 1;
for (i = 1; i <= val; i++) {
res *= i; // 각 곱셈으로 결과를 업데이트
}
return res;
}
//예제.2 배열을 이용해, 사용자로부터 입력받은 다섯 개의 수 평균 구하기
#include <stdio.h>
int main() {
int numbers[5]; // 5개의 숫자를 저장할 배열
int sum = 0; // 숫자들의 합계를 저장할 변수
float average; // 평균을 저장할 변수
// 사용자로부터 5개의 숫자 입력 받기
printf("숫자 다섯 개를 입력해주세요: ");
for (int i = 0; i < 5; i++) {
scanf("%d", &numbers[i]); // 배열에 숫자 저장
sum += numbers[i]; // 숫자를 합계에 더하기
}
// 평균 계산
average = (float)sum / 5;
// 결과 출력
printf("입력한 숫자들의 평균은 %.2f입니다.\n", average);
return 0;
}
//예제3. palindrome 검사 프로그램
#include <stdio.h>
#include <string.h>
int palindrome(char ch[]);
int main(void) {
char check[100]; // 문자열 저장용 배열, 최대 길이를 100으로 가정
printf("검사를 진행할 문자열을 입력해주세요: ");
scanf("%s", check); // 사용자로부터 검사할 문자열 입력받기
int result = palindrome(check);
if (result == 0)
printf("%s is a palindrome\n", check);
else
printf("%s is not a palindrome\n", check);
return 0;
}
int palindrome(char ch[]) {
int length = strlen(ch);
// 문자열의 중간 지점 탐색
int mid = length / 2;
for (int i = 0; i < mid; i++) {
/*
문자열의 시작과 끝을 비교하여 다르면 palindrome이 아님
이때 palindrome이면 0, 아니면 1을 반환
*/
if (ch[i] != ch[length - 1 - i]) {
return 1;
}
}
return 0;
}
오늘도 수고 많으셨습니다. 내일 새로운 내용으로 다시 오겠습니다.
파이팅!
'C' 카테고리의 다른 글
C언어 시작하기(기초4)-포인터와 구조체 (0) | 2024.01.12 |
---|---|
C언어 시작하기(기초2)-다양한 연산자들, scanf 함수, 상수와 기본 자료형, 제어문 (1) | 2024.01.10 |
C언어 시작하기(기초1)-개발 환경 구축, 변수 및 산술 연산자 (1) | 2024.01.08 |