포스트

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 라이센스를 따릅니다.