프로그래밍의 기본 원리 2

Develop Kim·2024년 10월 24일

programmers

목록 보기
33/40

프로그래밍의 기본원리 0-1-1 ~ 1-2-4

1-2 변수와 자료형/연산자

1-2-5 연산자

  • 비트 연산자는 잘 사용하지 않음

  • =은 같다가 아닌 대입한다, ==가 같다는 의미의 연산자, ===는 타입까지 같은 경우

  • 값을 누적하는 경우 연산자를 축약하여 사용할 수 있음

    a=a+1a+=1로 축약할 수 있고,
    a=a+ba+=b와 같이 축약할 수 있음

  • 축약은 가독성에 따라 적용하면 됨

  • 증감연산자에서는 연산자의 위치를 주의해야 함

  • 아래 예시를 참고하면 증감연산자의 비교가 쉬움
#include <stdio.h>

int main()
{
    int a = 5;
    int b = 10;
    printf("%d", a++);

    return 0;
} // 6
#include <stdio.h>

int main()
{
    int a = 5;
    int b = 10;
    printf("%d\n", ++a);
    printf("%d", a);

    return 0;
} // 5, 6
#include <stdio.h>

int main()
{
    int a = 5;
    int b = 10;
    printf("%d\n", --b);
    printf("%d\n", b--);
    printf("%d", b);

    return 0;
} // 9, 9, 8
  • 비교 연산자

#include <stdio.h>

int main()
{
    int a = 10;
    int b = 11;
    printf("%d", a == b);

    return 0;
} // 0 
  // false임, 데시멀로 출력하여 0으로 출력
#include <stdio.h>

int main()
{
    int a = 10;
    int b = 11;
    printf("%d", a == b);

    return 0;
} // 1
  • 논리 연산자
  • 부정 연산자!는 피연산자의 결과를 모두 반대로 만들어 줌

  • 엔드 연산자&&는 값이 모두 참이어야 true를 반환

    AB결과
    111
    101
    010
    001
  • OR 연산자||는 둘 중 하나만 참이어도 참

    AB결과
    111
    101
    011
    000

#include <stdio.h>

int main()
{
    int a = 1;
    int b = 2;
    int c = 10;
    printf("%d", a * b * c);

    return 0;
}

#include <stdio.h>

int main() {
    int num1, num2, num3; 
    int sum;
    float average; // 실수이므로 float 사용

    // 사용자로부터 세 개의 정수를 입력받음
    scanf("%d", &num1);
    scanf("%d", &num2);
    scanf("%d", &num3);

    // 세 정수의 합 계산
    sum = num1 + num2 + num3;

    // 평균 계산
    average = sum / 3.0;

    // 합과 평균 출력
    printf("세 정수의 합: %d\n", sum);
    printf("세 정수의 평균: %.2f\n", average);    // 소수점 둘째 자리까지 출력

    return 0;
}

1-3 분기문/반복문

1-3-1 분기문(if문)

#include <stdio.h>

int main()
{
    int a;
    printf("%d", &a);
    if (a > 5){
        printf("5보다 큽니다\n")
    }

    return 0;
} // 5보다 큰 값을 입력하면 참 아니면 거짓

1-3-2 분기문(if-else)

  • 반복되는 로직에는 if만 쓰기보다는 else를 사용하여 코드를 깔끔하게 만들 수 있음
#include <stdio.h>

int main()
{
    int a;
    scanf("%d", &a);
    if (a > 5){
        printf("5보다 큽니다\n");
    } else {
        printf("5보다 크지 않습니다\n");
    };

    return 0;
}

1-3-3 분기문(if~else if문)

#include <stdio.h>

int main()
{
    int a;
    scanf("%d", &a);
    if (a > 5){
        printf("5보다 큽니다\n");
    } else if(a < 5) {
        printf("5보다 작습니다\n");
    } else if(a == 5) {
        printf("5입니다\n");
    } else {
        printf("입력값 잘못됨\n");
    };

    return 0;
}

#include <stdio.h>

int main()
{
    int a;
    scanf("%d", &a);
    if (a > 60){
        printf("합격\n");
    } else if(a < 60) {
        printf("불합격\n");
    } else if(a == 60) {
        printf("합격\n");
    } else {
        printf("입력값 잘못됨\n");
    };

    return 0;
}

#include <stdio.h>

int main()
{
    int a;
    scanf("%d", &a);
    if (90 > a > 60){
        printf("합격\n");
    } else if(a >= 90) {
        printf("장학생입니다\n");
    } else if(a < 60) {
        printf("불합격\n");
    } else if(a == 60) {
        printf("합격\n");
    } else {
        printf("입력값 잘못됨\n");
    };

    return 0;
}

#include <stdio.h>

int main()
{
    int a;
    scanf("%d", &a);
    if (20 > a > 13){
        printf("청소년\n");
    } else if(a > 19) {
        printf("성인\n");
    } else if(a < 13) {
        printf("어린이\n");
    } else {
        printf("입력값 잘못됨\n");
    };

    return 0;
}

