중첩반복문


  • 중첩반복문에서 break 문이 실행될 경우, 하나의 반복문만 벗어난다.

예시


2중 중첩 for 문을 사용하여 구구단을 출력하는 프로그램을 작성하라.



public class NestedLoop {
    public static void main(String[] args) {
        for(int i=1; i<10; i++) {
            for(int j= 1; j<10; j++) {
                System.out.print(i+"*"+"="+ i*j);
                System.out.print('\t');
            }
            System.out.println();
        }
    }
}

실행결과
1*=1    1*=2    1*=3    1*=4    1*=5    1*=6    1*=7    1*=8    1*=9    
2*=2    2*=4    2*=6    2*=8    2*=10    2*=12    2*=14    2*=16    2*=18    
3*=3    3*=6    3*=9    3*=12    3*=15    3*=18    3*=21    3*=24    3*=27    
4*=4    4*=8    4*=12    4*=16    4*=20    4*=24    4*=28    4*=32    4*=36    
5*=5    5*=10    5*=15    5*=20    5*=25    5*=30    5*=35    5*=40    5*=45    
6*=6    6*=12    6*=18    6*=24    6*=30    6*=36    6*=42    6*=48    6*=54    
7*=7    7*=14    7*=21    7*=28    7*=35    7*=42    7*=49    7*=56    7*=63    
8*=8    8*=16    8*=24    8*=32    8*=40    8*=48    8*=56    8*=64    8*=72    
9*=9    9*=18    9*=27    9*=36    9*=45    9*=54    9*=63    9*=72    9*=81    

continue 문


  • continue 문이 실행되면 for 문은 반복 후 작업 단계로 넘어간다.
  • continue 문이 실행되면 do-while 문과 while 문은 조건식으로 넘어간다.

예시


5개의 정수를 입력받고 그 중 양수들만 합하여 출력하는 프로그램을 작성하라.
(입력된 수가 0이나 음수이면 continue 문을 이용하여 합하지 않고 다음 반복으로 넘어간다.)


import java.util.Scanner;

public class ContinueExample {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        int sum = 0;
        int input; 
        int i;
        for(i= 1; i<=5; i++) {
            input = scanner.nextInt();
            if(input <=0)
                continue;
            else
                sum +=input;
        }
        System.out.print("합:"+sum);
        scanner.close();
    }
}

실행결과
3
-5
19
-9
33
합:55

break 문


  • break 문이 실행되면 현재 반복문을 벗어난다.

예시


"exit"이 입력되면 while 문을 벗어나도록 break 문을 활용하는 프로그램을 작성하라.


import java.util.Scanner;
public class BreakExample {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.println("exit를 입력하면 종료합니다.");
        while(true) {
            System.out.print(">>");
            String text = scanner.nextLine();
            if(text.equals("exit"))
                break;
        }
        System.out.println("종료합니다...");
        scanner.close();
    }
}

실행결과
exit를 입력하면 종료합니다.
>>edit
>>check
>>exit
종료합니다...

특정한 문자열이 입력될 때까지 계속 반복하도록 하기 위해서 먼저 while 문 조건식에 true를 해서 무한반복하도록 한다. Scanner 클래스를 이용해서 값을 입력받고 if문을 활용하여 "exit"를 입력받으면 break 문을 통하여 while 문을 빠져나오도록 한다.


while 문을 무한반복하도록 한 뒤, if 문을 활용해서 반복을 탈출하도록 코딩하는 것이 꿀팁이다.!! 문자열 비교 시 equals()를 사용한다. 문자열이 같으면 equals()는 true를 리턴한다.

for 문

 

for (초기문; 조건식; 반복 후 작업) {
    ..작업문..
}

 

  • 반복 횟수를 아는 경우에 사용한다.
  • 초기문은 시작할 때 한 번만 실행된다.
  • 초기문에 ','를 사용하여 여러문장을 나열할 수 있다.
  • 조건식에 true 가 있거나 비어 있으면 무한 반복된다.
  • 작업문이 실행된 후, 반복 후 작업이 실행된다.

 

예시

 

for 문을 이용하여 1에서 10까지 덧셈으로 표시하고 합을 출력하라.

 

public class ForSample {
    public static void main(String[] args) {
        int sum = 0;

        for(int i=1; i<=10; i++) {
            sum += i;
            System.out.print(i);
            if(i<10)
                System.out.print("+");
        }

        System.out.print("="+sum);
    }
}

 

