문자열, 함수1

이정현
∙∙조회 5

20261002 문자열, 함수1

나누기와 합치기

Split

구분자를 기준으로 문자열을 잘라 배열로 만듬

csharp
using System;

string colors = "Red,Green,Blue";
string[] parts = colors.Split(',');

Console.WriteLine($"조각 수: {parts.Length}");

for (int i = 0; i < parts.Length; i++)
{
    Console.WriteLine($"{i}: {parts[i]}");
}

  • 주의사항: 구분자가 연달아 있으면 빈 조각이 생김
csharp
using System;

string messy = "a,,b,";
string[] parts = messy.Split(',');

Console.WriteLine($"조각 수: {parts.Length}");

for (int i = 0; i < parts.Length; i++)
{
    Console.WriteLine($"{i}: [{parts[i]}]");
}

빈 조각을 버리려면 옵션을 사용하면 된다.(StringSplitOptions.RemoveEmptyEntries)

csharp
using System;

string messy = "a,,b,";
string[] parts = messy.Split(',', StringSplitOptions.RemoveEmptyEntries);

Console.WriteLine($"조각 수: {parts.Length}");

foreach (string part in parts)
{
    Console.WriteLine($"[{part}]");
}

구분자를 한번에 여러 개 지정할 수도 있다.

  • string[] parts = mixed.Split(',', ';', ' ');

Join

Split의 반대다. 배열의 조각들을 구분자로 이어 하나의 문자열로 만든다.

csharp
using System;

string[] fruits = { "사과", "바나나", "오렌지" };

Console.WriteLine(string.Join(", ", fruits));
Console.WriteLine(string.Join(" / ", fruits));
Console.WriteLine(string.Join("", fruits));
Console.WriteLine(string.Join(" → ", fruits));

// 아래처럼 출력 된다.
// 사과, 바나나, 오렌지
// 사과 / 바나나 / 오렌지
// 사과바나나오렌지
// 사과 → 바나나 → 오렌지

반복문으로 이어붙일 경우 끝에 하나가 남는 문제가 생겨서 따로 처리를 해줘야 하지만 Join은 그것을 알아서 처리한다.

csharp
using System;

string[] items = { "검", "활", "지팡이" };

// 반복문으로 이어 붙이면 뒤에 구분자가 남음
string manual = "";
foreach (string item in items)
{
    manual += item + ", ";
}

Console.WriteLine($"직접: [{manual}]");
Console.WriteLine($"Join: [{string.Join(", ", items)}]");

// 아래와 같이 출력 된다
// 직접: [검, 활, 지팡이, ]
// Join: [검, 활, 지팡이]

Concat

여러 문자열을 그냥 이어붙인다. 구분자가 없는 Join과 같다. 결과는 +로 이어붙이는 것과 같으며 조각들이 배열에 담겨있을 때 Concat이나 Join이 편하다.

문자 배열과 문자열 사이

ToCharArray는 문자열을 char배열로 만들고, new string(배열)은 그 반대임. 문자열은 글자를 바꿀 수 없지만, char 배열로 바꿔주면 각 칸을 수정할 수 있게됨. 글자단위로 수정해야 할 때 쓰는 방법이다.

csharp
using System;

string text = "Hello";
char[] chars = text.ToCharArray();

chars[0] = 'J';
chars[4] = 'y';

Console.WriteLine($"원본: {text}");
Console.WriteLine($"수정: {new string(chars)}");

StringBuilder

이어붙이기가 느려지는 이유 문자열은 내용이 바뀌지 않으므로 +=로 이어 붙일 때마다 앞의 것을 모두 복사한 새 문자열이 만들어짐. 붙일수록 복사하는 양이 커짐. StringBuilder는 내용을 바꿀 수 있는 문자열 담개임. 붙일 때 새로 만들지 않고 담긴 내용을 늘림.

StringBuilder를 사용하는 방법

System.Text안에 있음. 만들고, Append로 붙이고, 다 붙인 뒤 ToString으로 문자열을 꺼냄.

csharp
using System;

using System.Text; // 여기에 StringBuilder가 있다.

StringBuilder sb = new StringBuilder();

sb.Append("안녕");
sb.Append("하세요");
sb.Append("!");

string result = sb.ToString();

Console.WriteLine(result);
Console.WriteLine($"길이: {result.Length}");

주요 메서드

메서드하는 일
Append(값)끝에 붙임
AppendLine(값)붙이고 줄바꿈까지 넣음
AppendFormat(서식, 값들)서식을 적용해 붙임
Insert(위치, 값)지정한 자리에 끼워 넣음
Remove(위치, 개수)지정한 범위를 지움
Replace(찾을 것, 바꿀 것)전부 바꿈
Clear()담긴 내용을 모두 비움
ToString()문자열로 꺼냄