#include <stdio.h>

int main()
{
    char a;  // 문자여서 int 대신 char 타입 사용
    printf("드라이브를 포멧할까요? (y/n): ");
    scanf(" %c", &a); 
    if (a == 'y'){
        printf("네 포멧하겠습니다\n");
    } else if(a == 'n') {
        printf("아니요 포멧하겠습니다\n");
    } else {
        printf("틀려서 포멧함\n");
    };

    return 0;
}

#include <stdio.h>

int main()
{
    int a;
    scanf("%d", &a);
    if (100 >= a > 91){
        printf("A\n");
    } else if(90 >=a > 81) {
        printf("B\n");
    } else if(80 >=a > 71) {
        printf("C\n");
    } else if(70 >=a > 61) {
        printf("D\n");
    } else {
        printf("F 낙제\n");
    };

    return 0;
}

1-3-4 반복문(while문)

  • 반복문은 반복이 거짓이 될 때 끝남, 참인 동안만 반복

#include <stdio.h>

int main()
{
    int i = 0;
    while(i < 5){
        printf("프로그래밍\n");
        i++;
    };

    return 0;
} // 문자열을 다섯번만 출력하고 끝남

#include <stdio.h>

int main()
{
    int i = 1;
    while(i <= 12){
        printf("%d월\n", i);
        i++;
    };

    return 0;
} // 12월까지 출력

#include <stdio.h>

int main()
{
    int i = 1;
    while(i < 10){
        printf("2 * %d = %d\n", i, 2*i);
        i++;
    };

    return 0;
} // 2 * 1 = 2 ...

1-3-5 반복문(이중 while문)

  • 밖의 반복문에서는 단수에 대한 반복처리를 하는 것이 좋음(천천히 반복하기 때문), 안쪽 반복문에서는 단수와 곱해지는 반복처리를 해주는 것이 좋음(빠르게 반복하기 때문)

  • 지구의 공전&자전 또는 육상트랙의 이치와 비슷하다

#include <stdio.h>

int main()
{
    int dan = 2;

    while(dan < 10){
        
        int i = 1;
        while(i < 10){
            printf("%d * %d = %d\n", dan, i, dan*i);
            i++;
        };
        dan++;
    }
    return 0;
} // 2*1=2 ... 9*9=81

#include <stdio.h>

int main() {
    int i, j;

    // 바깥쪽 반복문은 줄(row)을 나타냅니다 (1줄부터 5줄까지)
    for (i = 1; i <= 5; i++) {
        // 안쪽 반복문은 각 줄에 출력할 별의 개수를 나타냅니다
        for (j = 1; j <= i; j++) {
            printf("*");
        }
        // 한 줄을 다 출력한 후 줄바꿈
        printf("\n");
    }
    return 0;
}

1-3-6 반복문(무한루프)

  • 무한루프는 이벤트 기반의 어플리케이션에서 중요함
  • 메모장 어플에서 계속해서 입력할 수 있는 것도 무한루프임
    • 키보드 -> 운영체제 -> 메모장 앱으로 데이터가 넘어감
    • 이 때 무한루프가 돌면서 실시간으로 이벤트(글자입력)를 감시함
    • 단, 영원히 수행되지 않도록 메모장 어플을 끄면 무한루프도 종료하도록 만듦

1-3-7 반복문(for문)

  • for문은 기능적으로 while문과 동일하나 초기문, 조건문, 증감문을 한 눈에 볼 수 있다는 장점이 있음

  • 수행순서는 (1)초기화, (2)반복조건 확인, (3)반복 수행, (4)증가를 실행함
  • 위 수행순서를 끝내고 (2)부터 반복하는 것이 기본 수행로직

  • while문에도 초기문, 증감문이 사용되며, for문이 더 정돈된 형태임

#include <stdio.h>

int main()
{
    int dan, i;
    scanf("%d", &dan);
    
    for(i=1; i<10; i++){
        printf("%d * %d = %d\n", dan, i, dan*i);
    };

    return 0;
} // 입력하는 값의 구구단이 출력됨

1-3-8 반복문(break & continue)

#include <stdio.h>

int main()
{
    int a=0;
    while(1){
        if(a>100){
            break;
        }
        printf("a는 %d입니다\n", a);
        a++;
    };
    printf("a는 100보다 큼");

    return 0;
}; // 100이 출력될 때 break걸림
  • continue는 반복의 시작점으로 가게 됨, 일종의 스킵기능
#include <stdio.h>

int main()
{
    int a=0;
    
    while(a < 100){
        a++;
        if(a > 80 && a < 90){
            continue;
        }
        printf("a의 값 : %d\n", a);
    }
    return 0;
}; // 100까지 출력함

1-4 함수/배열/포인터

1-4-1 함수

  • 인수 = 매개변수 = 전달인자 = 파라미터
  • 자료형 = 데이터 타입

  • C언어에서 전달인수에는 타입이 붙음, 타입스크립트에서도 비슷한 형태

  • void 타입은 타입이 없다는 의미, 타입스크립트에서 자주 사용함

