본문 바로가기

C# 기본 문법, 변수부터 메서드까지

C# SorryP 2026. 10. 6. 16:39
반응형

C# 프로그램을 쓰는 데 꼭 필요한 기본 문법을 정리합니다. 변수와 자료형, 문자열과 형 변환, 연산자, 조건문, 반복문과 배열, 메서드를 짧은 예제로 하나씩 실행해 봅니다. 마지막에는 배운 문법을 모두 써서 성적 계산기를 만듭니다.

이 글은 C# 작업환경, Visual Studio 2026 설치하기에서 이어집니다. 그 글에서 만든 콘솔 앱 프로젝트의 Program.cs에 이 글의 예제를 입력하면 됩니다.

예제마다 Program.cs의 내용을 모두 지우고 예제 코드로 바꾼 뒤, Ctrl+F5(디버그하지 않고 시작, Start Without Debugging)로 실행합니다. 예제의 값은 모두 코드에 직접 적어 둡니다. 키보드로 값을 입력받는 방법은 콘솔 입출력을 다루는 글에서 봅니다.

실행 결과는 .NET 10 SDK로 직접 빌드하고 실행해서 얻은 출력입니다. Visual Studio에서 Ctrl+F5로 실행하면 콘솔 창 끝에 종료 안내 문구가 더 붙을 수 있습니다. 한글과 →, ←는 코드 페이지 949 콘솔에서도 출력되며, 보이는 모양은 콘솔 글꼴에 따라 조금 다를 수 있습니다.

1. 변수와 자료형

변수와 자료형 정리 그림: 이름표 붙은 상자 세 개(int age 안에 20, string name 안에 '홍길동', bool isStudent 안에 true)로 자료형은 상자 종류, 이름은 이름표, 값은 안의 내용임을 보여 줌. 자료형 6가지 표(int 정수 20, double 실수 175.5, decimal 돈 계산용 12900.50m, bool 참/거짓 true, char 문자 1개 'A', string 문자열 '홍길동')와 int 범위, var는 컴파일러가 자료형을 정하고 const는 바꾸면 빌드 오류 CS0131. 초보가 True로 나온다고 하자 선배가 출력은 True, 코드에는 true라고 답함

변수는 값을 담아 두는 상자입니다. 상자마다 이름표가 붙어 있어서, 이름으로 값을 꺼내 쓰거나 바꿀 수 있습니다.

변수 만드는 법

int age = 20;
  • int: 자료형입니다. 상자에 어떤 종류의 값을 담을지 정합니다. int는 정수입니다.
  • age: 변수 이름입니다.
  • =: 오른쪽 값을 왼쪽 변수에 넣으라는 뜻입니다.
  • 20: 넣을 값입니다. 끝의 ;는 문장이 끝났다는 표시입니다.

자주 쓰는 자료형 6가지

자료형 담는 값 예 메모
int 정수 20 약 −21억 ~ +21억까지 담습니다.
double 실수 175.5 소수점이 있는 계산에 씁니다.
decimal 정밀한 실수 12900.50m 돈 계산에 씁니다. 숫자 끝에 m을 붙입니다.
bool 참/거짓 true true 또는 false입니다.
char 문자 한 개 'A' 작은따옴표로 감쌉니다.
string 문자열 "홍길동" 큰따옴표로 감쌉니다.

예제: 변수 만들고 출력하기

// 변수와 자료형
int age = 20;               // 정수
double height = 175.5;      // 실수(소수점)
decimal price = 12900.50m;  // 돈 계산용 실수 (끝에 m을 붙입니다)
bool isStudent = true;      // 참/거짓
char grade = 'A';           // 문자 한 개 (작은따옴표)
string name = "홍길동";      // 문자열 (큰따옴표)

Console.WriteLine("이름: " + name);
Console.WriteLine("나이: " + age);
Console.WriteLine("키: " + height);
Console.WriteLine("가격: " + price);
Console.WriteLine("학생인가요? " + isStudent);
Console.WriteLine("학점: " + grade);

// 값 바꾸기
age = age + 1;
Console.WriteLine("내년 나이: " + age);

// var: 오른쪽 값을 보고 컴파일러가 자료형을 정합니다
var city = "서울";  // string
var count = 3;      // int
Console.WriteLine(city + ", " + count);

// const: 바꿀 수 없는 값(상수)
const double Pi = 3.14159;
Console.WriteLine("원주율: " + Pi);
// Pi = 3.14;  // 주석을 풀면 컴파일 오류(CS0131)가 납니다

// 자료형이 담을 수 있는 범위
Console.WriteLine("int 최댓값: " + int.MaxValue);
Console.WriteLine("int 최솟값: " + int.MinValue);

실행 결과입니다.

이름: 홍길동
나이: 20
키: 175.5
가격: 12900.50
학생인가요? True
학점: A
내년 나이: 21
서울, 3
원주율: 3.14159
int 최댓값: 2147483647
int 최솟값: -2147483648
  • "이름: " + name처럼 글자와 변수를 +로 이으면 한 줄로 출력됩니다.
  • bool 값은 코드에 소문자 true로 쓰지만, 출력하면 True처럼 첫 글자가 대문자로 나옵니다.
  • decimal로 넣은 12900.50은 끝의 0까지 그대로 출력됩니다.
  • age = age + 1;은 "age에 1을 더한 값을 다시 age에 넣는다"는 뜻입니다. 그래서 다음 줄에서 21이 나옵니다.
  • int.MaxValue와 int.MinValue는 int가 담을 수 있는 가장 큰 값과 가장 작은 값입니다.

