👾 내일배움캠프/🎮 TIL & WIL

내일배움캠프 6일차 TIL - C# 기초 문법 (1)

리리핸 2023. 8. 14. 22:19

 

[공부 내용]

 

* 기억해야 할 부분 또는 헷갈리는 내용 위주로

 


프로그래밍 기본 요소

 

(1) Escape Sequence

 

이스케이프 시퀀스 설명
\' 또는 \" 문자열 내에 따옴표 삽입
\\ 문자열 내 역슬래시 삽입: 파일 경로 등의 표기에 필요한 경우 많음
\n 줄바꿈
\r 현재 줄 맨 앞으로 이동
\t 탭 삽입
\b 백스페이스 삽입
  • 다른 프로그래밍 언어들과 거의 비슷한 것 같다.
  • \r, \t, \b는 모두 활성 위치(커서)를 옮겨가도록 한다. 그 후에 덮어쓰기 되는 것
    • \b 백스페이스 삽입 같은 경우에도 커서를 한 칸 뒤로 옮기기 때문에 백스페이스 역할을 하는 것

 


(2) 주석

 

  • 작성하는 습관이 들지 않아 주석을 정말 안 쓰는데 (심지어 코드도 나만 알아볼 수 있는 최악의 상황), 앞으로 협업이 많아질 것을 생각하면 필요한 정보들을 표시하는 습관을 들여야겠다.
  • 물론 주석 의존 금지 (주석 대신 누구나 알아볼 수 있는 직관적인 코드를 쓰는 습관 들이기, 주석은 코드 대체 불가)
  • 필요한 경우에만 사용하기 (불필요한 주석은 코드 읽기를 방해)

 


변수와 자료형

 

(1) 자료형의 세분화

 

  • 메모리의 효율적인 사용
    • ex) sbyte 음수값 포함하기 때문에 양수를 사용하면 음수 부분을 버리는 비효율적인 활용이
  • 정확한 데이터 표현
    • 데이터가 int 표현 범주를 넘어설 때는 long이나 ulong 등을 쓰도록
    • float double 차이도 마찬가지 --> 서로 다른 범위의 값을 표현할 수 있음
  • 타입 안전성
    • 해당 자료형이 가질 수 있는 값의 범위를 통해 코드를 제한

 


(2) 변수 선언과 초기화

 

    • 기본적인 변수 선언: 자료형 변수이름;
    • 한 번에 여러 개의 변수 선언 가능: int num1, num2, num3;
    • 변수 초기화: 변수에 값을 저장 (변수이름 = 값;)
    • 한 번에 여러 개 초기화
      • Int num1, num2, num3 = 10; (x)      // 경우 num 3 초기화 됨
      • num1 = num2 = num3 = 10;            // 이런 식으로 오른쪽에서부터 할당 가능

 


(3) *** 변수명 ***

 

  • 규칙
    • 식별자: 변수, 메서드, 클래스, 인터페이스 등의 이미 이름. 키워드(이미 예약된 이름)를 쓸 수 없다.
    • 문자는 알파벳 or 언더스코어(_)
    • 번째부터는 숫자도 가능 (알파벳, 숫자, 언더스코어만 가능)
    • 대소문자 구분
    • 명확한 이름 사용하기 (식별자 명으로 x, a, b와 같은 무의미한 이름은 지양하기 / 어떤 용도로 쓰였는지 이해하기 쉬운 이름)
  • 코드 컨벤션 (관습적으로 쓰이는 규칙)
    • PascalCase: 클래스, 매서드, 프로퍼티
    • camelCase: 변수, 매개변수, 로컬변수
    • 대문자: ID, HTTP, FTP 예외
    • 관련 없는 코드 사이에서 하나 추가
    • 메서드, 클래스 등의 블록 사이에는 추가

 

 


 