#include <stdio.h>

// 함수 작성
void calculateArea(int width, int height) {
    int area = width * height;
    printf("사각형의 넓이는: %d\n", area);
}

int main() {
    int width, height;
    // 사용자로부터 가로와 세로 길이를 입력 받음
    printf("가로의 길이를 입력하세요: ");
    scanf("%d", &width);
    printf("세로의 길이를 입력하세요: ");
    scanf("%d", &height);
    
    // 함수 호출하여 넓이 계산
    calculateArea(width, height);
    
    return 0;
}

#include <stdio.h>

// 자판기 함수 정의
void vendingMachine(int price) {
    if (price == 100) {
        printf("블랙커피를 제공합니다.\n");
    } else if (price == 200) {
        printf("밀크커피를 제공합니다.\n");
    } else {
        printf("잘못된 금액입니다. 100원 또는 200원을 넣어주세요.\n");
    }
}

int main() {
    int price;
    // 사용자로부터 금액 입력 받음
    printf("금액을 입력하세요 (100원: 블랙커피, 200원: 밀크커피): ");
    scanf("%d", &price);
    
    // 자판기 함수 호출
    vendingMachine(price);
    
    return 0;
}

1-4-2 변수의 범위

  • 각 지역에 있는 변수들은 이름이 같아도 충돌이 나지 않음

1-4-3 배열 1

  • 배열은 한꺼번에 많은 변수를 선언하고 싶어서 사용

  • 배열의 길이 = 변수의 개수

#include <stdio.h>

int main() {
    int arr1[5] = {1, 2, 3, 4, 5}; // 원본 배열
    int arr2[5];                   // 복사된 배열

    // 배열을 역순으로 복사
    for(int i = 0; i < 5; i++) {
        arr2[i] = arr1[4 - i];
    }

    // 결과 출력
    for(int i = 0; i < 5; i++) {
        printf("배열 arr2[%d] = %d\n", i, arr2[i]);
    }

    return 0;
}

1-4-4 배열 2

  • null은 왜 추가될까?

1-4-5 포인터

  • 특정 주소값만 보관하는 변수를 포인터 변수라고 함

  • 왜 포인터를 사용할까?
    • 윈도우 원격 제어기능을 보면 내가 직접 가지고 있는 변수는 아니지만 원격으로 가져와서 제어할 수 있는 점에서 비슷함
    • 즉, 직접적으로 참조하는 것이 아니라 간접참조한다는 장점

#include <stdio.h>

int main()
{
    int b = 100;
    int *pb = &b; // 여기서 *는 포인터임을 표기
    printf("b = %d\n", b);
    printf("b = %p\n", &b);
    printf("b = %p\n", pb);
    printf("b = %d", *pb); // 여기서 *는 해당메모리의 실제 값을 참조하라는 의미

    return 0;
}; /* 
b = 100
b = 0x7ffd0fbeae2c
b = 0x7ffd0fbeae2c
b = 100
*/ 

1-4-6 포인터와 배열

#include <stdio.h>

int main()
{
    int arr[] = {1,2,3,4,5};
    
    for(int i = 0; i < 5; i++){
        printf("%d\n", arr[i]);
        printf("%d\n", &arr[i]);
    }
    printf("배열의 이름 = %p\n", arr);

    return 0;
};
/*
1
723793824
2
723793828
3
723793832
4
723793836
5
723793840
배열의 이름 = 0x7ffc2b2437a0
*/ 
  • 위 코드를 보면 배열의 이름이 포인터라는 것을 알 수 있음
  • 일반적인 포인터와 다른 점은 배열의 이름은 상수이기 때문에 포인터 상수라고도 함

1-4-7 함수와 포인터

  • 복사에는 값에 의한 복사와 참조에 의한 복사가 있음

  • 전달인자가 많을 때는 코드가 난잡해질 수 있음
  • 이때 배열을 사용하면 한번에 전달할 수 있음(메모리 주소값을 넘겨주면 되는 것, 받을 때는 포인터 변수로 받음 이 과정에서 주소값이 복사됨(참조에 의한 복사))

#include <stdio.h>

void func(int *pArr){
    for(int i = 0; i <5; i++){
        printf("함수 안의 배열 : %d\n", *(pArr + i));
    }
};

int main()
{
    int arr[] = {1,2,3,4,5};
    
    func(arr);
    
    for(int i = 0; i < 5; i++){
        printf("%d\n", arr[i]);
        printf("%d\n", &arr[i]);
    }

    return 0;
}; /*
함수 안의 배열 : 1
함수 안의 배열 : 2
함수 안의 배열 : 3
함수 안의 배열 : 4
함수 안의 배열 : 5
1
1092842016
2
1092842020
3
1092842024
4
1092842028
5
1092842032
*/ 

profile
김개발의 개발여정

0개의 댓글