[로데시] 개발

[정처기 실기] 6. 프로그래밍 언어 활용 요약 - C언어2 본문

자격증/정보처리기사 - 실기

[정처기 실기] 6. 프로그래밍 언어 활용 요약 - C언어2

로데시 2026. 3. 25. 11:08
반응형
☰   정보처리기사 실기  




Ⅵ. 프로그래밍 언어 활용

02. C언어

1️⃣ 배열

(1) 배열 종류
 
📌 1차원 배열
int a[3] = {1,2} // a[2]는 0으로 초기화
float b[3] = {1.1, 1.2} // b[2]은 0.0으로 초기화
char c[8] = "Hello"; // 나머지는 NULL 로 초기화


📌 2차원 배열
int a[2][3] = {1,2,3,4} // a[2]는 0으로 초기화
1 2 3
4 0 0

char b[2][8] = {"Hello", "computer"}; // 나머지는 NULL 로 초기화
H e l l o NULL NULL NULL
c o m p u t e r




2️⃣ 문자열

(1) 1차원 배열과 문자열
ㆍchar 형 배열로 표현
ㆍ초기화 할 때 마지막에 NULL 문자 삽입
ㆍprintf("%s")시 NULL 직전까지 읽어서 출력


cf) 문자열과 주소
int a[5]
ㆍ&a[0] <=> a <=> a의 0번째 주소
ㆍ&a[3] <=> a + 3 <=> a의 3번째 주소


(2) 2차원 배열과 문자열
ㆍchar 형 2차원 배열을 사용
ㆍ&a[0][0] <=> a[0] <=> a의 0번째 행, 0번째 열의 주소
ㆍ&a[1][2] <=> a[1] + 2 <=> a의 1번째 행, 2번째 열의 주소




3️⃣ 구조체(Structure Type)

(1) 구조체 개념
ㆍ기본 자료형으로 새롭게 정의할 수 있는 사용자 정의 자료형
ㆍ초기화 할 때 마지막에 NULL 문자 삽입
ㆍprintf("%s")시 NULL 직전까지 읽어서 출력


(2) 구조체 선언
ㆍ구조체 정의
struct 구조체명{
  자료형 변수명;
  char gender;
  int age;
}

ㆍ구조체 변수 선언 및 초기화
struct 구조체명 변수명 = {'F', 21};

ㆍ구조체 멤버 접근
ㆍp.gender = 'M', p.age = 25; // 일반 변수
ㆍp->gender = 'M', p->age = 25; // 포인터 변수




4️⃣ 함수

(1) main 함수
ㆍ모든 프로그램의 시작
ㆍvoid main() 일 경우, return; or return 자체를 사용 안 함
ㆍint main() 일 경우, return 반환값; 명시


(2) 사용자 정의 함수(User-Defined Function)
ㆍ매개변수, 생성된 변수 -> 사용자 정의 함수 종료되면 없어짐
ㆍmain 함수에서 fn() 호출 시 ->
 1) main 함수 위에 fn() 작성
 2) fn()이 함수라고 명시
 
① 매개변수 전달 방법(Parameter Passing Mechanism)
 
📌 구성요소
ㆍ매개변수(parameter) - 호출하는 쪽에서 전달받는 변수의 값/주솟값
int fn(int x, int y){ // 매개변수
  ...
}

ㆍ전달인자(argument) - 호출하는 쪽에서 전달하는 변수의 값/주솟값
void main(){
  int i, j;
  ...
  fn(i, j); // 전달인자
}


📌 종류
ㆍCall by Value
 - 새로운 공간에 할당
 - 실 매개변수에 영향 X
int fn(int x, int y){
  ...
}

void main(){
  int i, j;
  ...
  fn(i, j);
}

ㆍCall by Reference
 - 메모리 공간의 주소 전달
 - 실 매개변수의 주소를 형식 매개변수로 보냄
int fn(int* x, int* y){ // * 는 간접 연산자
  ...
}