(4) 형변환

 

    • 형변환: 데이터의 타입을 바꾸는 것
    • 명시적 형변환: 직접 바꾸는
      • ex) int num; --> string age = num.ToString();
      • (int / int) 나머지를 버리고 int 반환하기 때문에 평균값 등을 구할 때는   하나를 부동소수점형(float 또는 double)의 형태로 명시적으로 변환시켜야 함
    • 암시적 형변환: 직접 변환하지 않아도 계산 중에 자동적으로 형태를 변환하여 인식되는 것
      • 작은 데이터타입에서 데이터타입으로 대입하는 경우 발생
        • byte --> int
      • 리터럴 값이 대입되는 경우
        • float result = 1; (1은 int 형태이지만 컴파일러가 float으로 판별)
      • 정수형과 부동소수점형 간의 연산 --> 부동소수점형으로
  • var 키워드: 초기값에 따라 자료형이 컴파일러에 의해 자동으로 결정됨
    • 변수를 선언하는 시점에서 변수의 자료형을 정확히 알 수 없는 경우에 유용하게 사용할 수 있다.
    • ex) var num = 20; --> int 자료형으로 결정

 


연산자와 문자열 처리

 

(1) 연산자

 

  • 산술연산자 : + - / * %
  • 관계연산자 : ==, !=, >, <, >=, <=
  • 논리연산자 : &&, ||, !
  • 증감연산자 : ++ (1 증가), -- (1 감소)
    • 전위 vs 후위에 따라 실행이 달라진다.
    • 코드는 왼쪽에서부터 오른쪽으로 읽히며 실행된다.  ++x (전위) 경우 증감연산자에 의해 더하는 행위를 할 준비가 완료된 상태에서 x라는 변수를 만나기 때문에 바로 연산자 발동한다. 그러나 x++ (후위) 경우 x 이미 처리했는데 ++ 뒤에 나오기 때문에 뒤에 붙은 모든 작업이 끝난 후에 값이 더해진다.

 


 

(2) 비트연산자

 

연산자 설명
& (AND) 두 비트 값이 모두 1일 때 1 반환
| (OR) 두 비트 값 중 하나라도 1일 때 1 반환
^ (XOR) 두 비트 값이 서로 다를 때 1 반환
~ (NOT) 비트 값의 보수(complement)를 반환
<< (왼쪽 시프트) 비트를 왼쪽으로 이동
>> (오른쪽 시프트) 비트를 오른쪽으로 이동
int a = 0b1100; // 12 (2진수)
int b = 0b1010; // 10 (2진수)

int and = a & b; // 0b1000 (8)
int or = a | b; // 0b1110 (14)
int xor = a ^ b; // 0b0110 (6)

int c = 0b1011; // 11 (2진수)
int leftShift = c << 2; // 0b101100 (44)
int rightShift = c >> 1; // 0b0101 (5)

int d = 0b1100; // 12 (2진수)
int bit3 = (d >> 2) & 0b1; // 0 (3번째 비트)
d |= 0b1000; // 0b1100 | 0b1000 = 0b1100 (12)
 

비트 연산자 (bitwise operator)

비트 연산이란? 비트 연산은 비트 단위로 수행되는 연산이다. 기본 자료형 char, int와 같은 바이트 단위보다 더 작은 비트 단위를 다룬다. 정수형 변수 또는 정수형 값을 이루는 모든 비트들에 대

velog.io

 


 

(3) 문자열

 

  • 생성: string str1 = new string(‘I’, 5);     // str1 == “iiiii” 같은 문자를 지정된 횟수만큼 반복해서 만듦
  • 연결: 더하기 
  • 분할: Split() - 띄어쓰기(공백) 또는 입력값을 기준으로 나누어 배열 형태로 저장
  • 검색
    • string str = “Hello, World!”;
    • int index = str.IndexOf(“World!); // index == 7
  • 대체:
    • string newStr = str.Replace(“World”, “Universe”); // newStr == “Hello, Universe!”
  • 문자열의 대소비교: 사전식 비교. 사전에 뒤에 나올수록 높은 값 (문자열 길이 상관 x)
    • string apple = "apple"; 
    • apple > "ant" // false
  • 포맷팅
    • 문자열 형식화 (위) vs 문자열 보간 (아래) --- 편한 방법 골라 쓰기
