C#에서는 Console 클래스를 사용하여 입력받고 출력을 할 수 있다
⚔ 입력과 출력
Console.WriteLine("숫자를 입력해주세요.");
int num = int.Parse(Console.ReadLine());
Console.WriteLine($"{num}를 입력하셨습니다.");
Console.ReadLine()을 사용하면 string으로 받기 때문에 int로 형변환을 해야 한다.
string에서 int로 형변환을 하기 위해서는 int.Parse 또는 Convert.ToInt32 메소드를 사용할 수 있다.
Parse() 함수는 문자열에서 다른 자료형으로 형변환을 하는 것이고, Convert 클래스는 문자열이 아닌 다른 자료형에서도 형변환 시 사용 가능하다.
C#에서 반복문은 for, while, do-while 문이 있다.
⚔ for문
// 반복 횟수가 정해져 있을 때 주로 사용
for(int i=0; i<10; i++)
{
Console.WriteLine(i);
}
⚔ while문
// 조건이 참이면 반복
int i=0;
while(i < 10)
{
Console.WriteLine(i++);
}
⚔ do-while문
// 코드 블록이 최소 한 번이상 실행
int i=0;
do
{
Console.WriteLine(i++);
}while(i < 10);
조건문은 if, else if, else 문이 있다.
⚔ if문
// 조건이 참인 경우 실행
int num = 2;
if(num > 0)
{
Console.WriteLine("양수 입니다.");
}
⚔ else if문
// 이전 조건이 거짓이고 다음 조건이 참인 경우 실행
int num = -2;
if(num > 0)
{
Console.WriteLine("양수 입니다.");
}
else if(num < 0)
{
Console.WriteLine("음수 입니다.");
}
⚔ else 문
// 모든 조건이 거짓인 경우 실행
int num=0;
if(num > 0)
{
Console.WriteLine("양수 입니다.");
}
else if(num < 0)
{
Console.WriteLine("음수 입니다.");
}
else
{
Console.WriteLine("0입니다.");
}
같은 자료형을 가진 데이터를 여러 개 저장할 수 있는 자료구조.
⚔ 배열 선언 & 초기화
int[] nums = new int[5]; // 크기가 5인 정수 배열 선언.
nums[0] = 10; // 첫 번째 요소에 10 저장
nums[1] = 20; // 두 번째 요소에 20 저장
// 배열 선언과 동시에 초기화
int[] nums2 = {10, 20, 30, 40};
⚔ 배열 접근 & 순회
int[] nums = {10, 20, 30, 40};
// 배열의 모든 요소에 접근하는 방법
for(int i=0; i<nums.Length; i++)
{
Console.WriteLine(nums[i]);
}
클래스는 객체를 정의하는 데 사용되는 청사진으로 속성과 메소드를 포함한다.
⚔ 클래스 정의와 사용
// 클래스 정의
class Person
{
public string name; // 속성
public int age;
public void Introduce() // 메소드
{
Console.WriteLine($"안녕하세요 제 이름은 {name}이고 나이는 {age}에요.");
}
}
// 클래스 사용 예제
Person person = new Person();
person.name = "Jin";
person.age = 30;
person.Introduce();
상속은 자식 클래스가 부모 클래스의 속성과 메소드를 물려받는 것입니다. C#에서는 다중 상속을 지원하지 않습니다.
다이아몬드 문제와 같은 모호성 때문이다.
예를 들어 서로 다른 부모 클래스에 같은 이름의 메소드가 있으면 자식 클래스에서 메소드를 호출할 때 어떤 부모의 메소드를 호출하는지 모호해지기 때문이다.
⚔ 상속
class Animal
{
public void Eat()
{
Console.WriteLine("먹는다.");
}
}
// Animal 클래스를 상속
class Dog: Animal
{
public void Bark()
{
Console.WriteLine("멍멍");
}
}
Dog dog = new Dog();
dog.Eat(); // Animal에서 상속받은 메소드 사용
dog.Bark();
인터페이스는 클래스나 구조체가 구현해야 하는 메소드와 속성의 정의를 포함한다. C#에서 인터페이스는 다중 상속이 가능하다. (클래스가 객체의 청사진이면 인터페이스는 클래스의 청사진)
인터페이스는 선언만 존재하고 구현이 없기 때문에 여러 개의 인터페이스를 가져도 충돌이 발생하지 않기 때문이다.
⚔ 인터페이스
// interface의 이름을 정의할 때 대문자 'I'를 앞에 관습적으로 붙임
interface IAnimal
{
void MakeSound();
}
// 인터페이스에 선언된 메소드는 반드시 구현해야 함
class Dog: IAnimal
{
public void MakeSound()
{
Console.WriteLine("멍멍");
}
}
Dog dog = new Dog();
dog.MakeSound();
추상 클래스는 객체를 생성할 수 없고, 상속을 통해서만 사용 가능하며 추상 메소드를 포함할 수 있다. 그리고 일반 메소드의 구현을 가질 수 있다. (다중 상속은 지원하지 않는다.)
⚔ 추상 클래스
abstract class Animal
{
// 추상 메소드: abstract 키워드를 사용하며 구현은 할 수 없다. -- 파생 클래스는 추상 메소드를 구현해야 함
public abstract void MakeSound();
// 일반 메소드: 구현할 수 있다.
public void Eat()
{
Console.WriteLine("먹는다.");
}
}
class Dog : Animal
{
// 추상 메소드 구현
public override void MakeSound()
{
Console.WriteLine("멍멍");
}
}
Dog dog = new Dog();
dog.MakeSound();
dog.Eat();
가상 메소드는 virtual 키워드를 사용하며 자식 클래스에서 재정의할 수 있는 부모 클래스의 메소드.
가상 메소드는 선택적으로 재정의할 수 있고 추상 메소드는 파생 클래스에서 반드시 구현을 해야 한다.
또한 가상 메소드는 구현이 가능하며 추상 메소드는 구현이 불가능하다.
⚔ 가상 메소드
class Animal
{
public virtual void MakeSound()
{
Console.WriteLine("소리");
}
}
class Dog : Animal
{
public override void MakeSound()
{
Console.WriteLine("멍멍");
}
}
Dog dog = new Dog();
dog.MakeSound();
C#에서 난수를 생성할 때는 Random 클래스를 사용합니다.
⚔ 랜덤 숫자 생성
Random random = new Random();
int randomNum = random.Next(); // 0 ~ int.MaxValue사이의 난수 생성
int randomNumInRange = random.Next(1,101); // 1 ~ 100 사이의 난수 생성
문자열 처리란 문자열을 다루고 조작하는 방법이다.
⚔ 문자열 생성 및 초기화
string s = "Hello, World!";
⚔ 문자열 길이 확인
// 문자열의 길이는 Length 속성을 사용
string s = "Hello, World!";
int len = s.Length; // 13
⚔ 문자열 비교
// 문자열을 비교할 때 '==' 연산자나 'Equal' 메소드를 사용
string s1 = "Hello";
string s2 = "World";
bool isEqual = s1 == s2; // false;
bool isEqualMethod = s1.Equals(s2); // false
⚔ 부분 문자열 추출
// Substring() 메소드로 문자열의 일부를 추출할 수 있다.
string s = "Hello, World!";
string hello = s.Substring(0,5); // "Hello"
⚔ 문자열 분할
// Split() 메소드로 문자열을 특정 구분자로 나눌 수 있다.
string s = "Hello, World!";
string[] words = s.Split(','); // {"Hello", " World!"}
⚔ 문자열 합치기
// '+' 연산자나 'String.Concat' 메소드로 문자열을 합칠 수 있다.
string s1 = "Hello,";
string s2 = " World!";
string message = String.Concat(s1, s2); // "Hello, World!"
⚔ 문자열 포맷팅
string name = "Jin";
int age = 30;
string message = String.Format("Name: {0}, Age: {1}", name, age); // "Name: Jin, Age: 30"
⚔ 문자열 배열 변환
string message = "Hello";
char[] chars = message.ToCharArray(); // {'H', 'e', 'l', 'l', 'o'}
string newMessage = new string(chars); // "Hello"
C#에서 out과 ref 키워드는 메소드에 인수로 전달된 변수를 참조로 전달할 때 사용. 둘 다 메소드 내부에서 값을 변경할 수 있으며, 메소드 호출 후에도 변경된 값이 반영됨.
⚔ out
// 메소드가 여러 값을 초기화해서 반환할 때 유용
// 특징: 메소드가 값을 반환하기 전에 값을 할당해야 하고, 호출할 때 초기화되지 않아도 됨.
void GetValues(out int x, out int y)
{
x = 10;
y = 20;
}
int a, b;
GetValues(out a, out b);
Console.WriteLine($"a: {a}, b: {b}"); // a: 10, b: 20
⚔ ref
// 변수의 현재 값을 메소드 내부에서 수정할 때 유용
// 호출할 때 변수는 초기화되어 있어야 하고, 메소드 내부에서 값을 수정할 수 있음.
void Increment(ref int number)
{
number++;
}
int a = 5;
Increment(ref a);
Console.WriteLine(a); // 6
ref는 메소드에서 값이 수정되지 않아도 괜찮고, 매개변수로 전달하기 전에 초기화되어야 한다.
out은 메소드에서 값을 반드시 할당해야하고, 매개변수로 전달하기 전에 초기화하지 않아도 괜찮다.
C#에서 is와 as키워드는 객체의 타입을 확인하고 변환하는 데 사용된다.
⚔ is
// 객체가 특정 타입인지 확인할 때 사용한다.
// 타입이 일치하면 true, 그렇지 않으면 false를 반환한다.
object obj = "Hello, World!";
if(obj is string)
{
Console.WriteLine("obj is a string");
}
else
{
Console.WriteLine("obj is not a string");
}
⚔ as
// 객체를 특정 타입으로 변환할 때 사용
// 타입 변환이 성공하면 변환된 객체를 반환, 실패하면 null을 반환한다.
object obj = "Hello, World!";
string str = obj as string;
if(str != null)
{
Console.WriteLine("Conversion successful: " + str);
}
else
{
Console.WriteLine("Conversion failed");
}