void main(){
  int i, j;
  ...
  fn(&i, &j); // & 는 주소 연산자
}

② 재귀함수(Recursive Function)
 
ㆍ함수 자신이 자신을 부르는 함수
ㆍ계산이 끝나면 main으로 return


(3) 표준 함수
 
📌 문자열 함수 ㅡ string.h 헤더 추가
ㆍstrcat (Concatenate - 문자열끼리 연결)
strcat("Hello", "Clan"); // HelloClan
strncat("Hello", "Clan", 2); // HelloCl

ㆍstrcpy (Copy - 문자열 복사)
strcpy("Hello", "Clan"); // Clan
strncpy("Hello", "Clan", 2); // Clllo - Hello 중 앞 2글자(Cl)만 복사됨 

ㆍstrcmp (Compare - 문자열 비교)
strcmp(s1,s2); 일 때, s1 > s2면 1, s1 = s2면 0, s1 < s2면 -1을 반환 (아스키 코드를 비교)
strcmp("Hello", "Clan"); // -1
strncmp("Hello", "Help", 2); // 0 

ㆍstrlen (Length - 문자열 길이)
strlen("Hello"); // 5

ㆍstrrev (Reverse - 문자열 뒤집음)
strrev("Hello"); // olleH

ㆍstrchr (Char - 일치하는 문자 있는지 검사)
strchr("Hello", "H"); // Hello - 일치하는 문자부터 NULL 전까지 출력
strchr("Hello", "l"); // llo 


📌 수학 함수 ㅡ math.h 헤더 추가
ㆍsqrt(n) - 양의 제곱근 계산, 소수 확인할 때 사용
ㆍceil(n) - 소수점 올림
ㆍfloor(n) - 소수점 내림


📌 유틸리티 함수 ㅡ stdlib.h, time.h 헤더 추가
ㆍrand() - 임의의 값 생성 (0~32767(=215-1))
ㆍsrand(seed) - seed 값에 따른 임의의 값 생성
ㆍtime() - 현재 시간 가져옴

ㆍatoi(str) - 문자열(str) -> 정수형(int) 변환
ㆍatof(str) - 문자열(str) -> 실수형(float, double) 변환
ㆍitoa(value, str, radix) - value 를 변환하여 str에 radix 진수로 저장




5️⃣ 포인터

포인터 - 변수의 주솟값 저장
 
(1) 포인터 선언
자료형* 포인터변수명 = & 변수명
* : 자료형과 쓰임 - 주솟값을 저장하는 변수 선언
  포인터 변수명/주솟값을 의미하는 변수와 함께 쓰임 - 그 주소의 값
& : 변수명 앞에 붙음 - 해당 변수명의 주솟값

ex)
int a = 10;
int *b = &a; // b는 a의 주솟값을 갖는다
printf("%d %d %d", a, *b, *(&a)); // a는 10, b가 가리키는 곳의 값 = 10, a의 주소가 가리키는 곳의 값 = 10

char *p = "KOREA";
printf("%c", *p+2); // *p 계산 후 + 2 를 연산. *p의 값은 K, K+2를 문자로 출력하면 M (∵아스키코드)
printf("%c", *(p+2)); // p+2 계산 후 * 를 연산. p+2의 값은 R의 주솟값. *(R의 주솟값)을 연산하면 R


(2) 배열과 포인터
 
ㆍ포인터와 배열 -> 둘 다 주소 갖고 있다.
 

📌 1차원 배열과 포인터
int a[3] = {1, 2, 3}
int *p = a;

ㆍa[]의 주솟값을 각각 100, 101, 102 로 가정
ㆍp는 a의 주솟값인 100을 갖고 있음
ㆍ이를 표로 나타내면 다음과 같다

  a a[0] a[1] a[2]
주솟값 100 100 101 102
  1 2 3

p
100

그림을 꼭 그려서 포인터에 익숙해지길 바랍니다
ㆍp*는 '그 곳의 값'임을 명심

예제)
printf("%d", *p); // 100번지의 값 = 1 