실행결과
1+2+3+4+5+6+7+8+9+10=55

for 문에서 1부터 10까지의 합을 sum변수에 대입하고 이를 출력한다.

 

while 문

 

whlie (조건식){
    ...작업문...
}

 

  • 조건식이 true 를 만족하는 동안 작업문을 반복 실행한다.
  • 조건식이 없으면 컴파일 오류가 발생한다.

 

예시

 

while 문을 이용하여 -1이 입력될 때까지 정수를 계속 입력받아 합을 구하고 평균을 출력하는 프로그램을 작성하라.

 

import java.util.Scanner;

public class WhileSample {
    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        int sum = 0;
        double avg;
        int count = 0;
        int input = scanner.nextInt();
        while(input!= -1) {

            sum = sum + input;
            count ++;
            input = scanner.nextInt();

        }
        avg= (double)sum/count;

        System.out.print("합:"+sum+", 평균:"+avg);
        scanner.close();
    }
}

 

실행결과
38
20
-33
29
15
-1
합:69, 평균:13.8

 

정수를 입력받기 위해서 Scanner클래스를 이용한다. 입력받은 정수를 저장하기 위해서 sum을 선언하고, 입력받은 값들의 평균을 구하기 위해서 avg를 선언한다. 입력받은 값이 -1이 아닐동안에 값을 반복 입력받고 sum변수에 값을 계속 누적한다. 입력받은 값이 -1이라면, 이때까지 입력받은 값들의 합을 입력받은 횟수로 나누어서 평균을 구한다. 그리고 합과 평균을 출력한다.

 

조건식이 만족할 동안에 반복실행하기 때문에 scanner 메소드가 반복문 안에 있어야 한다.

 

do-whlie 문

 

do {
    ..작업문..
} while(조건식);

 

  • 작업문 실행 후 조건식을 검사하므로 작업문은 최초 한 번은 반드시 실행된다.
  • 조건식 뒤에 세미콜론을 빠뜨리지 않도록 한다.

 

예시

 

do-while 문을 이용하여 'a'부터 'z'까지 출력하는 프로그램을 작성하라.

 


public class DoWhileSample {
    public static void main(String[] args) {
        char c = 'a';

        do {
            System.out.print(c);
            c = (char)(c+1);
        }while(c<='z');
    }
}

 

실행결과
abcdefghijklmnopqrstuvwxyz

 

char 변수c 를 선언하고 문자리터럴 'a'로 초기화한다. do-while 문에서 일단 c 를 출력하고 c에 1만큼 더한 뒤(내부적으로는 c에 일대일대응되는 숫자값과 1을 더한 뒤 다시 char형으로 변환한다.), 이를 c가 'z'보다 작거나 같을 때가지 반복한다.

do-while 문을 활용하여 문자 리터럴과 문자열 사이의 개념을 다진 좋은 예제였다. 이 부분에 대해서는 나중에 추가적인 공부가 필요하리라 생각된다.

if 문


if(조건식){
    실행문장
    }

  • 조건식이 참이면, 문장을 실행한다.

예시


시험점수가 80점 이상이라면 합격 판별을 하는 프로그램

import java.util.Scanner;

public class SuccessOrFail {
    public static void main (String[] args) {
        Scanner scanner = new Scanner(System.in);


        System.out.print("정수를 입력하시오:");
        int score = scanner.nextInt();
        if (score >= 80)
            System.out.println("축하합니다.! 합격입니다.");

        scanner.close();
    }
}

실행결과
정수를 입력하시오:90
축하합니다.! 합격입니다.

시험점수를 입력받기위해서 Scanner 클래스를 import한다. 이를 이용하여서 사용자로부터 값을 입력받고, 입력받은 값을 nextInt()메소드를 이용해서 score변수에 대입한다. if문 조건식score가 80보다 크거나 같으면 아래의 문장을 실행한다. 마지막으로 프로그램을 종료하기 전에 clsoe()메소드로 scanner를 종료한다.


if문에서는 문제를 해결하기 위한 알맞은 조건을 조건식으로 설정하는 것이 가장 중요햐다.


if-else 문


  • 실행문장이 하나일 경우에는 중괄호 생략이 가능하다.
  • if문 조건식이 참이라면 아래문장을 실행하고, 거짓이라면, else문을 실행한다.

if(조건식){
    실행문장
    }
else {
    실행문장
}