메서드를 이어 부르기

Append계열은 자기 자신을 돌려주므로 점을 이어 붙여 계속 호출할 수 있음.

csharp
using System;
using System.Text;

string message = new StringBuilder()
    .Append("이어 부르기로 ")
    .Append("한 문장을 ")
    .Append("만듦")
    .ToString();

Console.WriteLine(message);

// 아래와 같이 출력됨.
// 이어 부르기로 한 문장을 만듦

  • 주의사항: 맨처음 만들어낸 StringBuilder가 Append할 때마다 Return된다고 생각 해야함.

어떤 상황에 무엇을 사용할 지 선택

상황알맞은 것
정해진 개수의 값을 한 번 합침보간 문자열, +
배열의 조각들을 구분자로 잇기string.Join
반복문 안에서 계속 붙임StringBuilder
붙이는 횟수가 실행 중에 정해짐StringBuilder
중간에 끼워 넣고 지우기를 반복함StringBuilder

함수

특정 작업을 하는 코드에 이름을 붙여 묶는것.

  • 함수와 메서드: 클래스에 속한 함수를 메서드 라고 부른다.

  • 용어 정리

    용어뜻
    함수이름을 붙여 묶은 코드 덩어리
    호출(call)함수 이름을 불러 그 코드를 실행시키는 것
    매개변수(parameter)함수가 받기로 정해 둔 입력값. 함수 정의에 적음
    인수(argument)호출할 때 실제로 넘기는 값. 함수 호출에 적음
    반환값(return value)함수가 호출한 쪽으로 돌려주는 결과
  • 함수로 묶어서 얻는 것은 세가지임.

    얻는 것내용
    재사용한 번 정의하고 필요한 만큼 호출함
    한 곳 수정고칠 자리가 함수 안 한 곳으로 모임
    읽기 쉬움PrintHeader() 한 줄이 세 줄보다 의도를 잘 드러냄

함수의 구조

함수를 정의하는 형태는 아래와 같음.

kotlin
반환타입 함수이름(매개변수 목록)
{
    // 실행할 코드

    return 반환값;   // 반환 타입이 void 가 아닐 때
}

자리하는 일
반환타입돌려주는 값의 타입. 돌려줄 값이 없으면 void
함수 이름호출할 때 부르는 이름
매개변수 목록받을 값의 타입과 이름. 없으면 괄호를 비워둠
본문 {}실제로 실행되는 코드
return결과를 돌려주고 함수를 끝냄

이름 짓는 규칙

함수 이름은 파스칼 표기법으로 씀. 첫 글자를 포함해 각 낱말의 첫 글자를 대문자로 적는 방식임.

표기판정
PrintHeader권장
GetTotalPrice권장
printHeader변수 표기법이라 함수에 쓰지 않음
print_headerC# 표기법이 아님

이름은 하는 일이 드러나게 지음. 값을 돌려주는 함수는 Get, Calculate, 참, 거짓을 알려주는 함수는 Is, Has, 동작만 하는 함수는 동사로 시작하는 것이 관례임.

정의 위치

함수 정의는 실행문 사이 어디에 놓아도 됨. 정의보다 앞에서 호출해도 문제가 없음.

  • 팁: 문법상 위치는 자유롭지만 함수 정의를 파일 아래쪽에 모아 두면 위쪽의 실행 흐름이 한눈에 들어옴. 앞으로도 아래쪽에 모아서 작성하도록.

함수가 함수를 호출함

함수 안에서 다른 함수를 부를 수 있음. 이렇게 하면 큰 작업을 작은 작업으로 쪼갤 수 있음.

매개변수