var와 const

var는 자료형 자리에 쓰는 말입니다. 컴파일러가 오른쪽 값을 보고 자료형을 정합니다. var city = "서울";은 string, var count = 3;은 int가 됩니다. "자료형이 없는 변수"라는 뜻이 아닙니다.

const를 붙이면 바꿀 수 없는 값(상수)이 됩니다. 예제에서 주석으로 막아 둔 Pi = 3.14;를 실제로 쓰면 빌드가 실패합니다.

const double Pi = 3.14159;
Pi = 3.14;
Program.cs(2,1): error CS0131: The left-hand side of an assignment must be a variable, property or indexer

명령줄에서 빌드해 받은 실제 메시지이고, 앞쪽 폴더 경로만 줄였습니다. =의 왼쪽에는 값을 바꿀 수 있는 변수가 와야 한다는 뜻입니다. 한국어 Visual Studio에서는 메시지가 한국어로 나올 수도 있습니다.

헷갈리기 쉬운 점

  • 변수에 쓰는 등호는 "같다"가 아니라 "넣는다"입니다. =는 대입입니다. 두 값이 같은지 비교할 때는 ==를 씁니다. 연산자에서 다시 봅니다.
  • 문자 한 개는 작은따옴표, 문자열은 큰따옴표입니다. 'A'는 char이고 "홍길동"은 string입니다.
  • 코드와 출력에서 대소문자가 다릅니다. 코드에는 소문자 true/false로 쓰고, 출력은 True/False로 나옵니다.

2. 문자열과 형 변환

문자열과 형 변환 정리 그림: + 이어 붙이기와 $'이름: {name}' 보간이 같은 출력을 내는 모습, \n 줄바꿈과 \t 탭, @'C:\Temp\data.txt' 경로, Length 9·ToUpper·Contains·Substring(0, 5) 결과 표. 형 변환 표: (int)3.99는 3(버림), 7 / 2는 3, 7 / 2.0은 3.5, int.Parse('123') + 1은 124, ToString('N0')은 15,000원, TryParse는 실패하면 false를 돌려주고 계속 진행. Parse('abc')를 쓰면 FormatException으로 프로그램이 멈춘다는 경고

이어 붙이기, 문자열 보간, 이스케이프 문자

// 문자열 다루기
string name = "홍길동";
int score = 95;

// 1) + 로 이어 붙이기
Console.WriteLine("이름: " + name + ", 점수: " + score);

// 2) 문자열 보간: 앞에 $를 붙이고 { } 안에 변수를 씁니다
Console.WriteLine($"이름: {name}, 점수: {score}");
Console.WriteLine($"10점을 더하면 {score + 10}점");

// 3) 이스케이프 문자: \n 줄바꿈, \t 탭, \" 큰따옴표, \\ 역슬래시
Console.WriteLine("첫째 줄\n둘째 줄");
Console.WriteLine("이름\t점수");
Console.WriteLine("그가 말했다: \"안녕\"");
Console.WriteLine("C:\\Temp\\data.txt");

// 4) @를 붙이면 역슬래시를 그대로 씁니다 (파일 경로에 편리)
Console.WriteLine(@"C:\Temp\data.txt");

실행 결과입니다. 여섯째 줄의 이름과 점수 사이 공백은 탭 문자입니다.

이름: 홍길동, 점수: 95
이름: 홍길동, 점수: 95
10점을 더하면 105점
첫째 줄
둘째 줄
이름	점수
그가 말했다: "안녕"
C:\Temp\data.txt
C:\Temp\data.txt
  • 이어 붙이기: +로 글자와 변수를 잇습니다.
  • 문자열 보간: 따옴표 앞에 $를 붙이고 { } 안에 변수나 계산식을 씁니다. {score + 10}처럼 계산 결과도 넣을 수 있습니다. +로 잇는 것보다 읽기 쉬워서, 이 글의 뒤쪽 예제는 주로 보간을 씁니다.
  • 이스케이프 문자: 역슬래시(\)로 시작하는 특별한 글자입니다. \n은 줄바꿈, \t는 탭, \"는 큰따옴표, \\는 역슬래시 한 개입니다.
  • @ 문자열: 따옴표 앞에 @를 붙이면 역슬래시를 그대로 씁니다. 파일 경로를 적을 때 편합니다.

자주 쓰는 문자열 기능

// 5) 자주 쓰는 문자열 기능
string text = "Hello, C#";
Console.WriteLine(text.Length);              // 글자 수
Console.WriteLine(text.ToUpper());           // 대문자로
Console.WriteLine(text.Contains("C#"));      // 포함 여부
Console.WriteLine(text.Replace("C#", "World")); // 바꾸기
Console.WriteLine(text.Substring(0, 5));     // 0번째부터 5글자

// 6) 쉼표로 나누기 (나중에 CSV 파일을 읽을 때 씁니다)
string csv = "사과,배,포도";
string[] fruits = csv.Split(',');
Console.WriteLine(fruits[0]);
Console.WriteLine(fruits[2]);
Console.WriteLine("과일 개수: " + fruits.Length);

실행 결과입니다.