예시


입력된 수가 3의 배수인지 판별하는 프로그램

import java.util.Scanner;

public class MultipleOfThree {
    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        System.out.print("수를 입력하시오: ");

        int num = scanner.nextInt();
        if(num%3 ==0) {
            System.out.println("3의 배수입니다.");

        }
        else {
            System.out.println("3의 배수가 아닙니다.");
        }
    }
}

실행결과
수를 입력하시오: 267
3의 배수입니다.

수를 입력받기 위해서 Scanner클래스를 사용한다. 정수형 변수 num을 선언하면서 nextInt()메소드를 대입한다. num이 3으로 나누었을 때, 나머지가 0이면 아래의 문장을 실행한다. 나머지가 0이라는 말은 곧, "3의 배수이면"과 같다. 조건식이 거짓이면, "3의 배수가 아님을 출력한다.".


다중 if-else 문


  • if-else문에 else if문이 추가된 형태이다.

예시


다중 if-else 문을 이용하여 입력받은 성적에 대해 학점을 부여하는 프로그램


import java.util.Scanner;

public class Grading {
    public static void main(String[] args) {
        char grade;
        Scanner scanner = new Scanner(System.in);

        System.out.print("점수를 입력하시오(0-100): ");
        int num = scanner.nextInt();

        if(num >= 90)
            grade = 'A';
        else if(num >= 80)
            grade = 'B';
        else if(num >= 70)
            grade = 'C';
        else if(num >= 60)
            grade = 'D';
        else
            grade = 'F';
        System.out.print("학점은 "+ grade + "입니다.");

        scanner.close();
    }
}

실행결과
점수를 입력하시오(0-100):79
학점은 C입니다.

if문 조건식이 거짓이면, else if문의 조건식을 검사한다. 조건식이 참이면, 문장을 실행하고 아니면 아래의 else if문의 조건식을 검사한다.


if-else문을 조건연산자 '?' ':'으로 변경할 수 있다.

switch 문

switch (식){
    case 값1:
    break;
     case 값2:
    break;
...
case 값n:
    case 값n;
    break;
default:
    실해문장 m;

  • 특정한 값에 따라 여러 방향으로 분기하는 경우, switch문을 사용하면 가독성이 높은 코드를 작성할 수 있다.
  • switch문 식을 case문의 값과 비교한다. 이때, case문의 값은 정수 리터럴, 문자 리터럴, 문자열 리터럴 만 허용한다.
  • case문의 값 중에서 변수나 식은 사용할 수 없다.

예시


switch문을 이용하여 커피 메뉴의 가격을 알려주는 프로그램을 작성하라. 에스프레소, 카푸치노, 카페라떼는 3500원이고, 아메리카노는 2000원이다.


import java.util.Scanner;
public class CoffeePrice {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int price = 0;

        System.out.print("무슨 커피를 드릴까요?");
        String order = scanner.next();

        switch(order) {
        case "에스프레소":
        case "카푸치노":
        case "카페라떼":
            price = 3500;
            break;
        case "아메리카노":
            price = 2000;
            break;
        default:
                System.out.println("메뉴없음");

        }
        if(price!= 0) System.out.print(order + "는 " + price + "원입니다.");
        scanner.close();

    }
}

실행결과
무슨 커피를 드릴까요?카푸치노
카푸치노는 3500원입니다.

Scanner클래스로 입력받은 값을 String클래스 order에 대입한다. switch문 식을 order로 하여서 이를 case문의 값과 비교하도록 하고 이를 만족하면, 설정해놓은 price값을 대입한다. 이때, 해당하는 조건이 없을 경우에는 "메뉴없음"을 출력하도록 한다.
price값이 '0'이 아니라면, 커피 메뉴의 가격을 출력하도록 한다.


default문은 생략가능하다. break;를 만나면, switch문을 벗어난다.

Scanner scanner = new Scanner(System.in);


  • System.in은 표준 입력 스트림 객체이다.
  • import문이 필요하다. (import java.util.Scanner;)
  • System.in은 단순히 키 입력을 바이트 형태로 입력 받기에 이를 사용자가 원하는 타입으로 바꾸는 Scanner 클래스가 필요하다.
  • 일반적으로 Scanner 클래스는 키 값을 토큰 단위로 읽는다.(토큰은 공백 문자를 기준으로 분리한 단위를 말한다.)

예시

import java.util.Scanner;