값을 받는 함수 ` 함수마다 다른 값을 다루게 하려면 매개변수로 값을 받는다.

csharp
using System;

ShowMessage("안녕하세요");
ShowMessage("반갑습니다");
ShowMessage("좋은 하루 되세요");

void ShowMessage(string message)
{
    Console.WriteLine(message);
}

타입이 서로 다른 매개변수

  • 매개변수마다 타입을 따로 적으므로 섞어 쓸 수 있음.

인수의 개수와 타입이 맞아야 함

  • 매개변수가 정한 개수와 타입에 맞지 않으면 컴파일 오류가 남.
  • 다만 넓은 타입으로 자동 변환되는 경우는 통과함.(int -> double 이것이 그 예다.)

배열을 매개변수로 받기

  • 배열도 다른 값과 마찬가지로 넘길 수 있음.
  • 주의사항: 함수 안에서 배열의 요소를 바꾸면 원본 배열이 바뀜.

반환값

값을 돌려주는 함수

  • 계산결과를 호출한 쪽이 받아서 쓰려면 값을 돌려줘야 함.

return은 함수를 즉시 끝냄

반환값을 주는 함수라고 해서 무조건 쓸 필요는 없다. 반환값이 필요없다면 함수만 실행해도됨.

기본값이 있는 매개변수

함수를 선언할 때 매개변수에 = 값붙이면 호출할 때 그 인수를 생략할 수 있음. 매개변수에 값을 입력하면 매개변수 값으로 적용되고 생략하면 = 값에 있는 값을 사용한다.

csharp
using System;

Log("디스크 공간 부족");
Log("파일을 찾을 수 없음", 3);

void Log(string message, int level = 1) // <= `int level = 1 `
{
    Console.WriteLine($"[{level}] {message}");
}

기본값이 여러개 일 떄

기본값이 여러개인 경우 뒤쪽에 있는 매개변수부터 생략할 수 있음. 기본값은 뒤쪽부터 앞쪽 순서로 놓을 수 있다.

명명된 인수

이름을 붙여서 넘기기

호출할 때 매개변수이름:값 형태로 적으면 어느 매개변수에 넣을지 직접 지정할 수 있음. 일반적인 경우에는 잘 사용하지 않는다.

기본값과 함께 쓰기

명명된 인수를 쓰면 중간 매개변수를 건너뛰고 뒤쪽만 지정 할 수 있음

csharp
using System;

Attack("슬라임");
Attack("고블린", isCritical: true);
Attack("드래곤", damage: 100, isCritical: true);

void Attack(string target, int damage = 10, bool isCritical = false)
{
    string mark = isCritical ? " (치명타!)" : "";
    Console.WriteLine($"{target}에게 {damage} 피해{mark}");
}

섞어 쓸 때의 규칙

이름 없는 인수와 이름 있는 인수를 섞어 쓸 수 있음. 조건은 이름을 붙인 인수가 자기 자리에 그대로 있어야 뒤에 이름 없는 인수를 둘 수 있음.

csharp
using System;

Order("사과", count: 3, isGift: true);
Order(item: "배", 3, isGift: false);

void Order(string item, int count, bool isGift)
{
    Console.WriteLine($"{item} {count}개 (선물={isGift})");
}

변수의 범위

지역 변수

함수 안에서 선언한 변수는 그 함수 안에서만 쓸 수 있음. 이런 변수를 지역 변수(local variable) 라고 함.

블록범위

중괄호로 묶인 블록 안에서 선언한 변수는 그 블록 안에서만 유효함. 함수 안이라도 마찬가지.

매개변수도 지역 변수

함수 안에서 매개변수를 바꿔도 넘긴 쪽의 변수는 그대로임.

함수 밖의 변수에 닿을 때

함수 밖에서 선언한 변수는 함수 안에서 보이고, 값을 바꿀 수도 있음

csharp
using System;

int score = 0;

AddScore(10);
AddScore(25);
Console.WriteLine($"최종 점수: {score}");

void AddScore(int point)
{
    score += point;   // 함수 밖의 변수를 직접 바꿈
    Console.WriteLine($"{point}점 획득 (누적 {score}점)");
}

편리해 보이지만 함수 밖 변수를 함수 안에서 바꾸는 것은 조심해서 써야 함. AddScore(10)이라는 호출만 봐서는 score가 바뀐다는 사실이 드러나지 않기 때문이다. 값을 반환하는 형태로 만들어서 사용하면 흐름이 눈에 보인다.

csharp
using System;

int score = 0;

score = AddScore(score, 10);
score = AddScore(score, 25);
Console.WriteLine($"최종 점수: {score}");

int AddScore(int current, int point)
{
    return current + point;
}

같은 이름을 쓰면 바깥이 가려짐

함수 밖에 있는 이름을 함수 안에서 다시 선언할 수 있음. 이때 안쪽 이름이 바깥 이름을 가림.

식 본문 함수

=>로 줄여쓰기. 본문이 식 하나로 끝나는 함수는 중괄호와 return 없이 =>로 적을 수 있음.

  • 주의사항: 식의 반환형이 함수의 반환형과 동일 해야 한다.
csharp
using System;

Console.WriteLine(Add(10, 20));
Console.WriteLine(AddShort(10, 20));

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

int AddShort(int a, int b) => a + b; // 이부분이 식 본문함수

void 함수도 쓸 수 있다.

csharp
using System;

PrintLine();
SayHelloTo("홍길동");

void PrintLine() => Console.WriteLine("--------");
void SayHelloTo(string name) => Console.WriteLine($"{name}님, 안녕하세요");

언제 쓰는가

본문이 여러 줄이면 =>를 쓸 수 없음. 조건문이나 반복문이 들어가는 순간 중괄호 형태로 써야함.