printf("%d", *(p+1));
// p+1 먼저 계산; 100+1=101
// 그 다음 *(101) 계산; 101번지의 값 = 2

*p++ = 10;
// 연산이 2가지. *p = 10 & p++
// *p = 10 먼저 계산; p가 가리키는 곳의 값을 10으로 만들어라 -> a[0]의 값이 1에서 10으로 대입됨
// 그 다음 p++ 연산; p가 가리키는 곳인 100에서 ++ 해줘라. -> p가 가리키는 값이 100에서 101이 됨

*++p = 20;
// 연산이 2가지. *p = 20 & p++
// p++ 먼저 연산; p가 가리키는 곳인 101에서 ++ 해줘라. -> p가 가리키는 값이 101에서 102가 됨
// 그 다음 *p = 10 계산; p가 가리키는 곳의 값을 20으로 만들어라. -> a[3]의 값이 3에서 20으로 대입됨


📌 2차원 배열과 포인터
int a[3][2] = { {1, 2}, {3, 4}, {5, 6} };
int *p = a[1];

ㆍa[][]의 주솟값을 각각 100, 101, 102, 103, 104, 105 로 가정
ㆍp*는 '그 곳의 값'임을 명심
ㆍa는 100번지임을 명심
ㆍ*a도 100번지임을 명심. 왜냐하면 a가 가리키는 곳의 값은 대표행 a[0]의 주소를 의미
ㆍ**a는 '그 곳의 값의 값'임을 명심. 즉, 100번지의 값이므로 1

a
100

대표행주소 대표행
100 a[0] 1 2
102 a[1] 3 4
104 a[2] 5 6

p
102

예제)
printf("%d", *p); // p는 102, *(102)는 102번지의 값을 의미. ∴ *p = 3

printf("%d", *(p+2)); // p는 102, p+2는 104, *(104)는 104번지의 값을 의미. ∴ *(p+2) = 5

printf("%d", *(*a+1)); // *a는 100, *a+1은 100+1, *(101)은 101번지의 값을 의미. ∴ *(*a+1) = 2

printf("%d", *a[1]); // a[1]는 102, *(102)는 102번지의 값을 의미. ∴ *a[1] = 3


📌 2차원 배열과 포인터 배열
 
ㆍ포인터 배열: 포인터 변수의 배열화, 배열 요소에 주솟값이 있다
char *student[3] = { "kim", "lee", "han" };

ㆍstudent[]에는 주솟값이 들어감
ㆍstudent[]의 주솟값을 100번지 로 가정
ㆍkim, lee, han가 들어간 주솟값을 각각 20번지, 30번지, 40번지 로 가정
ㆍkim에서 k 20번지, i 21번지, m 22번지로 연속해서 주솟값이 들어간다. lee, han도 동일

student 20번지 30번지 40번지
100 100 101 102

20번지  k i m
30번지 l e e
40번지 h a n

예제)
printf("%s", *(student+1));
  // student + 1 계산 후 -> * 를 연산
  //ㆍstudent 은 100, student + 1은 101
  //ㆍ*(101)은 101의 값을 의미, 101의 값은 30번지, %s을 만났으니 30번지부터 NULL 만날 때까지 계속 출력.
  // ∴ lee


char *array[2] = { "Good morning", "C language" };

ㆍarray[]에는 주솟값이 들어감
ㆍarray[]의 주솟값을 100번지 로 가정
ㆍGood morning, C language의 주솟값을 각각 20번지, 50번지 로 가정

array 20번지 50번지
100 100 101

20번지  G o o d   m o r n i n g
50번지  C   l a n g u a g e

예제)
printf("%s", array[0]+5);
  // array[0]의 값은 20, array[0]+5는 25, 25번지부터 NULL 만날 때까지 문자열 출력.
  // ∴ morning

printf("%c", *(array[1]+6));
  // array[1]의 값은 50, array[1]+6은 56, *(56)은 56번지의 값.
  // ∴u


 

 

 

반응형