public class ScannerEx {
    public static void main(String[] args) {
        System.out.println("이름, 도시, 나이,체중, 독신 여부를 빈칸으로 분리하여 입력:");
        Scanner scanner = new Scanner(System.in);

        String name = scanner.next();
        System.out.print("이름은 "+name+", ");

        String city = scanner.next();
        System.out.print("도시는 "+city+" ");

        int age = scanner.nextInt();
        System.out.print("나이는 "+age+" ");

        double weight = scanner.nextDouble();
        System.out.print("체중은 "+weight+" ");

        boolean isSingle = scanner.nextBoolean();
        System.out.print("독신 여부는 "+isSingle+" ");
        scanner.close();
    }
}

실행결과
이름, 도시, 나이,체중, 독신 여부를 빈칸으로 분리하여 입력:
Kim Seoul 20 65.1 true
이름은 Kim, 도시는 Seoul 나이는 20 체중은 65.1 독신 여부는 true 

사용자로부터 값을 입력 받기 위해서 Scanner클래스를 import한다. 클래스 내에서 Scanner 객체를 생성하여 사용자로부터 값을 입력받는다. 문자열 형태로 입력 받기 위해서 next()메소드를 사용한다. 나이를 입력 받기 위해서 nextInt()매소드를 사용한다. 체중 값을 입력 받기 위해서 nextDouble()메소드를 사용한다. 독신여부를 나타내기 위해서 nextBoolean()메소드를 사용한다. 다 사용하였으므로 scanner 객체의 사용을 종료하기 위해서 close()메소드를 사용하였다.


클래스 내에서 함수를 사용하였기에 '메소드'라 부른다. System.in을 통해 받은 데이터를 사용자가 원하는 타입으로 바꾸기 위해서 Scanner 클래스를 사용한다. scanner.close()가 없어도 프로그램이 종료되면 자동으로 닫힌다.

System.out.print(), System.out.println()


  • 정수, 문자, 문자열 등 데이터를 화면 출력하기 위해 사용한다.
  • import 필요없다.

예시

public class ConsolePrint1 {
    public static void main(String[] args) {

        System.out.print("Hello");
        System.out.println(" World");
        System.out.println(3);
        System.out.println(2*5);


    }
}

실행결과
Hello World
3
10

System.out.println()의 경우 화면에 출력하고 다음 줄로 이동하지만, System.out.print()은 다음 줄로 이동하지 않는다.
System.out.println()대신에 이스케이프 시퀀스 '\n'를 사용할 수 있다.


그냥 위와 같다고 배웠지, 어떠한 원리로 인하여 위와 같은지 정확하게 모른다. 추가 보충이 필요한 부분이다.


String에 대한 간단한 이해


  • String은 JAVA에서 기본 타입에 속하지 않는다. 자바 라이브러리에서 제공하는 클래스이다.
  • 문자열을 사용해야 할 때, String 클래스를 이용한다.

예시


public class UnderstandString {
    public static void main(String[] args) {

        String toolName = "JDK";
        toolName = toolName + 1.8;
        System.out.println("("+3+","+"5"+")");
        System.out.println(toolName + "이 출시됨");
    }
}

실행결과
(3,5)
JDK1.8이 출시됨

toolName이라는 String클래스를 선언하고 "JDK"로 초기화한다. toolName에 1.8를 더해서 다시 대입한다. 이를 화면에 출력하여 어떠한 값이 나오는지 확인한다.


String클래스와 기본 타입의 +연산은 기본 타입의 값이 문자열로 바뀐다. 두 문자열이 연결되어 새로운 문자열이 생성된다.

 

2차원 배열 선언과 요소 사용

 

  • 2차원 배열은 1차원 배열을 요소로 가지는 1차원 배열이다.
  • 논리적으로 [N] x [N] 행렬과 구조가 같다.
  • 물리적으로 1차원 배열을 첨자 순서대로 메모리 공간에 나열한 것이다.
  • 배열명 옆에 있는 대괄호를 '첨자' 라 칭한다.
  • 배열에서 특정 요소를 구분하기 위해서 첨자 '[]'를 사용한다.

 

예시

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>


int main(void) {

    int stu[3][4];
    int tot;
    double avg;

    int i, j;

    for (i = 0; i < 3; i++) {

        for (j = 0; j < 4; j++) {

            scanf("%d", &stu[i][j]);

        }
    }

    for (i = 0; i < 3; i++) {
        tot = 0;
        for (j = 0; j < 4; j++) {
            tot += stu[i][j];

        }
        avg = tot / 4.0;
        printf("총점: %d, 평균 : %.1lf\n", tot, avg);
    }

    return 0;
}

 