string name = "John";
int age = 30;
string message = string.Format("My name is {0} and I'm {1} years old.", name, age);
string name = "John";
int age = 30;
string message = $"My name is {name} and I'm {age} years old.";

 


조건문과 반복문

 

*코드의 흐름을 제어하므로 제어문에 해당

 

(1) 조건문

  • 조건문 종류: if / else / else if / 중첩조건문 / switch / 3항연산자
  • 3항연산자
    • (조건식) ? 참일 경우 : 거짓일 경우 ;
    • string result = (currentExp >= requiredExp) ? "레벨업 가능" : "레벨업 불가능";  // (조건식)의 결과에 따라 다른 값이 할당 되는 사례
  • Switch문은 break만나기 전까지 쭈욱 읽기 때문에, case를 이어서 쓰면 동일한 실행을 둘 이상의 케이스에서 진행할 수 있음
switch (변수나 식)
{
    case 값1:
        // 값1이 나온 경우 실행되는 코드
        break;
    case 값2:
        // 값2가 나온 경우 실행되는 코드
        break;
    // ...
    default:
        // 모든 case문에 해당하지 않는 경우 실행되는 코드
        break;
}
  • case를 인덱스로 생각하면 좋을 듯. 해당되는 인덱스로 바로 찾아 가는 느낌. case를 찾아갔는데 다음 case까지 break가 없으면 다음 break가 나올 때까지의 내용을 다 실행함. 
  • 따라서 case 값1: 부분에 break가 없으면 값 1에 해당하는 경우이더라도 (값 1이 나온 경우 실행되는 코드)와 (값 2가 나온 경우 실행되는 코드)가 모두 실행됨.

 


 

(2) 반복문

 

  • for문 : 초기식, 조건식, 증감식을 사용하여 반복문을 작성
    • 명확한 회차, 명확한 데이터가 주어질 때 사용
    • n 반복하기
  • while :
    • 변화되는 조건 속에서 ~가 될 때까지
    • 조건이 강조
  • do while
    • while문과 비슷하지만 조건식을 검사하기 전에 먼저 코드 블록을 한 번 실행한다는 점!
  • foreach문 :         // 직접 써본 적 없으니 활용해보기
    •  배열이나 컬렉션의 요소를 하나씩 꺼내서 활용 (해당 자료 구조의 길이 만큼 반복)
foreach (자료형 변수 in 배열 또는 컬렉션)
{
    // 배열 또는 컬렉션의 모든 요소에 대해 반복적으로 실행되는 코드
}

 


배열과 컬렉션

 

(1) 배열

 

  • 동일한 자료형의 값들이 연속적으로 저장되는 구조
  • 인덱스를 통해 요소 접근
// 배열 선언
데이터_유형[] 배열_이름;

// 배열 초기화
배열_이름 = new 데이터_유형[크기];

// 배열을 한 줄로 선언 및 초기화
데이터_유형[] 배열_이름 = new 데이터_유형[크기];

// 배열 요소에 접근
배열_이름[인덱스] = 값;
값 = 배열_이름[인덱스];

 

  • 다차원 배열
    • 여러 배열을 묶어서 행과 열로 구성된 표와 같아 보이는 배열
    • 만들 활용

 


 

(2) 컬렉션

 

  • 자료를 모아 놓은 데이터 구조
  • 배열과 다르게 크기가 가변적
  • 사용하려면 System.Collections.Generic 네임스페이스 추가 필요

 

  •  List
    •  Length   없음. 대신 Count()를 
List<int> numbers = new List<int>(); // 빈 리스트 생성
numbers.Add(1); // 리스트에 데이터 추가
numbers.Add(2);
numbers.Add(3);
numbers.Remove(2); // 리스트에서 데이터 삭제

foreach(int number in numbers) // 리스트 데이터 출력
{
    Console.WriteLine(number);
}

 

  • Dictionary
    • 키와 값으로 구성
using System.Collections.Generic;