9
HELLO, C#
True
Hello, World
Hello
사과
포도
과일 개수: 3
쓰는 법 하는 일 결과
text.Length 글자 수 9
text.ToUpper() 대문자로 바꾸기 HELLO, C#
text.Contains("C#") 들어 있는지 확인 True
text.Replace("C#", "World") 글자 바꾸기 Hello, World
text.Substring(0, 5) 0번째부터 5글자 꺼내기 Hello
csv.Split(',') 쉼표를 기준으로 나누기 문자열 배열
  • "Hello, C#"은 쉼표와 공백까지 한 글자로 세서 9글자입니다.
  • Substring(0, 5)처럼 글자 위치는 0부터 셉니다.
  • Split은 나눈 조각을 배열로 돌려줍니다. 배열은 반복문과 배열에서 자세히 봅니다. 나중에 CSV 파일을 읽을 때도 다시 씁니다.

형 변환: 자료형 바꾸기

// 형 변환: 자료형 바꾸기
// 1) 작은 그릇 → 큰 그릇은 자동 (암시적 변환)
int a = 10;
double b = a;
Console.WriteLine(b);

// 2) 큰 그릇 → 작은 그릇은 (int)처럼 직접 써야 합니다 (명시적 변환)
double c = 3.99;
int d = (int)c;       // 소수점 아래는 버려집니다 (반올림 아님)
Console.WriteLine(d);

// 3) 문자열 → 숫자
string text = "123";
int number = int.Parse(text);
Console.WriteLine(number + 1);

double rate = double.Parse("0.5");
Console.WriteLine(rate * 10);

// 4) 숫자 → 문자열
int price = 15000;
string priceText = price.ToString();
Console.WriteLine(priceText + "원");
Console.WriteLine(price.ToString("N0") + "원"); // 천 단위 쉼표

실행 결과입니다.

10
3
124
5
15000원
15,000원
  • 암시적 변환: int를 double에 넣는 것처럼 작은 그릇에서 큰 그릇으로 옮길 때는 자동으로 바뀝니다.
  • 명시적 변환: double을 int로 옮길 때는 (int)처럼 직접 써야 합니다. 소수점 아래는 버려집니다. 그래서 3.99가 3이 됩니다.
  • 문자열 → 숫자: int.Parse, double.Parse를 씁니다. "123"을 숫자 123으로 바꾼 다음 1을 더해서 124가 나왔습니다.
  • 숫자 → 문자열: ToString()을 씁니다. ToString("N0")은 천 단위 쉼표를 넣습니다. 이 결과는 한국어 문화권(ko-KR) 설정으로 실행한 출력입니다.

변환에 실패하면: Parse와 TryParse

숫자가 아닌 글자를 int.Parse로 바꾸면 어떻게 될까요? 일부러 실패하는 코드를 실행해 봅니다.

// 숫자가 아닌 문자열을 int.Parse로 바꾸면 프로그램이 멈춥니다
Console.WriteLine("변환을 시작합니다.");
int number = int.Parse("abc");
Console.WriteLine("이 줄은 실행되지 않습니다: " + number);

실행 결과입니다.