실행결과
72 80 95 60
68 98 83 90
75 72 84 90
총점: 307, 평균 : 76.8
총점: 339, 평균 : 84.8
총점: 321, 평균 : 80.2

 

학생 3명 당 각 4과목씩 과목별 점수를 입력 받아서 총점과 평균을 출력하는 프로그램이다. main()에서 stu배열을 선언한 뒤, 2중 for문을 이용하여서 각 배열의 요소에 값을 입력받고, 2중 for문을 이용하여서 출력한다.

 

2중 for문에서 바깥쪽 for문이 배열의 행에 해당하고, 안쪽 for문이 배열의 열에 해당한다.

 

2차원 char 배열

 

예시 1 (char 배열 초기화)

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(void) {

    char animal[5][20];
    int i;
    int count;

    count = sizeof(animal) / sizeof(animal[0]);

    for (i = 0; i < count; i++) {

        scanf("%s", animal[i]);
    }

    for (i = 0; i < count; i++) {

        printf("%s", animal[i]);
    }

    return 0;

}

 

실행결과
dog
tiger
rabbit
horse
cat
dog tiger rabbit horse cat

 

5 * 20 animal 문자열 배열을 선언한다. for문에서 배열의 행 수를 이용하기 위해서 count 변수를 선언하고 초기화한다. 행의 수는 전체 배열의 크기를 첫번째 행의 크기로 나눈 몫이다. 이를 통해 구한 count를 이용하여서 animal에 문자열을 입력받고 출력한다.

 

여러개의 문자열은 char배열을 이용하여 처리한다. scanf()에서 배열명의 표현식을 변수로 오해할 수 있지만, 2차원 배열에서는 부분배열의 이름이 된다. 이름이 된다는 것은 곧, 주소값을 인수로 준다는 것이고, 이는 scanf() 인수전달조건을 만족한다.

 

예시 2 (char 배열의 초기화 방법)

#include <stdio.h>

int main(void) {

    char animal1[5][10] = {
        {'d','o','g','\0'},
        {'t','i','g','e','r','\0'},
        {'r','a','b','b','i','t','\0'},
        {'h','o','r','s','e','\0'},
        {'c','a','t','\0'}
    };

    char animal2[][10] = { "dog","tiger", "rabbit","horse","cat" };
    int i;

    for (i = 0; i < 5; i++) {
        printf("%s ", animal1[i]);
    }
    printf("\n");
    for (i = 0; i < 5; i++) {
        printf("%s ", animal2[i]);
    }

    return 0;
}

 

실행결과
dog tiger rabbit horse cat
dog tiger rabbit horse cat

 

char 배열을 선언하고 초기화할 때, 각 요소에 문자 상수로 초기화 할 수 있다(animal1 배열). 또는 문자열 상수로 초기화 할 수 있다.(animal2 배열) 문자열 상수로 초기화하면, 문자열 상수의 개수가 배열의 행의 수가 된다.

 

CALL BY VALUE는 함수를 호출할 때 인수로 값을 복사하여 주는 방식이고, CALL BY REFERENCE는 호출 함수의 변수를 호출되는 함수에서 매개변수의 이름으로 직접 사용하는 방식이다.


함수의 인수를 값으로 복사하여 전달하는 경우

  • 함수를 호출할 때, 호출한 함수명 옆 소괄호 안에 있는 데이터를 '인수' 라 칭한다.
  • 호출된 함수에서, 함수명 옆 소괄호 안에 있는 데이터를 '매개변수' 라 칭한다.

예시 1

#include <stdio.h>

void add_ten(int a);

int main(void) {

    int a = 10;

    add_ten(a);

    printf("a: %d",a);

    return 0;
}


void add_ten(int a) {

    a = a + 10;
}

실행결과
a: 10

main()에서 정수형 변수를 선언 및 초기화한다. add_ten()를 호출한다. 이 함수 정의를 보면, 매개변수로 main()의 변수 a의 값 10을 복사한 것을 받아서 다시 10를 더한 뒤 함수를 반환없이 함수를 종료한다. 이후 main()에서 printf()를 통해 값을 확인하면 값의 변화가 없다.

