2024.06.13 프로그래머스 - C언어로 프로그래밍 근간 알아보기 2
C언어로 프로그래밍 근간 알아보기 2
개발을 할 떄, 무작정 키보드로 손이 가는 개발 보다는, 조금 더 고민해보고, 코드 흐름을 생각하며 차근차근 개발하는 습관을 들이는 것은 생각보다 더 중요하다.
연산자
- 정적인 데이터들을 유기적으로 행동하게 하여 새로운가치를 창출해 내는것
기능 | 연산자 종류 | ||
---|---|---|---|
산술 연산자 | +,-, *, / ,% | ||
대입 연산자 | =, +=, -=, *=, /=, %= | ||
부호 연산자 | +,- | ||
증감 연산자 | ++, — | ||
관계 연산자 | ==, ≠, <, >, ≤, ≥ | ||
논리 연산자 | , &&, ! | ||
비트 연산자 | !, &, », «, ~ |
산술 연산자
- 사칙연산에 사용되는 연산자
- +
- -
- *
- /
- %
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
int main()
{
int a = 5;
int b = 3;
printf("두 수의 합은 %d 입니다\n", a+b);
printf("두 수의 차는 %d 입니다\n", a-b);
printf("두 수의 곱은 %d 입니다\n", a*b);
printf("두 수를 나눈 값은 %d 입니다\n", a/b);
printf("두 수의 나머지는 %d 입니다\n", a%b);
return 0;
}
대입 연산자
- 오른쪽에 있는 값을 왼쪽에 대입하는 역할을 한다.
- 대입 연산자와 산술 연산자를 혼용해서 사용하기도 한다.
- 연산자
- =
- +=
- -=
- *=
- %=
- /=
증감 연산자
- 증가 연산자와 감소 연산자
- 연산자
- (전위)++ : 값을 1 증가 시킨 뒤 다른 연산을 진행
- (후위)++ : 다른 연산을 진행한 후 값을 1 증가
- (전위)— : 값을 1 감소 시킨 뒤 다른 연산을 진행
- (후위)— : 다른 연산을 진행한 뒤, 값을 1 감소
관계 연산자
- 두개의 피연산자의 관계를 따지는 연산자
- 연산자
- ==
- ≠
- >
- <
- ≥
- ≤
논리 연산자
- 두 개의
조건식
등을 결합하여 하나의 결과를 만들어 낸다 - 연산자
- !
- &&
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
int main()
{
int a = 10;
int b = 11;
int c = 12;
int d = 15;
printf("%d\n", (a == 10)); // 1
printf("%d\n", !(a == 10)); // 0
printf("%d\n", (a < b) && (a < c)); // 1
printf("%d\n", (a >= c) || (a == d)); // 0
printf("%d\n", (a >= c) || (a == d)); // 0
return 0;
}
연산자 연습 문제
사용자 로 부터 3 개의 정수를 입력 받아서, 3개의 수를 곱한 결과를 출력해라.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
#include <stdio.h> int main() { int a; int b; int c; printf("정수 1을 입력하세요 : "); scanf("%d",&a ); printf("정수 2을 입력하세요 : "); scanf("%d",&b ); printf("정수 3을 입력하세요 : "); scanf("%d",&c ); printf("세 정수의 곱 : %d", a*b*c); return 0; }
세 정수를 입력 받아 세 정수의 합과, 평균을 출력하는 코드 작성해라
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
#include <stdio.h> int main() { int a; int b; int c; printf("정수 1을 입력하세요 : "); scanf("%d",&a ); printf("정수 2을 입력하세요 : "); scanf("%d",&b ); printf("정수 3을 입력하세요 : "); scanf("%d",&c ); int sum = a + b + c; double avg = sum / 3; printf("세 정수의 합 : %d \n", sum); printf("세 정수의 평균 : %.1f", avg); return 0; }
분기문
- 특정 조건에 따라 코드 흐름의 방향을 나눈다.
- if…else (eise If) 문, swich문등을 이용하여 코드의 실행 흐름을 컨트롤 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// if...else 문
#include <stdio.h>
int main()
{
int a = 7;
if(a > 5){
printf("입력값이 5보다 큽니다.");
} else if(a == 7) {
printf("입력 값은 7입니다.");
} else {
printf("입력값이 5보다 작습니다.");
}
return 0;
}
입력값이 짝수 인지 홀수 인지 구분하는 코드 예제
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
#include <stdio.h> int main() { int input; printf("정수를 입력하세요 : "); scanf("%d",&input); if((input % 2) == 0) { printf("입력값은 짝수 입니다.\n"); } else { printf("입력값은 홀수 입니다.\n"); } printf("입력값 : %d", input); return 0; }
입력 받은 세개의 정수 값을 비교하여 최소 값을 출력하는 코드 예제
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
#include <stdio.h> int main() { int a; int b; int c; printf("정수 1을 입력하세요 : "); scanf("%d",&a ); printf("정수 2을 입력하세요 : "); scanf("%d",&b ); printf("정수 3을 입력하세요 : "); scanf("%d",&c ); if((a > c) && (b > c)) { printf("최소값은 정수3 : %d 입니다.\n", c); } else if((a >b) && (c > b)) { printf("최소값은 정수2 : %d 입니다.\n", b); } else if((b > a) && (c > a)) { printf("최소값은 정수1 : %d 입니다.\n", a); } else { printf("3개의 정수중 최솟값은 없습니다."); } return 0; }
사용자로부터 시험점수 (정수) 를 입력받아 60점 이상이면 합격, 미만이면 불합격, 90점 이상이면 장학대상임을 알리는 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
#include <stdio.h> void exam() { int input; printf("시험 점수를 입력해주세요 : "); scanf("%d", &input); if(input >= 60) { if (input >= 90) { printf("장학 대상입니다."); } else { printf("합격입니다."); } }else { printf("불합격 입니다."); }; return; } int main() { exam(); }
사용자로 부터 나이를 입력 받는다. 나이의 값이 13세 미만 이면 어린이임을 13이상 19세 미만이면 청소년 19세 이상이면 성인입니다 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
#include <stdio.h> void user_age() { int ageinput; printf("사용자의 나이를 입력해주세요 : "); scanf("%d",&ageinput); if(ageinput > 19) { printf("성인입니다."); } else if(ageinput < 19 && ageinput >= 13){ printf("청소년입니다."); } else { printf("어린이입니다."); } return; } int main() { user_age(); }
반복문
- for 문, while문
while문
1
2
3
while(반복조건){
//반복할 코드
}
- 반복 조건을 만족하는동인에는 while문의 반복 코드블럭을 계속해서 실행
- 반복 조건이 false가 될 때까지 반복한다.
- 반복 코드 블럭의 실행이 종료 되면, 반복 조건 확인 부분으로 다시 코드 흐름이 이동하여 반복 여부를 결정한다.
- 반복 조건에 항상 true가 반환되는 조건식을 작성하면
무한 Loop
가 발생한다.- 의도하지 않은 이상, 무한 Loop는 발생하지 않아야 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
void main () {
int i = 0;
while(i < 5) {
printf("programming\n");
i++;
}
return;
}
/*
programming
programming
programming
programming
programming
*/
while로 2단부터 9단까지 구구단 출력
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
#include <stdio.h> void main () { int i = 2; while (i <= 9){ int j = 1; while(j <= 9) { printf("%d * %d = %d\n", i,j,i*j); j++; } i++; } } /* 출력결과 2 * 1 = 2 2 * 2 = 4 2 * 3 = 6 2 * 4 = 8 2 * 5 = 10 2 * 6 = 12 2 * 7 = 14 2 * 8 = 16 2 * 9 = 18 3 * 1 = 3 3 * 2 = 6 3 * 3 = 9 3 * 4 = 12 3 * 5 = 15 3 * 6 = 18 3 * 7 = 21 3 * 8 = 24 3 * 9 = 27 4 * 1 = 4 4 * 2 = 8 4 * 3 = 12 4 * 4 = 16 4 * 5 = 20 4 * 6 = 24 4 * 7 = 28 4 * 8 = 32 4 * 9 = 36 5 * 1 = 5 5 * 2 = 10 5 * 3 = 15 5 * 4 = 20 5 * 5 = 25 5 * 6 = 30 5 * 7 = 35 5 * 8 = 40 5 * 9 = 45 6 * 1 = 6 6 * 2 = 12 6 * 3 = 18 6 * 4 = 24 6 * 5 = 30 6 * 6 = 36 6 * 7 = 42 6 * 8 = 48 6 * 9 = 54 7 * 1 = 7 7 * 2 = 14 7 * 3 = 21 7 * 4 = 28 7 * 5 = 35 7 * 6 = 42 7 * 7 = 49 7 * 8 = 56 7 * 9 = 63 8 * 1 = 8 8 * 2 = 16 8 * 3 = 24 8 * 4 = 32 8 * 5 = 40 8 * 6 = 48 8 * 7 = 56 8 * 8 = 64 8 * 9 = 72 9 * 1 = 9 9 * 2 = 18 9 * 3 = 27 9 * 4 = 36 9 * 5 = 45 9 * 6 = 54 9 * 7 = 63 9 * 8 = 72 9 * 9 = 81 */
1부터 사용자가 입력한 정수까지의 합을 출력하는 코드 작성 예제
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
#include <stdio.h> int sum(int input){ int start = 1; int temp = 0; while(temp < (input + 1) ){ start += start+1; printf("result : %d \n", start); temp++; } return start; } void main () { int userInput; printf("정수를 입력하세욥: "); scanf("%d", &userInput); int result = sum(userInput); printf("결과 : %d",result); return; }
별나무 출력하기
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
#include <stdio.h> // #include <ctype.h> void main (){ char * star = "*"; int temp = 0; while(temp < 5) { int temp_2 = 0; while(temp_2 < temp + 1) { printf("%c",star[0]); temp_2++; } printf("\n"); temp++; } return; }
for 문
- 기능적으로는 while문과 동일하나, 초기문, 조건문, 증감문을 이용하여 반복을 수행한다.
1
2
3
4
5
for(초기문; 조건문; 증감문){
// 반복 할 코드
// 코드 실행 종료시, 증감문 수행 후 조건문으로 이동
// 조건을 만족하면 다시 반복 코드 블럭으로 흐름이 진입한다.
}
- 간단한 for문 사용 예시 (구구단)
1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
void main (){
for(int i = 2; i < 10; i++) {
for(int j=1; j < 10; j++) {
printf("%d * %d = %d \n", i, j, i*j);
}
}
return;
}
break & continue
- continue : 다음 반복 흐름으로 바로 이동 ( 반복조건 검사 부터)
- break : 가장 가까운 반복문을 탈출
break와 continue 문 둘다, 사용시, 하위의 코드흐름을 무시한다.
짝수단만 출력하는 반복문
1 2 3 4 5 6 7 8 9 10 11 12 13 14
#include <stdio.h> void main (){ for(int i = 2; i < 10; i++) { if(i % 2 != 0) { continue; } for(int j=1; j < 10; j++) { printf("%d * %d = %d \n", i, j, i*j); } } return; }
함수
- 함수를 써야 하는 이유
- 코드의 가독성 향상
- 코드의 유지 보수 및 확장 용이
- 기능 분리
표준함수
- 사용하는 언어에서 기본적으로 제공해주는 함수
- 라이브러리화 되어 있어 개발자의 생산성을 높여준다.
사용자 정의 함수
- 사용자가 원하는 기능을 직접 만든 함수
- 표준 함수의 기능에는 한계가 있기 때문에 개발자 역량에 따라 뛰어난 사용자 정의 함수를 작성할 수 있다.
C언어의 사용자 정의 함수
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*
자료형 함수이름 (인수) {
함수 내용
}
*/
#include <stdio.h>
int Add (int a, int b) {
return a + b;
}
void main () {
int result = Add(6,10); // 16이 저장 된다.
return;
}
- 함수의 자료형 : 함수가 반환하는 값의 자료형
- 함수이름 : 함수 호출을 위해 사용되는 식별자
- 인수 : 함수 내 수행을 위해 호출부에서 넘겨받게 되는 인수를 선언
void 타입 함수
- 결과값을 리턴하지 않는 함수.
타입이 없음을 의미한다.
사각형의 넓이를 구하는 함수 작성 예제
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
#include <stdio.h> int getSquareArea(int width, int height) { return width * height; } void main (){ int width; int height; printf("사각형의 가로 길이를 입력해주세요 : "); scanf("%d", &width); printf("사각형의 세로 길이를 입력해주세요 : "); scanf("%d", &height); int result = getSquareArea(width, height); printf("입력한 사각형의 넓이 : %d",result); return; }
변수의 범위
- 지역변수, 전역변수, static 변수가 있다.
지역변수
- 특정 지역에서만 선언되어 사용가능한 변수
- 같은 이름이라도, 서로 다른 함수에 속해 있거나, 분리된 지역환경이라면, 서로 다른 변수이다.
- 지역변수는 속해있는 환경이 호출되거나 사용될 때,
스택메모리
에 등록되었다가, 해당 환경이 종료 되면 메모리상에서 삭제 된다. - 함수에 전달되는
매개변수
또한 스택 메모리에 할당 되는지역변수
이다.
전역변수
- 함수 바깥쪽에 선언되어,
전역적
으로 사용이 가능한 변수 - 코드의 복잡성이 증가하면, 전역변수를 사용하는 것을 지양 (필요한 상수 제외) 해야 한다.
- 전역변수는 나쁜것은 아니나, 코드 관리측면에서 충분한 고민 후 사용하는 것이 좋다.
- 전역변수는 프로그램이 실행 되는 순간부터
데이터 영역
에 저장되어있다가 프로그램이 종료 될 때 사라진다.
static 변수
- 고전상태의 변수를 뜻한다.
- 지역변수와 같은 지역적 환경을 가지고 있으나, 해당 지역이 종료되어도 메모리상에 고정되어 사라지지 않는다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
void func() {
static int value = 0;
value++;
printf("%d\n",value);
}
void main (){
int i = 0;
while(i < 5) {
func();
i++;
}
return;
}
/*
1
2
3
4
5
*/
배열
- 배열이란 ?
- 같은 속성 (자료형) 을 가진 요소들을 나열해 놓은 자료형
- 순서가 보장되어 있다.
- 배열의 요소는 같은 자료형을 가지고 있어야 한다.
1
2
3
4
5
6
7
8
9
10
11
int arr[100] = {1,2,3,4,5}
// 배열의 길이가 100 인 int형 요소를 가지는 배열
// 4byte * 100 = 400 byte
// arr[0] => 배열의 0번째 요소 접근
int arr2[] = {1,2,3};
// 배열의 길이지정을 생략
// => 초기값의 개수를 보고 자동으로 컴파일러가 배열의 길이를 계산하여 설정한다.
sizeof(arr) / sizeof(int);
// 지정한 배열의 자료형을 사용하여 배열의 길이를 구할 수 있다.
문자열
- C언어에서 문자열은 , char 의 배열의 형태이다.
1
char str[] = "Hello";
- 문자열은 저장될 값의 끝에항상 ‘\0’ 값을 저장한다
- 컴퓨터가 해당 메모리의 끝을 알기 위한 값
C언어의 포인터!
- 메모리는 주소를 통해 메모리에 접근하여 값을 읽고 쓸 수 있다.
- 문자 = 1 byte
- 정수 = 4 byte
- 실수 = 8 byte
포인터의 개념
- 포인터 변수의 줄임말
- 메모리의 주소값을 저장하고 있는 변수
- 주소값 저장 = 메모리를 가리킨다.
- 어느 특정 메모리 주소를 가리키거나 향하고 있다.
- 어떤한 변수 A의 주소값을 저장하고 있는 또 다른 변수 pA 의 개념!
포인터 변수 선언
*
를 통해 포인터 변수를 선언할 수 있다.1 2 3
char *pA; int *pB; double *pC;
포인터 변수에 변수의 주소값을 저장하는 방법
1 2
int b = 100; // 일반 변수할당 int *pb = &b; // 포인터 변수 pB가 변수 b의 주소값을 가리킨다.
1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
void main() {
int b = 100;
int *pB = &b;
printf("b = %d\n", b); // 100
printf("&b = %p\n", &b); // 0x7ffd45272f2c
printf("pB = %p\n", pB); // 0x7ffd45272f2c
printf("*pb = %d\n", *pB); // 100
}
포인터와 배열
- 배열의 이름은 배열의 요소의
첫 번째 주소값
을 갖는다.- 배열의 이름은 해당 배열을 가리키는 포인터임을 알 수 있다.
- arr == &arr[0] 이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
void main() {
int arr[] = {1,2,3,4,5};
for(int i = 0; i < 5; i++) {
printf("%d\n", arr[i]);
printf("%p\n", &arr[i]);
}
}
/*
1
0x7ffc973d2db0
2
0x7ffc973d2db4
3
0x7ffc973d2db8
4
0x7ffc973d2dbc
5
0x7ffc973d2dc0
주소값을 확인해 보면 4byte 씩 주소값이 증가하는 것을 알 수 있다.
*/
- 배열의 이름은
포인터
이다.- 일반 포인터와 다른점은
상수
이므로 주소값을 변경할 수 없다.
- 일반 포인터와 다른점은
함수와 포인터
- 기본적인 함수의 인자 전달은 복사의 형태로 이루어 진다.
- call by Value
- 메모리를 공유하는 것은 아니다!
- 함수에 여러개의 인자를 넘길때, 배열자체를 인자로 사용하여 넘겨주면 여러 값을 넘겨줄수 있다.
- 배열은 주소를 가지고 있다는 특성을 잘 인지해놓아야 한다.
- *포인터변수로 인수를 받아주도록 해준다.
- 함수 전달 형태에 따라 배열을 인자로 넘겨주면,
주소값
이 복사가 되는것! - 값자체를 넘기는 것이 아니고, 같은 메모리를
참조
하도록 하기 때문에, 성능상 이점이 있다.- 참조에 의한 복사 (call by reference)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <stdio.h>
void func(int *pArr) //2. 포인터 변수로 인수를 받아준다.
{
for (int i = 0; i < 5; i++) {
printf(" 함수안의 배열 : %d\n", *(pArr + i));
// pArr 에 + i 를 하는 이유는, 시작값 에서 1칸씩 (요소 1개씩)의 주소를 가리키게 되고
// * 키워드를 통해 해당 주소가 실제 가지는 값을 사용할 수 있다.
// 1, 2, 3, 4 , 5 전부 출력 된다.
}
}
void main() {
int arr[] = {1,2,3,4,5};
func(arr); // 1 . 배열의 주소값 (첫번째) 가 인수로 넘어간다.
}
/*
<출력>
함수안의 배열 : 1
함수안의 배열 : 2
함수안의 배열 : 3
함수안의 배열 : 4
함수안의 배열 : 5
*/
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.