Dictionary<string, int> scores = new Dictionary<string, int>(); // 빈 딕셔너리 생성
scores.Add("Alice", 100); // 딕셔너리에 데이터 추가
scores.Add("Bob", 80);
scores.Add("Charlie", 90);
scores.Remove("Bob"); // 딕셔너리에서 데이터 삭제

foreach(KeyValuePair<string, int> pair in scores) // 딕셔너리 데이터 출력
{
    Console.WriteLine(pair.Key + ": " + pair.Value);
}

 

  • Stack / Queue
    • Stack은 후입선출(LIFO) 구조를 가진 자료 구조
      • Stack<int> stack1 = new Stack<int>(); 
      • int value = stack1.Pop();     // value = 3 (마지막에 추가된 요소)
    • Queue는 선입선출(FIFO) 구조를 가진 자료 구조
      • Queue<int> queue1 = new Queue<int>(); 
      • int value = queue1.Dequeue();     // value = 1 (가장 먼저 추가된 요소)

 

  • HashSet
    • HashSet은 중복되지 않은 요소들로 이루어진 집합
    • 중복 제거 등에 활용하기 좋을 듯?

 


  

(3) 배열과 리스트

 

  • 배열의 정해진 크기 때문에 리스트를 더 편하게 생각하고 무분별하게 리스트를 사용하는 경우가 많다고 함.
    • 리스트는 크기가 가변적인 대신 메모리 사용량, 데이터 접근 시간 증가
    • 배열이 가진 기능들을 활용하지 못하므로 코드 복잡도 증가
    • 필요에 따라 잘 선택해서 사용할 필요 

 

 


메서드

 

(1) 메서드

 

  • 독립적인 기능 단위의 코드블록
  • 코드의 재사용성과 모듈화를 위해 사용, 필요할 때 호출하여 실행
[접근 제한자] [리턴 타입] [메서드 이름]([매개변수])
{
    // 메서드 실행 코드
}
  • 구조와 문법
    • 접근제한자 : 메서드에 접근할 수 있는 범위.
      • public: 어디에서나
      • private: 같은 클래스 내에서만
      • protected: 상속받은 자식의 클래스에서만
    • 리턴 타입 
      • 반환값이 있을 경우 : 반환값의 데이터 타입으로 설정
      • 반환값이 없을 경우 : void
    • 메서드 이름 : PascalCase로 쓰도록

 


 

(2) 메서드 오버로딩

 

  • 이름의 메서드를 다양한 매개변수 목록으로 다중 정의
  • 매개변수의 개수, 타입, 순서가 다를 경우 활용
  • 호출하는 입장에서는 고려할 부분이 없다. 호출 시 입력되는 매개변수에만 영향을 받아 알아서 적절한 함수를 선택함

 


 

(3) 재귀 함수

 

  • 예시로 보는 게 가장 좋을 듯
void CountDown(int n)
{
    if (n <= 0)
    {
        Console.WriteLine("Done");
    }
    else
    {
        Console.WriteLine(n);
        CountDown(n - 1);  // 자기 자신을 호출
    }
}

// 메서드 호출
CountDown(5);
  • 함수 내에서 함수가 반복적으로 호출됨
  • 이전 프로젝트에서도 카운트다운에 활용할 수 있었을 것 같다

 

 


[기록]

 

잘한 점 :

  • 딱히 없는 것 같다... 어떡하지...

 

어려웠던 점 :

  • 집중하기...

 

되돌아보기 :

  • 오늘의 몰입도 : 50점
    • 여행 피로 + 어느 정도 아는 내용 --> 집중 정말 안 됨..
    • 그래도 꾸역꾸역 2주차까지는 들었으니까 절반은 주기
  • 스스로 찾아보기: 20점
    • 별로 한 게 없다..

 

내일 목표

  • C#문법종합반 3주차까지 듣기
  • Invoke, Coroutine 등 시간 관련된 공부
  • 생명 주기 공부
  • 피로 회복 잘 하고 공부 패턴 돌려놓기..