main()에 있는 변수의 값을 직접적으로 바꾼 것이 아니라, 값을 복사한 것을 사용하였기 때문에 a변수 값에 영향을 주지 않는다. 따라서 값이 그대로인 것이다.


함수의 인수로 주소값을 전달하는 경우


  • 주소값을 전달하므로 포인터에 대한 이해가 필요하다.

예시

#include <stdio.h>

void add_ten(int* pa);

int main(void) {



    int a = 10;
    add_ten(&a);

    printf("a: %d", a); 
}


void add_ten(int* pa) {

    *pa = *pa + 10;

}

실행결과
a: 20

정수형 변수 a를 선언 및 10으로 초기화한다. add_ten()의 인수로 변수 a의 주소값을 넘겨준다. add_ten()정의를 보면, 호출한 함수에서 호출된 함수로 주소값을 넘겨주었으므로 이를 넘겨받기 위해서 정수형 포인터 변수를 매개변수로 선언하였다. 포인터 변수pa가 가리키는 곳의 값에 10을 더해서 포인터가 변수가 가리키는 곳에 대입한다. 포인터 변수pa는 값 20을 가지게 되고 함수가 종료된다. main()에서 printf()를 호출하여 값을 확인하면 a값이 20으로 변경된 것을 확인할 수 있다.


주소값을 넘겨주는 방식도 call by value인 이유는 호출할 때 인수로 주소값을 넘겨주어서 직접적으로 메모리공간에 접근할 수 있지만 결국에는 '주소값'을 넘겨준 것이고 이를 간접참조연산을 활용한 포인터로 받은 것이기 때문에 이러한 방식도 call by value에 해당한다.


지역변수는 블록 내부에서 사용하는 변수이다.

  • 사용범위는 블록 내부로 한정된다.
  • 함수 형태
  • auto 자료형 변수명; // 'auto'는 생략 가능하다.

예시1


#include <stdio.h>

void assign(void);


int main(void) {

    auto int a = 0;

    assign();

    printf("\nmain함수 a:%d\n", a);

    return 0;
}


void assign() {
    int a;

    a = 10;
    printf("assign 함수a:%d", a);
}

실행결과
assign 함수a:10
main함수 a:0

정수형 지역변수 a를 선언 및 초기화 한다. assign()를 호출한다. 호출된 함수 정의를 보면, main()내에 있는 같은 이름의 지역변수를 선언하였다. 서로 다른 블록 내에 있기 때문에 헷갈릴 수 있지만 같은 이름을 다른 함수에서 사용할 수 있다. a에 10를 대입하고 함수를 출력한다. 그리고 다시 main()으로 돌아와서 printf()를 호출하면, 어떠한 값이 나오는지 확인한다.

같은 이름일지라도 다른 서로 다른 변수이기 때문에 '0' 값이 출력된다.


예시2


    #include<stdio.h>

int main(void) {

    int a = 10, b = 20;

    printf("교환 전 a와 b의 값: %d, %d\n", a, b);
    {
    int temp, a,b;
    a = 11;
    b = 12;
    temp = a;
    a = b;
    b = temp;
    }
    printf("교환 후 a와 b의 값: %d, %d\n", a, b);





    return 0;
}

실행결과 교환 전 a와 b의 값: 10, 20 교환 후 a와 b의 값: 10, 20

main()내에 정수형 지역변수 a와 b를 선언 및 초기화한다. 먼저 a,b값을 콘송창에 출력해서 값을 확인한다. 그다음에 중괄호를 사용하고 중괄호 내부에 이름이 같은 a,b변수와 임시로 사용할 temp변수를 선언한다. 마치 자료구조 기초에서 배우는 swap()처럼 a와 b의 값을 temp를 이용하여 바꾼다. 그리고 중괄호 바깥에 printf()함수를 호출하여 어떠한 값이 나오는지 확인한다.


전역변수는 함수밖에시 선언하는 변수이다.

  • 사용범위는 프로그램 전체 그리고 종료시까지이다.
  • 전역변수를 선언한 뒤 따로 초기화 하지 않으면 0으로 초기화 된다.

예시


#include <stdio.h>

void assign10(void);
void assign20(void);


int a;

int main(void) {


    printf("함수 호출 전 a값:%d\n", a);

    assign10();
    printf("함수 호출 후 a값1: %d\n", a);

    assign20();

    printf("함수 호출 후 a값2: %d\n", a);



    return 0;
}

