연습 - 메서드를 사용하여 코드 빌드
메서드는 코드를 체계적으로 구성하고, 코드를 재사용하고, 문제를 효율적으로 해결하는 데 유용합니다. 입력을 받고 명명된 작업을 수행하고 출력을 반환하는 블랙박스와 같은 메서드를 생각할 수 있습니다. 이 가정을 사용하면 작업을 메서드로 명명한 다음 필요한 모든 작업을 식별한 후 논리를 입력하는 것만으로 프로그램을 신속하게 구성할 수 있습니다.
일반 언어를 사용하여 구문 규칙을 엄격하게 준수하지 않고 코드의 단계를 설명하는 경우 "의사 코드"를 사용하는 것입니다. 메서드와 의사 코드를 결합하는 것은 어려운 프로그래밍 작업을 신속하게 처리할 수 있는 좋은 방법입니다.
메서드를 사용하여 코드 구조화
코딩 면접의 후보라고 가정해 보겠습니다. 면접관이 IPv4 주소가 유효한지 여부를 확인하는 프로그램을 작성하도록 요청합니다. 다음과 같은 규칙이 제공됩니다.
- 유효한 IPv4 주소는 점으로 구분된 4개의 숫자로 구성됩니다.
- 각 숫자에는 선행 0이 포함되어서는 안 됩니다.
- 각 숫자의 범위는 0에서 255 사이여야 합니다.
예를 들면 1.1.1.1 및 255.255.255.255는 유효한 IP 주소입니다.
IPv4 주소는 문자열로 제공됩니다. 이 문자열은 숫자와 점으로만 구성된다고 가정할 수 있습니다(제공된 문자열에는 문자가 없음).
이 작업에 어떻게 접근해야 할까요?
참고
IP 주소에 대해 잘 몰라도 걱정하지 마세요! 이 연습에서는 단계를 따라 코드를 완료할 수 있습니다.
문제 분할
이 작업에서는 문제를 해결하는 데 필요한 단계를 식별합니다. 규칙을 자세히 살펴보면 IPv4 주소가 유효한지 여부를 확인하는 데 세 단계만 거치면 된다는 것을 알 수 있을 것입니다.
Visual Studio Code 편집기에서 이전 연습의 기존 코드를 모두 삭제합니다.
편집기에 다음 의사 코드를 입력합니다.
/* if ipAddress consists of 4 numbers and if each ipAddress number has no leading zeroes and if each ipAddress number is in range 0 - 255 then ipAddress is valid else ipAddress is invalid */의사 코드는 문제 해결을 시작하는 좋은 방법입니다. 이 주석 블록을 사용하여 프롬프트 규칙과 프로그램 코드 간의 격차를 좁혀 코드가 수행할 주요 작업을 명확히 설명합니다. 의사 코드는 기능적이거나 구문 규칙을 준수할 필요는 없습니다. 그러나 코드가 수행할 작업을 명확하게 설명해야 합니다. 이제 이를 실제 코드로 전환해 보겠습니다.
새 빈 코드 줄을 입력하고 편집기에서 다음 코드를 입력합니다.
if (ValidateLength() && ValidateZeroes() && ValidateRange()) { Console.WriteLine($"ip is a valid IPv4 address"); } else { Console.WriteLine($"ip is an invalid IPv4 address"); }이 단계에서는 의사 코드의
if문을 호출 가능한 메서드로 변환하고 결과를 출력합니다. 메서드를 정의하는 것에 대해서는 아직 걱정하지 마세요. 각 메서드가 해당 이름이 설명하는 작업을 수행한다고 가정할 수 있습니다. 컴파일 오류를 수정하고 곧 메서드 논리를 만들지만 지금은 전체 디자인에 집중하세요. 새 프로그램 작업을 시작할 때 전체 디자인에 집중하면 체계적으로 구성된 애플리케이션을 더 신속하게 개발하는 데 도움이 됩니다.기존 코드 아래에 새 빈 코드 줄을 입력하고 편집기에서 다음 코드를 입력합니다.
void ValidateLength() {} void ValidateZeroes() {} void ValidateRange() {}자리 표시자 메서드를 사용하여 문제에 신속하게 접근하고 코드를 구조화하여 솔루션을 개발할 수 있었습니다. 이제 구조화된 계획을 마련했으므로 코드 조각을 하나씩 입력하여 문제를 계속 해결할 수 있습니다.
솔루션 개발
이제 문제를 해결하는 데 필요한 모든 자리 표시자 메서드가 있으므로 솔루션의 세부 사항에 집중할 수 있습니다. IPv4 주소의 입력 형식은 점으로 구분된 숫자로 구성된 문자열이라는 것을 항상 기억하세요. 시작해 봅시다!
프로그램 시작 부분에서 입력 및 유효성 검사 상태를 저장할 변수를 만듭니다.
string ipv4Input = "107.31.1.5"; bool validLength = false; bool validZeroes = false; bool validRange = false;다음과 같이 유효성 검사 변수를 사용하도록 솔루션 코드를 업데이트합니다.
ValidateLength(); ValidateZeroes(); ValidateRange(); if (validLength && validZeroes && validRange) { Console.WriteLine($"ip is a valid IPv4 address"); } else { Console.WriteLine($"ip is an invalid IPv4 address"); }다음과 같이
ValidateLength메서드를 업데이트합니다.void ValidateLength() { string[] address = ipv4Input.Split("."); validLength = address.Length == 4; };첫 번째 규칙은 IPv4 주소에 4개의 숫자가 있어야 한다고 명시합니다. 따라서 이 코드에서는
string.Split를 사용하여 숫자를 구분하고 4개의 숫자가 있는지 확인합니다.다음과 같이
ValidateZeroes메서드를 업데이트합니다.void ValidateZeroes() { string[] address = ipv4Input.Split("."); foreach (string number in address) { if (number.Length > 1 && number.StartsWith("0")) { validZeroes = false; } } validZeroes = true; }규칙을 코드로 변환하는 방법을 잠시 생각해 보세요.
두 번째 규칙은 IPv4 주소의 숫자에 선행 0이 포함되지 않아야 한다고 명시합니다. 따라서 메서드는
0을 유효한 숫자로 수락할 때 선행 0의 개수를 확인해야 합니다. 모든 숫자에 유효한 0이 있는 경우validZeroes는true와 같아야 하고, 그렇지 않은 경우false여야 합니다. 따라서 이 코드에서는 자리수가 두 개 이상인 각 숫자가 0으로 시작되지 않는지 확인합니다.자세히 살펴보면
validZeroes루프가 완료된 후true가foreach로 설정됩니다. 그러나 선행 0이 없는 경우에만validZeroes를true로 설정해야 합니다.validZeroes = true루프가 실행되기 전에foreach를 설정하여 이 버그를 수정할 수 있습니다. 그러나 return 문을 사용하여 이 버그를 수정할 수도 있습니다.코드를 다음과 같이 업데이트합니다.
foreach (string number in address) { if (number.Length > 1 && number.StartsWith("0")) { validZeroes = false; return; } }return 문은 해당 메서드의 실행을 종료하고 메서드 호출자에게 컨트롤을 반환합니다.
return뒤에validZeroes = false문을 추가하면 메서드가 첫 번째 잘못된 0을 찾은 후 종료됩니다. 잘못된 0이 없으면 메서드가validZeroes를true로 설정한 후 종료됩니다. 이제 다음 메서드를 살펴보겠습니다.다음과 같이
ValidateRange메서드를 업데이트합니다.void ValidateRange() { string[] address = ipv4Input.Split("."); foreach (string number in address) { int value = int.Parse(number); if (value < 0 || value > 255) { validRange = false; return; } } validRange = true; }세 번째 규칙은 IPv4 주소의 각 숫자가 0에서 255 사이여야 한다고 명시합니다. 따라서 이 코드에서는 각 숫자가 255보다 작은지 확인하고, 그렇지 않은 경우
validRange를false로 설정한 후 실행을 종료합니다. 입력 문자열에는 숫자와 점만 포함되므로 음수 여부를 확인할 필요가 없습니다.그러나 점 사이에 숫자가 없는 경우가 있을 수 있습니다. 예를 들어 "255...255"입니다. 이 경우
string.Split(".")가 빈 항목을 반환하여int.Parse는 실패합니다.StringSplitOptions를 지정하여 이를 방지할 수 있습니다.코드를 다음과 같이 업데이트합니다.
string[] address = ipv4Input.Split(".", StringSplitOptions.RemoveEmptyEntries);StringSplitOptions.RemoveEmptyEntries를 사용하면address배열에서 빈 항목이 생략되고 빈 문자열을 구문 분석하지 않게 됩니다.
솔루션 완성
이제 IP 주소의 유효성을 검사하는 모든 메서드가 완료되었으므로 초기 솔루션을 다시 살펴볼 차례입니다. 이 작업에서는 더 많은 입력 값을 추가하고 코드를 테스트할 준비를 합니다.
프로그램에서 앞서 작성한 다음 코드를 찾습니다.
string ipv4Input = "107.31.1.5";코드를 다음과 같이 업데이트합니다.
string[] ipv4Input = {"107.31.1.5", "255.0.0.255", "555..0.555", "255...255"};솔루션을 개발할 때 다양한 입력 사례로 코드를 테스트하는 것이 중요합니다. 이 코드에서는 광범위한 테스트 값을 제공합니다. 이제 테스트 입력을 업데이트했으므로 새 값을 사용하도록 코드를 업데이트해야 합니다. 값은 배열에 있으므로 루프를 사용하여 각 값을 테스트하도록 코드를 업데이트해야 합니다.
코드를 다음과 같이 업데이트합니다.
foreach (string ip in ipv4Input) { ValidateLength(); ValidateZeroes(); ValidateRange(); if (validLength && validZeroes && validRange) { Console.WriteLine($"{ip} is a valid IPv4 address"); } else { Console.WriteLine($"{ip} is an invalid IPv4 address"); } }마지막으로,
ipv4Input을 문자열에서 배열로 업데이트했으므로 각 메서드가 사용하는 입력 데이터를 수정해야 합니다. 각 메서드는string.Split를 사용하므로 변수를 선언하여string.Split의 결과를 저장하고 각 메서드에서 대신 사용할 수 있습니다.변수를 추가하여 각 메서드가 참조할 현재 IPv4 주소를 저장합니다.
string[] ipv4Input = {"107.31.1.5", "255.0.0.255", "555..0.555", "255...255"}; string[] address; bool validLength = false; bool validZeroes = false; bool validRange = false;다음과 같이
address를 사용하여string.Split를 초기화합니다.foreach (string ip in ipv4Input) { address = ip.Split(".", StringSplitOptions.RemoveEmptyEntries);전역
string.Split변수를 대신 사용하도록 각 유효성 검사 메서드에서address에 대한 참조를 제거합니다. 예를 들면 다음과 같습니다.void ValidateLength() { validLength = address.Length == 4; };
작업 결과 확인
이 작업에서는 통합 터미널에서 애플리케이션을 실행하고 코드가 올바르게 작동하는지 확인합니다. 이제 시작하겠습니다.
코드를 다음과 비교하여 올바른지 확인합니다.
string[] ipv4Input = {"107.31.1.5", "255.0.0.255", "555..0.555", "255...255"}; string[] address; bool validLength = false; bool validZeroes = false; bool validRange = false; foreach (string ip in ipv4Input) { address = ip.Split(".", StringSplitOptions.RemoveEmptyEntries); ValidateLength(); ValidateZeroes(); ValidateRange(); if (validLength && validZeroes && validRange) { Console.WriteLine($"{ip} is a valid IPv4 address"); } else { Console.WriteLine($"{ip} is an invalid IPv4 address"); } } void ValidateLength() { validLength = address.Length == 4; }; void ValidateZeroes() { foreach (string number in address) { if (number.Length > 1 && number.StartsWith("0")) { validZeroes = false; return; } } validZeroes = true; } void ValidateRange() { foreach (string number in address) { int value = int.Parse(number); if (value < 0 || value > 255) { validRange = false; return; } } validRange = true; }Ctrl + S를 사용하거나 Visual Studio Code 파일 메뉴를 사용하여 작업을 저장합니다.
필요한 경우 Visual Studio Code의 통합 터미널 패널을 엽니다.
탐색기 패널에서 TestProject 폴더 위치에서 터미널을 열려면 TestProject를 마우스 오른쪽 단추로 클릭한 다음 통합 터미널에서 열기를 선택합니다.
터미널 명령 프롬프트에서 dotnet run을 입력합니다.
코드가 다음 출력을 생성하는지 확인합니다.
107.31.1.5 is a valid IPv4 address 255.0.0.255 is a valid IPv4 address 555..0.555 is an invalid IPv4 address 255...255 is an invalid IPv4 address코드가 다른 결과를 표시하는 경우 코드를 검토하여 오류를 찾고 업데이트해야 합니다. 코드를 다시 실행하여 문제가 해결되었는지 확인합니다. 코드가 예상 결과를 생성할 때까지 코드를 계속 업데이트하고 실행합니다.
요약
지금까지 메서드를 사용하는 방법에 대해 배운 내용은 다음과 같습니다.
- 메서드를 사용하여 애플리케이션을 신속하게 구조화할 수 있습니다.
-
return키워드를 사용하여 메서드 실행을 종료할 수 있습니다. - 문제의 각 단계는 종종 자체 메서드로 변환될 수 있습니다.
- 작은 문제를 해결하는 메서드를 사용하여 솔루션 빌드