변환을 시작합니다.
Unhandled exception. System.FormatException: The input string 'abc' was not in a correct format.
   at System.Number.ThrowFormatException[TChar](ReadOnlySpan`1 value)
   at System.Int32.Parse(String s)
   at Program.<Main>$(String[] args) in C:\Users\(사용자)\source\repos\ParseCrash\ParseCrash\Program.cs:line 3
  • 첫 줄만 출력되고 프로그램이 멈췄습니다. 마지막 Console.WriteLine은 실행되지 않았습니다. 이렇게 실행 중에 문제가 생겨 프로그램이 멈추는 것을 예외라고 합니다.
  • FormatException은 글자의 형식이 숫자로 바꿀 수 있는 모양이 아니라는 뜻입니다. 마지막 줄의 line 3은 3번째 줄에서 멈췄다는 뜻입니다.
  • 마지막 줄의 in 뒤에는 Program.cs 파일의 전체 경로가 나옵니다. 위 경로는 ParseCrash라는 프로젝트를 기본 위치에 만든 경우의 예이고, 사용자 이름과 프로젝트를 만든 위치에 따라 달라집니다.
  • 메시지는 .NET 런타임이 출력한 것으로, 한국어 Windows(ko-KR)에서도 영어로 나왔습니다(예: The input string 'abc' was not in a correct format.). 빌드 오류(CS0103 등)는 같은 PC에서 한국어로 나왔습니다.
  • F5로 디버그 실행을 하면 Visual Studio가 문제가 생긴 줄에서 멈추고 예외 내용을 보여 줍니다. 이 화면은 Visual Studio 사용법을 다루는 글에서 봅니다.

바꿀 수 없는 글자가 들어올 수 있다면 TryParse를 씁니다.

// 5) 변환이 실패할 수도 있을 때는 TryParse
// int.Parse("abc")는 프로그램이 멈춥니다(예외). TryParse는 성공 여부를 bool로 알려 줍니다.
if (int.TryParse("abc", out int result))
{
    Console.WriteLine("변환 성공: " + result);
}
else
{
    Console.WriteLine("숫자가 아니라서 변환하지 못했습니다.");
}

if (int.TryParse("42", out int result2))
{
    Console.WriteLine("변환 성공: " + result2);
}

실행 결과입니다.

숫자가 아니라서 변환하지 못했습니다.
변환 성공: 42
  • int.TryParse는 바꾸기에 성공하면 true, 실패하면 false를 돌려줍니다. 프로그램은 멈추지 않습니다.
  • 바꾼 숫자는 out int result에 적은 변수 result에 들어갑니다.
  • 그래서 if와 함께 씁니다. if는 조건문에서 자세히 봅니다. 예외가 났을 때 try-catch로 처리하는 방법은 다음 글에서 다룹니다.

헷갈리기 쉬운 점

  • 3.99를 int로 바꾸면 4가 아니라 3입니다. (int)3.99는 반올림이 아니라 소수점 아래를 버립니다.
  • 따옴표로 감싼 숫자는 문자열입니다. "123"은 숫자가 아니라 문자열입니다. 숫자로 계산하려면 int.Parse나 int.TryParse로 바꿉니다.
  • Parse는 실패하면 프로그램이 멈추고, TryParse는 성공했는지를 알려 줍니다. TryParse는 결과를 true/false로 돌려줍니다.

3. 연산자

연산자 정리 그림: x = 17, y = 5일 때 x + y = 22, x - y = 12, x * y = 85, x / y = 3, x % y = 2. 공 17개를 5개씩 묶으면 3묶음에 2개가 남는 그림으로 /는 몫, %는 나머지. total = 100에서 += 50, -= 30, *= 2로 150, 120, 240이 되는 흐름. age = 25일 때 비교·논리 연산 결과(True/False) 표와 조건 연산자로 17은 홀수. 모자 친구가 x = y가 같다는 뜻이냐고 묻고 선배가 =는 값 넣기, 같은지는 ==라고 답함

산술 연산자

// 연산자
int x = 17;
int y = 5;

// 산술 연산자
Console.WriteLine($"{x} + {y} = {x + y}");
Console.WriteLine($"{x} - {y} = {x - y}");
Console.WriteLine($"{x} * {y} = {x * y}");
Console.WriteLine($"{x} / {y} = {x / y}");   // 정수 나눗셈: 몫
Console.WriteLine($"{x} % {y} = {x % y}");   // 나머지

실행 결과입니다.

17 + 5 = 22
17 - 5 = 12
17 * 5 = 85
17 / 5 = 3
17 % 5 = 2
  • +, -, *는 덧셈, 뺄셈, 곱셈입니다.
  • /는 나눗셈입니다. 정수끼리 나누면 몫만 남습니다. 17을 5로 나누면 몫은 3입니다.
  • %는 나머지입니다. 17을 5로 나눈 나머지는 2입니다. n % 2 == 0처럼 짝수와 홀수를 가릴 때 자주 씁니다.

복합 대입과 증가·감소 연산자

// 복합 대입 연산자
int total = 100;
total += 50;   // total = total + 50
Console.WriteLine("+= 50 → " + total);
total -= 30;
Console.WriteLine("-= 30 → " + total);
total *= 2;
Console.WriteLine("*= 2 → " + total);

// 증가·감소 연산자
int count = 0;
count++;
count++;
count--;
Console.WriteLine("count = " + count);

실행 결과입니다.

+= 50 → 150
-= 30 → 120
*= 2 → 240
count = 1
  • total += 50은 total = total + 50을 줄여 쓴 것입니다. -=, *=도 같은 방식입니다.
  • count++는 1 늘리고, count--는 1 줄입니다. 0에서 두 번 늘리고 한 번 줄여서 1이 됐습니다.

비교·논리·조건 연산자

// 연산자
int x = 17;
int y = 5;

// 비교 연산자 (결과는 bool)
Console.WriteLine($"x > y : {x > y}");
Console.WriteLine($"x == y : {x == y}");
Console.WriteLine($"x != y : {x != y}");

// 논리 연산자
int age = 25;
bool hasTicket = true;
Console.WriteLine($"성인이고 표가 있다: {age >= 19 && hasTicket}");
Console.WriteLine($"10살 미만이거나 65살 이상: {age < 10 || age >= 65}");
Console.WriteLine($"표가 없다: {!hasTicket}");

// 조건 연산자 (삼항 연산자): 조건 ? 참일 때 값 : 거짓일 때 값
string result = x % 2 == 0 ? "짝수" : "홀수";
Console.WriteLine($"{x}은(는) {result}입니다.");

실행 결과입니다.

x > y : True
x == y : False
x != y : True
성인이고 표가 있다: True
10살 미만이거나 65살 이상: False
표가 없다: False
17은(는) 홀수입니다.
  • 비교 연산자: 결과가 bool(True 또는 False)입니다. ==는 같다, !=는 다르다는 뜻입니다.
  • 논리 연산자: &&는 "그리고"입니다. 양쪽이 모두 참이어야 참입니다. ||는 "또는"입니다. 한쪽만 참이어도 참입니다. !는 "아니다"입니다. 참과 거짓을 뒤집습니다.
  • 조건 연산자: 조건 ? 참일 때 값 : 거짓일 때 값 모양입니다. if-else를 한 줄로 쓴 것입니다. 17은 2로 나눈 나머지가 0이 아니므로 "홀수"가 됐습니다.

헷갈리기 쉬운 점

대입과 비교는 다른 기호입니다. =는 오른쪽 값을 왼쪽 변수에 넣는 대입입니다. ==는 두 값이 같은지 묻는 비교입니다. 초보 때 가장 자주 헷갈리는 부분입니다.

정수끼리 나누면 결과도 정수입니다. 소수점까지 얻으려면 둘 중 하나를 실수로 만듭니다.

// 6) 정수끼리 나누면 정수, 하나라도 실수면 실수
Console.WriteLine(7 / 2);
Console.WriteLine(7 / 2.0);
Console.WriteLine((double)7 / 2);

실행 결과입니다.

3
3.5
3.5
  • 7 / 2는 3.5가 아니라 3입니다.
  • 7 / 2.0처럼 한쪽을 실수로 쓰거나, (double)7 / 2처럼 한쪽을 double로 바꾸면 3.5가 나옵니다.
  • 이 방법은 배열의 평균을 구할 때 다시 씁니다.

4. 조건문 if·switch

조건문 순서도: score = 83일 때 score &gt;= 90은 거짓, score &gt;= 80이 참이라 B 학점을 출력하고 아래 조건은 검사하지 않음. switch 그림: month = 4가 case 3·4·5 묶음으로 들어가 봄을 출력하고 break로 끝나며, 다른 묶음은 겨울·여름·가을, 맞는 case가 없으면 default의 잘못된 월입니다

조건문은 조건에 따라 실행할 코드를 고릅니다.

if, else if, else

// 조건문: if와 switch
int score = 83;

// if / else if / else
if (score >= 90)
{
    Console.WriteLine("A 학점");
}
else if (score >= 80)
{
    Console.WriteLine("B 학점");
}
else if (score >= 70)
{
    Console.WriteLine("C 학점");
}
else
{
    Console.WriteLine("재수강");
}

// 조건 두 개를 함께 검사하기
int age = 15;
if (age >= 13 && age <= 18)
{
    Console.WriteLine("청소년 요금입니다.");
}

실행 결과입니다.

B 학점
청소년 요금입니다.
  • if (조건)의 조건이 참이면 바로 아래 중괄호 { } 안을 실행합니다.
  • else if는 앞의 조건이 거짓일 때 이어서 검사합니다. else는 위의 조건이 모두 거짓일 때 실행합니다.
  • 위에서부터 차례로 검사하고, 처음 참이 된 곳 하나만 실행합니다. 83점은 score >= 90이 거짓이고 score >= 80이 참이라서 "B 학점"을 출력하고 끝납니다.
  • &&로 조건 두 개를 함께 검사할 수 있습니다. 15는 13 이상이고 18 이하라서 "청소년 요금입니다."가 나왔습니다.

switch문

// switch: 값 하나를 여러 경우와 비교할 때
int month = 4;
switch (month)
{
    case 12:
    case 1:
    case 2:
        Console.WriteLine("겨울");
        break;
    case 3:
    case 4:
    case 5:
        Console.WriteLine("봄");
        break;
    case 6:
    case 7:
    case 8:
        Console.WriteLine("여름");
        break;
    case 9:
    case 10:
    case 11:
        Console.WriteLine("가을");
        break;
    default:
        Console.WriteLine("잘못된 월입니다.");
        break;
}

// 문자열도 switch에 쓸 수 있습니다
string menu = "커피";
switch (menu)
{
    case "커피":
        Console.WriteLine("3,000원");
        break;
    case "주스":
        Console.WriteLine("4,000원");
        break;
    default:
        Console.WriteLine("없는 메뉴");
        break;
}

실행 결과입니다.

봄
3,000원
  • switch는 값 하나를 여러 경우와 비교할 때 씁니다. 값과 같은 case로 가서 코드를 실행합니다.
  • 각 case는 break로 끝냅니다.
  • case를 여러 개 붙여 쓰면 같은 처리를 함께 씁니다. 12, 1, 2는 모두 "겨울"입니다.
  • default는 어느 case에도 맞지 않을 때 실행합니다.
  • 숫자뿐 아니라 문자열도 switch에 쓸 수 있습니다.

헷갈리기 쉬운 점

  • if는 조건의 순서가 중요합니다. 처음 참인 곳 하나만 실행하기 때문입니다. 예제에서 score >= 70을 맨 위로 올리면 83점도 첫 조건에서 걸려 "C 학점"이 됩니다.
  • 같은지 검사할 때는 등호 두 개입니다. 조건에는 =가 아니라 비교 연산자 ==를 씁니다.
  • switch 식은 다른 문법입니다. 인터넷에서 x switch { ... } 모양의 코드를 볼 수도 있습니다. switch 식이라는 문법이고, 이 글에서는 다루지 않습니다.

5. 반복문과 배열

반복문과 배열 정리 그림: for (int i = 1; i &lt;= 5; i++)의 시작·조건·증감 세 칸과 실행 순서(출력 1 2 3 4 5). for, while, do-while, break, continue 다섯 가지의 쓰임과 실행 결과 예. int[] scores = { 90, 75, 88, 62, 95 } 상자 5칸에 번호 0~4, scores.Length는 5, scores[5]는 IndexOutOfRangeException 오류. 로봇이 while (true)에 break가 없으면 끝나지 않으니 Ctrl+C로 멈추라고 알려 줌

반복문은 같은 코드를 여러 번 실행합니다. 배열은 같은 자료형의 값 여러 개를 한 변수에 담습니다. 둘은 함께 쓰는 일이 많습니다.

for문

// for: 횟수가 정해져 있을 때
for (int i = 1; i <= 5; i++)
{
    Console.Write(i + " ");
}
Console.WriteLine();

// 1부터 100까지 더하기
int sum = 0;
for (int i = 1; i <= 100; i++)
{
    sum += i;
}
Console.WriteLine("1~100 합계: " + sum);

실행 결과입니다. 첫 줄 끝에는 공백이 하나 있습니다.

1 2 3 4 5 
1~100 합계: 5050

for의 괄호 안은 세 칸으로 나뉩니다.

  1. 시작 int i = 1: 처음에 한 번 실행합니다.
  2. 조건 i <= 5: 참인 동안 중괄호 안을 반복합니다.
  3. 증감 i++: 중괄호 안을 한 번 실행할 때마다 끝에 실행합니다.
  • 그래서 i가 1, 2, 3, 4, 5일 때 실행하고, 6이 되면 조건이 거짓이라 끝납니다.
  • Console.Write는 출력한 뒤 줄을 바꾸지 않습니다. 괄호 안이 빈 Console.WriteLine()은 줄만 바꿉니다.
  • 두 번째 for는 1부터 100까지 sum에 차례로 더합니다.

while과 do-while

// while: 조건이 참인 동안 반복
int money = 10000;
int days = 0;
while (money >= 3000)
{
    money -= 3000;  // 하루에 3,000원씩 사용
    days++;
}
Console.WriteLine($"{days}일 동안 쓸 수 있습니다. (남은 돈: {money}원)");

// do-while: 일단 한 번 실행하고 조건을 검사
int n = 10;
do
{
    Console.WriteLine("do-while 실행: n = " + n);
    n++;
} while (n < 10);

실행 결과입니다.

3일 동안 쓸 수 있습니다. (남은 돈: 1000원)
do-while 실행: n = 10
  • while은 조건이 참인 동안 반복합니다. 10,000원에서 3,000원씩 3번 쓰면 1,000원이 남아 조건 money >= 3000이 거짓이 됩니다.
  • do-while은 일단 한 번 실행하고 나서 조건을 검사합니다. n이 10이라서 조건 n < 10은 처음부터 거짓이지만, 한 번은 출력됐습니다.

break와 continue

// break: 반복문을 바로 빠져나가기
for (int i = 1; i <= 10; i++)
{
    if (i == 4)
    {
        break;
    }
    Console.Write(i + " ");
}
Console.WriteLine("← break");

// continue: 이번 반복만 건너뛰기 (짝수만 출력)
for (int i = 1; i <= 10; i++)
{
    if (i % 2 == 1)
    {
        continue;
    }
    Console.Write(i + " ");
}
Console.WriteLine("← continue");

실행 결과입니다.

1 2 3 ← break
2 4 6 8 10 ← continue
  • break는 반복문을 바로 빠져나갑니다. i가 4가 되자 멈춰서 1, 2, 3만 출력됐습니다.
  • continue는 이번 반복만 건너뛰고 다음 반복으로 갑니다. 홀수일 때 건너뛰어서 짝수만 출력됐습니다.

중첩 반복문

// 중첩 반복문: 구구단 2단~3단
for (int dan = 2; dan <= 3; dan++)
{
    Console.WriteLine($"[{dan}단]");
    for (int i = 1; i <= 9; i++)
    {
        Console.WriteLine($"{dan} x {i} = {dan * i}");
    }
}

실행 결과입니다.

[2단]
2 x 1 = 2
2 x 2 = 4
2 x 3 = 6
2 x 4 = 8
2 x 5 = 10
2 x 6 = 12
2 x 7 = 14
2 x 8 = 16
2 x 9 = 18
[3단]
3 x 1 = 3
3 x 2 = 6
3 x 3 = 9
3 x 4 = 12
3 x 5 = 15
3 x 6 = 18
3 x 7 = 21
3 x 8 = 24
3 x 9 = 27

반복문 안에 반복문을 넣을 수 있습니다. 바깥 for가 한 번 돌 때마다 안쪽 for가 1부터 9까지 모두 돕니다.

배열 만들고 꺼내 쓰기

// 배열: 같은 자료형 여러 개를 한 번에 담기
int[] scores = { 90, 75, 88, 62, 95 };

Console.WriteLine("첫 번째 점수: " + scores[0]);   // 번호(인덱스)는 0부터
Console.WriteLine("마지막 점수: " + scores[4]);
Console.WriteLine("점수 개수: " + scores.Length);

// 값 바꾸기
scores[3] = 70;

// for로 모두 출력
for (int i = 0; i < scores.Length; i++)
{
    Console.WriteLine($"scores[{i}] = {scores[i]}");
}

// foreach: 처음부터 끝까지 하나씩 꺼내기
int sum = 0;
foreach (int s in scores)
{
    sum += s;
}
double average = (double)sum / scores.Length;
Console.WriteLine($"합계: {sum}, 평균: {average}");

// 최댓값 찾기
int max = scores[0];
foreach (int s in scores)
{
    if (s > max)
    {
        max = s;
    }
}
Console.WriteLine("최고 점수: " + max);

// 범위를 벗어난 번호를 쓰면 실행 중 오류가 납니다
// Console.WriteLine(scores[5]);  // IndexOutOfRangeException

실행 결과입니다.

첫 번째 점수: 90
마지막 점수: 95
점수 개수: 5
scores[0] = 90
scores[1] = 75
scores[2] = 88
scores[3] = 70
scores[4] = 95
합계: 418, 평균: 83.6
최고 점수: 95
  • int[] scores = { ... };는 정수 5개를 담은 배열입니다.
  • 배열의 각 칸에는 번호(인덱스)가 있습니다. 번호는 0부터 시작합니다. 5칸짜리 배열의 번호는 0~4입니다.
  • scores.Length는 칸의 개수입니다.
  • scores[3] = 70;처럼 번호를 지정해 값을 바꿉니다. 그래서 62가 70으로 바뀌었습니다.
  • for로 번호를 0부터 scores.Length보다 작을 때까지 돌리면 모든 칸을 볼 수 있습니다.
  • foreach는 처음부터 끝까지 값을 하나씩 꺼냅니다. 번호를 쓰지 않아도 됩니다.
  • 평균은 (double)sum / scores.Length로 구했습니다. 정수 나눗셈이 되지 않도록 double로 바꾼 것입니다.
  • 최댓값은 첫 값을 max에 넣어 두고, 더 큰 값을 만날 때마다 바꿔서 찾았습니다.

크기만 정해 만들기와 정렬

// 크기만 정해서 만들기
string[] names = new string[3];
names[0] = "철수";
names[1] = "영희";
names[2] = "민수";
Console.WriteLine(string.Join(", ", names));

// 정렬
int[] scores = { 90, 75, 88, 62, 95 };
Array.Sort(scores);
Console.WriteLine("정렬 후: " + string.Join(", ", scores));

실행 결과입니다.

철수, 영희, 민수
정렬 후: 62, 75, 88, 90, 95
  • new string[3]은 3칸짜리 배열을 만듭니다. 값은 번호를 지정해 하나씩 넣습니다.
  • string.Join(", ", 배열)은 배열의 값을 , 로 이어서 한 줄 문자열로 만듭니다.
  • Array.Sort는 배열을 작은 값부터 차례로 정렬합니다.
  • 배열은 만들 때 크기가 정해지고 바뀌지 않습니다. 개수가 늘어나는 목록은 다음 글의 List로 다룹니다.

헷갈리기 쉬운 점

  • 배열 번호는 0부터입니다. 5칸짜리 배열의 마지막은 scores[4]입니다. 없는 번호인 scores[5]를 쓰면 실행 중에 IndexOutOfRangeException 예외가 나고 프로그램이 멈춥니다. 메시지는 "Index was outside the bounds of the array."입니다.
  • 그래서 for의 조건에는 "작다"를 씁니다. i < scores.Length처럼 씁니다. <=로 쓰면 마지막에 scores[5]를 읽게 됩니다.
  • i++는 i를 1 늘립니다. for에서는 중괄호 안을 한 번 실행한 다음에 실행됩니다.
  • 조건이 계속 참이면 반복이 끝나지 않습니다. while (true)처럼 쓰고 빠져나갈 break가 없으면 끝나지 않습니다. 이때는 콘솔 창에서 Ctrl+C를 눌러 멈춥니다.
  • do-while은 조건과 상관없이 최소 한 번 실행됩니다.

6. 메서드와 종합 예제(성적 계산기)

메서드 정리 그림: int Add(int a, int b)에서 int는 돌려줄 값의 자료형, Add는 이름, (int a, int b)는 매개변수, return은 값을 돌려줌, Add(3, 5)는 8. void PrintLine, bool IsEven, 기본값 매개변수가 있는 Greet 예. 성적 계산기 실행 결과(철수 92점 A, 영희 78점 C, 민수 85점 B, 지은 64점 D, 평균 79.8점, 1등 철수)와 쓰인 문법. 초보가 메서드를 부르는 곳보다 아래에 적어도 되냐고 묻고 로봇이 최상위 문에서는 괜찮고 오버로드는 다음 글에서 다룬다고 답함

메서드는 자주 쓰는 코드를 묶어서 이름을 붙인 것입니다. 이름을 부르면(호출하면) 묶어 둔 코드가 실행됩니다.

메서드 만들고 부르기

// 메서드: 자주 쓰는 코드를 이름 붙여 묶기
PrintLine();
Console.WriteLine("3 + 5 = " + Add(3, 5));
Console.WriteLine("10 + 20 = " + Add(10, 20));
PrintLine();

Console.WriteLine("7은 짝수? " + IsEven(7));
Console.WriteLine("8은 짝수? " + IsEven(8));

// ── 아래는 메서드 정의입니다 ──
// 최상위 문 프로그램에서는 실행할 코드 아래에 메서드를 적어도 됩니다.

// 반환값이 없는 메서드: void
void PrintLine()
{
    Console.WriteLine("--------------------");
}

// 매개변수 두 개를 받아 int를 돌려주는 메서드
int Add(int a, int b)
{
    return a + b;
}

// bool을 돌려주는 메서드
bool IsEven(int number)
{
    return number % 2 == 0;
}

실행 결과입니다.

--------------------
3 + 5 = 8
10 + 20 = 30
--------------------
7은 짝수? False
8은 짝수? True

메서드는 반환 형식 이름(매개변수) { ... } 모양으로 만듭니다.

  • int Add(int a, int b): int 두 개를 받아서 int를 돌려주는 메서드입니다. 받는 값 a, b를 매개변수라고 합니다.
  • return: 값을 돌려주고 메서드를 끝냅니다. Add(3, 5)를 부르면 8이 돌아옵니다.
  • void PrintLine(): void는 돌려주는 값이 없다는 뜻입니다. 줄만 출력합니다.
  • bool IsEven(int number): bool을 돌려줍니다. 짝수인지 검사하는 식 number % 2 == 0의 결과를 그대로 돌려줍니다.
  • 최상위 문 프로그램에서는 메서드를 실행 코드 아래에 적어도, 위에서 부를 수 있습니다.

배열 매개변수와 기본값 매개변수

// 배열을 받는 메서드, 기본값이 있는 매개변수
int[] scores = { 80, 90, 100 };
Console.WriteLine("평균: " + Average(scores));

Greet("홍길동");
Greet("김철수", 3);

// 배열을 받는 메서드
double Average(int[] values)
{
    int sum = 0;
    foreach (int v in values)
    {
        sum += v;
    }
    return (double)sum / values.Length;
}

// 기본값이 있는 매개변수: 생략하면 1이 들어갑니다
void Greet(string name, int times = 1)
{
    for (int i = 0; i < times; i++)
    {
        Console.WriteLine($"안녕하세요, {name}님!");
    }
}

실행 결과입니다.

평균: 90
안녕하세요, 홍길동님!
안녕하세요, 김철수님!
안녕하세요, 김철수님!
안녕하세요, 김철수님!
  • Average(int[] values)처럼 배열도 매개변수로 받을 수 있습니다.
  • int times = 1처럼 매개변수에 기본값을 주면, 부를 때 생략할 수 있습니다. Greet("홍길동")은 1번, Greet("김철수", 3)은 3번 인사합니다.

헷갈리기 쉬운 점: 돌려주는 것과 출력하는 것

메서드가 값을 돌려주는 것과 화면에 출력하는 것은 다릅니다. 아래 코드는 Add를 두 번 부릅니다.

// 돌려받은 값은 출력해야 화면에 보입니다
Add(3, 5);                     // 계산만 하고 결과를 버립니다
Console.WriteLine(Add(3, 5));  // 돌려받은 값을 출력합니다

int Add(int a, int b)
{
    return a + b;
}

실행 결과입니다.

8
  • 첫 번째 Add(3, 5);도 8을 계산해서 돌려줍니다. 하지만 받아서 쓰는 곳이 없어서 화면에는 아무것도 나오지 않습니다.
  • 화면에 출력하는 일은 Console.WriteLine이 합니다. 그래서 8은 한 번만 출력됐습니다.
  • 반대로 PrintLine은 메서드 안에서 직접 출력하고, 돌려주는 값이 없으니 void입니다.

하나 더 있습니다. 최상위 문 프로그램에 쓴 메서드는 공식 문서상 로컬 함수입니다. 그래서 public 같은 접근 제한자를 붙이지 않고, 같은 이름의 메서드를 여러 개(오버로드) 만들 수도 없습니다. 클래스 안의 메서드는 다음 글에서 다룹니다.

종합 예제: 성적 계산기

지금까지 배운 배열, 반복문, 조건문, 메서드를 모두 써서 성적표를 만듭니다.

// 종합 예제: 성적 계산기
// 배열, 반복문, 조건문, 메서드를 모두 사용합니다.
string[] names = { "철수", "영희", "민수", "지은" };
int[] scores = { 92, 78, 85, 64 };

Console.WriteLine("=== 성적표 ===");
for (int i = 0; i < names.Length; i++)
{
    string grade = GetGrade(scores[i]);
    Console.WriteLine($"{names[i]}\t{scores[i]}점\t{grade}");
}

int total = 0;
int best = 0;
for (int i = 0; i < scores.Length; i++)
{
    total += scores[i];
    if (scores[i] > scores[best])
    {
        best = i;
    }
}
double average = (double)total / scores.Length;

Console.WriteLine("==============");
Console.WriteLine($"평균: {average:F1}점");
Console.WriteLine($"1등: {names[best]} ({scores[best]}점)");

// 점수를 학점으로 바꾸는 메서드
string GetGrade(int score)
{
    switch (score / 10)
    {
        case 10:
        case 9:
            return "A";
        case 8:
            return "B";
        case 7:
            return "C";
        case 6:
            return "D";
        default:
            return "F";
    }
}

실행 결과입니다. 이름, 점수, 학점 사이는 탭 문자입니다.

=== 성적표 ===
철수	92점	A
영희	78점	C
민수	85점	B
지은	64점	D
==============
평균: 79.8점
1등: 철수 (92점)
  • 두 배열을 같은 번호로 짝짓습니다. names[0]의 "철수"와 scores[0]의 92가 한 사람의 정보입니다.
  • GetGrade 메서드는 score / 10으로 십의 자리를 구합니다. 정수 나눗셈이라 92는 9, 78은 7이 됩니다. 그 값으로 switch에서 학점을 고릅니다. return이 메서드를 끝내기 때문에 case마다 break를 따로 쓰지 않았습니다.
  • best에는 점수가 가장 높은 사람의 번호를 담습니다. 더 높은 점수를 만나면 번호를 바꿉니다.
  • F1 서식은 소수 첫째 자리까지 출력합니다. {average:F1}처럼 씁니다. 평균 79.75가 79.8로 반올림돼 나왔습니다.
  • 두 배열을 번호로 짝짓는 방식은 한쪽만 고치는 실수를 하기 쉽습니다. 다음 글에서 이 프로그램을 클래스와 List, LINQ로 다시 만듭니다.

마치며

이번 글에서는 C# 기본 문법을 변수부터 메서드까지 정리했습니다.

  • 변수는 이름표 붙은 상자이고, 자료형으로 담을 값의 종류를 정합니다. =는 값을 넣는 대입입니다.
  • 문자열은 보간($"...")으로 쉽게 만들고, Parse와 TryParse로 숫자로 바꿉니다. Parse가 실패하면 프로그램이 멈춥니다.
  • 정수끼리 나누면 몫만 남습니다. %는 나머지, ==는 비교입니다.
  • if는 처음 참인 곳 하나만 실행하고, switch는 값 하나를 여러 경우와 비교합니다.
  • 반복문은 for, while, do-while이 있고, 배열 번호는 0부터 시작합니다.
  • 메서드는 코드를 묶어 이름을 붙인 것입니다. 값을 돌려주는 것과 출력하는 것은 다릅니다.

다음 글 C# 고급 문법, 클래스부터 LINQ까지에서는 C# 고급 문법을 클래스부터 LINQ까지 정리합니다. 클래스와 상속, List와 Dictionary, 예외 처리, 람다와 LINQ를 배우고, 오늘 만든 성적 계산기를 클래스로 다시 만듭니다.

참고 자료

반응형