void assign10(void) {

    a = 10;
}

void assign20(void) {
    int a;
    a = 20;
}

실행결과
함수 호출 전 a값:0
함수 호출 후 a값1: 10
함수 호출 후 a값2: 10

main()바깥에 전역변수 a를 선언한다. 선언한 a값을 확인하기 위해서 printf()를 호출하여 값을 확인한다. assign10()함수를 호출한다. 그리고 다시 main()에서 printf()를 호출하여 a값을 확인한다. 여기까지 쉽게 값을 알 수 있다. 그 다음에 assign2()함수를 호출한다. assign20()정의를 보면, 정수형 지역변수를 선언하고 a에 20을 대입한다. 그리고 다시 main()내에서 printf()함수를 호출하여 어떠한 값이 나오는지 확인한다.


마지막 실행결과를 보면, a의 값이 바뀌지 않은 이유는 전역변수와 지역변수의 이름이 같으면 지역 변수를 먼저 사용하기 때문이다.

정적지역변수는 함수가 반환되더라도 정적지역변수가 할당된 메모리 공간을 유지하는 변수이다.


  • 지역변수이기에 사용범위는 블록 내부로 제한된다.
  • 할당된 메모리 공간은 프로그램이 실행되는 동안 유지된다.
  • 초기화하지 않으면 0으로 자동 초기화된다.

예시

    #include <stdio.h>

void auto_func(void);
void static_func(void);

int main(void) {
    int i;

    printf("일반 지역 변수(auto)를 사용한 함수...\n");
    for (i = 0; i < 3; i++) {
        auto_func();
    }


    for (i = 0; i < 3; i++) {
        static_func();
    }

    return 0;
}

void auto_func() {

    auto int a = 0;
    a++;
    printf("%d\n", a);
}

void static_func() {
    static int a;

    a++;
    printf("%d\n", a);
}

실행결과
일반 지역 변수(auto)를 사용한 함수...
1
1
1
1
2
3

main()안에서 for문을 이용하여 auto_func()를 총 3번 반복호출한다. auto_func()정의를 보면, 정수형 지역변수 a를 선언 및 초기화한다. 그리고 값을 1씩 증가시킨다. 이후 printf()를 호출하여 값을 확인한다. auto_func()가 호출될 때마다, 지역변수 a를 새롭게 선언 및 초기화하기 때문에 똑같은 값이 출력되는 것을 확인할 수 있다. 이후 똑같이 static_func()정의를 보면, 정적 지역변수 a를 선언하고 값을 1씩 증가시키고 printf()를 호출하여 값을 확인하면, 값이 증가된 것을 확인할 수 있다.


static_func()가 반환되더라도 정적 지역변수a가 할당된 메모리 공간은 반환되지 않고 남아있기 때문에 값이 증가하였다.


레지스터 변수는 메모리 대신에 CPU안에 레지스터를 저장공간을 사용하는 변수이다.

  • 레지스터 사용여부는 컴파일러가 결정한다.
  • CPU안에 있는 레지스터에 할당되기 때문에 데이터 처리 속도가 빠르다.
  • 사용횟수가 많은 경우에 주로 사용하여 실행 시간을 줄일 수 있다.
  • 변수 형태
    register 자료형 변수명;

예시


    #include <stdio.h>

int main(void) {


    register int i;
    auto int sum = 0;

    for (i = 0; i <= 10000; i++) {
        sum += i;
    }
    printf("%d\n", sum);

    return 0;
}

실행결과
50005000

레지스터 정수형 변수 i를 선언한다. 값을 저장할 변수 sum을 선언 및 초기화한다. 반복문을 사용하여서 1부터 10000까지 차례대로 값을 증가시키면서 sum에 대입한다. 마지막으로 printf()를 호출하여 값을 확인한다.


변수 i의 경우 조건식에서 한 번, 중괄호 내부에서 한 번, 증감식 한 번 그래서 sum보다 약 3배이상 반복사용하기 때문에 레지스터 변수로 선언하였다.

문자열 대입함수이다.


strcpy함수는 문자열을 대입하는 함수이다.


  • <string.h>안에 내장되어 있다.
  • #define _CRT_SECURE_NO_WARINGS 를 사용해야한다.
  • 함수 형태
  • strcpy(str1, str2) // 첫번재 인수에는 문자열 받을 곳, 두번째 인수에는 대입할 문자열

예시

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

int main(void) {


    char str1[80] = "strawberry";
    char str2[80] = "apple";
    char* ps1 = "banana";
    char* ps2 = str2;

    printf("최초 문자열: %s\n", str1);
    strcpy(str1, str2);
    printf("바뀐 문자열: %s\n", str1);


    strcpy(str1, ps1);
    printf("바뀐 문자열: %s\n", str1);

    strcpy(str1, ps2);
    printf("바뀐 문자열: %s\n", str1);

    strcpy(str1, "banana");
    printf("바뀐 문자열: %s\n", str1);

    return 0;
}

실행결과
최초 문자열: strawberry
바뀐 문자열: apple
바뀐 문자열: banana
바뀐 문자열: apple
바뀐 문자열: banana

strcpy()를 사용하기 위해서 문자열 배열 두 개를 선언 및 초기화한다. 문자열 포인터변수도 2개 선언 및 초기화한다. strcpy()햠수를 이해하기 쉽도록 초기의 문자열을 출력하고 strcpy(str1, str2)를 사용하고 다시 출력해서 결괏값을 확인한다. 포인터 변수 ps1이 가리키는 것은 문자열 상수이다. 문자열 상수는 첫번째 문자의 주소로 바뀔 수 있으므로 포인터 변수에 대입할 수 있다. 문자열 상수는 문자열이므로 strcpy()의 두번재 인수로 사용할 수 있다.


strncpy함수는 문자의 개수를 지정한 만큼 대입하는 함수이다.


  • <string.h>안에 내장되어 있다.
  • #define _CRT_SECURE_NO_WARNINGS 를 사용해야한다.
  • 함수 형태
  • strncpy(str1, str2, 개수) //첫번째 인수에는 문자열 받을 곳, 두번재 인수에는 대입할 문자열, 세번재 인수에는 지정할 문자 갯수

예시

    #define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

int main(void) {

    char str[20] = "mango tree";

    strncpy(str, "apple-pie", 5);

    printf("%s\n", str);



    return 0;
}

문자열 배열을 선언 및 초기화 한다. strncpy()함수에서 첫번째 인수에는 문자열을 받을 곳을 쓰고, 두번재 인수에는 넣을 문자열을, 세번재 인수에는 지정할 문자의 갯수를 쓴다. 항상 배열 안 문자열의 끝에는 '\0'문자가 붙는다.


실행결과
apple tree

'C > 문자열' 카테고리의 다른 글

[C] 문자열 (puts함수, fputs함수)  (1) 2024.01.15

문자열만을 출력하고 싶을 때 사용하는 함수이다.

 

puts함수는 문자열만을 출력하는 함수이다.

 

  • <stdio.h>안에 내장되어 있다.
  • 함수 원형
      int puts(const char *str) //문자열을 출력하고 줄 바꾼다.
  • 문자열의 시작 위치부터 널 문자가 나올 때까지 모든 문자를 출력한다.
  • 정상 출력됬을 때 0을 반환하고 출력에 실패하면 -1(EOF)를 반환한다.

 

fputs함수는 문자열만을 출력하는 함수이다.

 

  • <stdio.h>안에 내장되어 있다.
  • 함수 원형
       int fputs(const char *str, FILE *stream) //문자열을 출력하고 줄 바꾸지 않는다.
  • 문자열의 시작 위치부터 널 문자가 나올 때까지 모든 문자를 출력한다.
  • 정상 출력됬을 때 0을 반환하고 출력에 실패하면 -1(EOF)를 반환한다.

 

예시

 #include <stdio.h>
     int main(void){

    char str[80] = "apple juice";
    char *ps = "banana";

    puts(str);
    fputs(ps, stdout);
    puts("milk");

    return 0;
    }

 

실행결과
apple juice
bananamilk

 

 

문자열 배열을 선언하고 문자열 상수로 초기화를 한다. 문자열 포인터 변수를 선언하고 문자열 상수를 가리키도록 한다. 이때, 문자열은 주소이기 때문에 문자열 포인터에 대입하여 사용할 수 있다. puts함수로 문자열 배열str을 출력하고 줄 바꾼다. fputs함수로 ps를 표준출력으로 출력하고 줄 바꿈 없이 바로 puts함수로 문자열 상수를 출력한다.

 

'C > 문자열' 카테고리의 다른 글

[C] 문자열 (strcpy함수, strncpy함수)  (0) 2024.01.16

+ Recent posts