'수업일지 > C# 문법' 카테고리의 다른 글
24-08-12 11일차 클래스 , random , is, as (0) | 2024.08.12 |
---|---|
24-08-09 10일차 지역,전역변수 , 람다식 ,구조체, enum (0) | 2024.08.09 |
24-08-07 8일차 배열 (0) | 2024.08.07 |
24-08-07 7일차 (0) | 2024.08.06 |
24-08-05 6일차 (0) | 2024.08.05 |
24-08-12 11일차 클래스 , random , is, as (0) | 2024.08.12 |
---|---|
24-08-09 10일차 지역,전역변수 , 람다식 ,구조체, enum (0) | 2024.08.09 |
24-08-07 8일차 배열 (0) | 2024.08.07 |
24-08-07 7일차 (0) | 2024.08.06 |
24-08-05 6일차 (0) | 2024.08.05 |
1. 목표 |
메서드의 이해 및 사용
2. 정의 |
메서드(Method)란 C, C++ 언어에서는 함수(Function)불렸고 약간의 차이는 있겠지만 큰 틀에서 보면 같은 것을 지칭합니다.
c#에서는 메서드로 불리고 한글표기로는 메서드가 맞지만 많은 사람들이 메소드라고 사용하기도 합니다.
메서드는 어떠한 동작을 하는 코드들을 하나의 이름으로 묶어 놓은것이고 이 이름을 호출하여 실행 할수 있습니다.
예) 우리가 앞서 배운 출력을 하기 위한 메서드는 Console.WriteLine();
3. 실습 |
선언 방식
1
2
3
4
5
6
7
8
|
class 클래스 이름
{
[한정자] [반환 형식] [메서드 이름] ( [매개 변수] )
{
//실행 코드
return [반환 형식 결과];
}
}
|
한정자
여기서는 액세스 한정자(public, protected, private)에 대해서만 다루도록 하겠습니다.
액세스 한정자는 말 그대로 우리가 만드는 메서드를 호출할수 있는 권한을 정해 놓는 것입니다.
c#에서는 한정자가 없다면 자동으로 private로 지정됩니다.
public : 공개(누구나 접근하여 사용)
protected : 일부 공개(자신이 만들어진 class 또는 이를 상속 받는 하위 class에서만 사용)
private : 비공개(자신의 class에서만 사용)
반환 형식
void, int, string, class...등 이 메서드의 데이터 반환 형식을 지정할수 있습니다.
반환 형식은 선언된 반환 형식과 동일합니다.
void : 아무것도 반환 할게 없는 경우 return문도 필요하지 않습니다.
int : 코드를 실행하고 마지막에 return뭉으로 int형식의 반환값을 보냅니다.
매개 변수
메서드의 마지막에 붙는 작은 괄호 ( ) 안에 실행 코드에서 사용 될 특정한 데이터를 받을수 있습니다.
매개 변수는 없을수도 여러개 일수도 있습니다.
static
static은 정적메소드로 프로그램이 처음 실행될때 메모리에 자동적으로 생성이 됩니다.
그래서 프로그램의 시작점(main(string[] args))인 main 메서드 또한 static으로 선언되어 있는데
이 정적메소드에서 사용하기위해 예제 및 강좌 에서는 static 한정자를 붙여 사용합니다.
소스 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
using System;
namespace ConsoleApp1
{
class Program
{
static int intPlus (int a, int b)
{
int result = a + b;
return result;
}
static void Main(string[] args)
{
int nPlus = intPlus(10, 20);
Console.WriteLine(nPlus);
}
}
}
|
결과
30 |
위의 코드에서는 intPlus 메서드를 이용하여 int형 매개변수를 두개를 받아들이고 두 매개변수의 합을
리턴하는 메서드를 만들었습니다.
코드의 흐름을 알고 싶으시면 강좌 4편에서 언급한 디버그모드를 활용하여 확인하실수 있습니다.
14번 줄에 중단점을 놓고 F11을 이용해 다른 메서드로 이동하는 것까지 추적하여 볼수 있습니다.
오버로딩
우리가 Console.WriteLine의 메서드를 사용할때 int형이나 string과 같이 여러가지의 매개변수를
넣어 사용 하였는데 만능 메서드처럼 모든 매개변수를 받아들이는 것을 보았습니다.
이는 같은 이름의 메서드지만 매개변수로 받는 인자값을 달리하여 각각 메서드들이 만들어져 있고
실제로 사용할때 같은 메서드지만 매개변수의 형식에 따라 각각 대응을 하게 되는것을
메서드 오버로딩이라 합니다.
소스코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
using System;
namespace ConsoleApp1
{
class Program
{
static int Plus (int a, int b)
{
int result = a + b;
return result;
}
static float Plus(float a, float b)
{
float result = a + b;
return result;
}
static void Main(string[] args)
{
int nPlus = Plus(10, 20);
Console.WriteLine(nPlus);
float fPlus = Plus(1.4f, 2.423f);
Console.WriteLine(fPlus);
}
}
}
|
결과
30 3.823 |
위의 예제 처럼 같은 Plus 메서드 이지만 매개변수를 받는 인자값을 다르게 하여 int형과 float형에
대응 하도록 하였습니다.
매개 변수 전달 방식
매개 변수의 전달 방식은 크게 두가지로 나눌수 있는데 값에 의한 전달(call by value)과
참조에 의한 전달(call by reference)이 있습니다.
쉽게 말해 call by value는 메서드에서 값을 복사하여 전달 받아 사용은 할수 있지만 값의 변경은
하지못하고 call by reference는 해당 값이 있는 주소를 참조하여 전달 받아 값의 변경도 가능한
방법입니다.
소스코드(ref)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
using System;
namespace ConsoleApp1
{
class Program
{
//call by value
static void Plus (int a)
{
a += 323;
}
//call by reference
static void Plus(ref int a)
{
a += 814;
}
static void Main(string[] args)
{
int nA = 17;
Plus(nA);
Console.WriteLine("nA : {0}", nA);
Plus(ref nA);
Console.WriteLine("nA : {0}", nA);
}
}
}
|
결과
nA : 17 nA : 831 |
위의 예제코드에서 call by value는 8번줄의 메서드 처럼 인자 값 앞에 특정 키워드를 사용하지 않고 변수 형식과
변수이름을 넣어 사용하고 call by reference는 13번줄의 메서드처럼 인자 값 앞에 ref라는 키워드를 붙여 사용합니다.
이는 메서드를 호출하여 인자값을 전달 할때도 동일하게 ref 키워드를 짝으로 사용합니다.
call by reference의 키워드는 ref, out, in 세가지가 있습니다. 차이점은 앞서 사용한 ref는 매개 변수를 넘겨주고 받을때 먼저
초기화 해서 사용 하여야 되고 out은 초기화 하지 않아도 사용할수 있습니다. 이때 ref와 동일하게 out도 매개 변수를
넘겨주는 쪽과 받는쪽 둘다 out라는 키워드를 사용해야 합니다.
마지막으로 in은 ref와 out과 참조를 통해 인수를 전달하지만 값에 대한 수정은 불가능 합니다. 이는 매개변수의 안정성을
유지하면서 메서드를 사용할때 매개변수들의 복사본을 만들지 않아 잠재적으로 성능향상에 도움이 됩니다.
※이미 ref, out, in의 참조 형식의 메서드가 오버로드 되어 있는 경우 중복하여 오버로드 하여 사용할수 없습니다.
소스코드(out)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
using System;
namespace ConsoleApp1
{
class Program
{
static void Plus (out int a)
{
a = 777;
}
static void Main(string[] args)
{
int nA;
Plus(out nA);
Console.WriteLine("nA : {0}", nA);
}
}
}
|
결과
nA : 777 |
소스코드(in)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
using System;
namespace ConsoleApp1
{
class Program
{
static void Plus (in int a)
{
//아래와 같이 값에 대한 수정은 오류발생
//Uncomment the following line to see error CS8331
//a = 19;
Console.WriteLine(a + 111);
}
static void Main(string[] args)
{
int nA = 777;
Plus( nA);
}
}
}
|
결과
888 |
※만약 c#버전에 의한 오류가 발생한다면 아래 이미지 참고
params
배열 형태의 매개변수를 사용지정 할수 있습니다.
일반적인 배열의 형태 뿐만 아니라 여러가지의 매개 변수들을 받을수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
using System;
namespace ConsoleApp1
{
class Program
{
static void Plus (params object[] obj)
{
for (int i = 0; i < obj.Length; i++)
{
Console.Write("obj[{0}] : {1}", i, obj[i]);
Console.WriteLine();
}
}
static void Main(string[] args)
{
object[] objArray = { 777, 888, 'k', "test"};
Plus(objArray);
}
}
}
|
결과
obj[0] : 777 obj[1] : 888 obj[2] : k obj[3] : test |
C# 람다식과 델리게이트 (1) | 2024.08.09 |
---|---|
c# 메서드(1) (0) | 2024.08.07 |
c# 배열의 선언과 초기화방법 (0) | 2024.08.07 |
c# 배열뒤집기 (0) | 2024.08.07 |
c# 배열 - array, list (0) | 2024.08.07 |
24-08-09 10일차 지역,전역변수 , 람다식 ,구조체, enum (0) | 2024.08.09 |
---|---|
24-08-09 9일차 함수/메서드/재귀함수/overload (0) | 2024.08.08 |
24-08-07 7일차 (0) | 2024.08.06 |
24-08-05 6일차 (0) | 2024.08.05 |
24-08-03 5일차 (0) | 2024.08.02 |
프로그램을 만들다보면 중복해서 사용되는 기능들이 나오게되고
이걸 죄다 복붙을 통하여 해결하다보면 코드가 지저분해지고 길어지게 된다.
C#에서는 이러한 기능을 묶어 재사용할수있도록 일종의 모듈화가 가능한데
그것이 바로 메소드(함수)이다
C++ 강의자료 복붙이라 이후부터는 함수라 칭하도록 하겠다.
1.함수란
특정한 기능을 수행하도록 나눠진 작업 단위,
수학에서의 함수와 비슷한 의미를 가진다.
C# 에서 함수는 다음과 같은 구조를 가진다
<리턴타입> <함수이름> (<매개변수>)
{
<함수 본문(내용)>
return <리턴값>;
}
리턴타입은 돌려주는 리턴값이 어떤 변수 타입인지를 의미하고
매개변수느느 해당 함수에 넘겨줄 값을 의미한다.
위 구조대로 들어온 값에 1을 더하는 기능을 하는 함수를 만들어보면
다음과 같다.
대충 이러한 구조를 띄는데
사용하기 전에
과 같이 static을 앞에 붙여주도록 하자.
static은 정적 함수를 만드는것으로 객체가 아닌 클래스에 따라 작동하는 함수인데..
객체지향을 배우기 전이므로 그냥 일단 적어주도록 하자.
함수를 사용할때는 함수이름(매개변수)와 같이 사용하며 이를 함수를 호출한다고 한다.
위 함수를 사용한다고하면
int a = plusOne(10);
을 하면 plusOne 함수에 10이 매개변수로 들어가고 11이 리턴되며
11은 그 함수가 호출된 자리로 돌아간다.
즉 int a = 11이 되고 a는 11이 된다.
함수를 만드는 방법을 알았으니
두숫자를 더하는 함수를 만들어보자
해당 함수의 동작과정은 다음과 같다.
1. 함수의 인자값으로 x,y가 들어간다 x,y값은 각각 10과 5 이므로
Plus(10,5)와 같다.
2. 인자값이 전달된다.
이제 Plus함수에서 x는 10, y는 5이다.
3. 해당 인자값을 사용하여 함수 내용을 실행한다.
출처: https://see-ro-e.tistory.com/100 [SeeRoE 프로그래밍 기록:티스토리]
C# 람다식과 델리게이트 (1) | 2024.08.09 |
---|---|
C# 메서드(2) (0) | 2024.08.08 |
c# 배열의 선언과 초기화방법 (0) | 2024.08.07 |
c# 배열뒤집기 (0) | 2024.08.07 |
c# 배열 - array, list (0) | 2024.08.07 |
C#에서 가변 배열(Jagged Array)은 배열의 배열입니다. 각 배열의 길이는 달라질 수 있으며,
2차원 배열과는 다르게 비정형 구조를 가질 수 있습니다.
1. 가변 배열 (Jagged Array)
가변 배열은 배열의 배열로, 배열의 각 요소가 배열 자체를 가리킵니다. 따라서 각 행의 길이가 달라질 수 있습니다.
가변 배열 선언 및 초기화
가변 배열을 선언하고 초기화하는 방법은 다음과 같습니다:
두가지 방법으로 선언이 가능합니다
가변 배열에 접근하는 방법: for 문과 foreach 문
가변 배열의 각 요소에 접근하는 방법은 for 문과 foreach 문을 사용할 수 있습니다.
for문과 foreach문으로 접근 가능합니다!
C#의 가변 배열(Jagged Array)에는 GetLength 메서드를 사용할 수 없습니다.
이는 GetLength 메서드가 다차원 배열(Multidimensional Array)에서만 사용 가능하기 때문입니다.
대신 가변 배열에서는 각 배열의 길이를 개별적으로 확인해야 합니다.
대신 Length를 사용해서 총 길이를 구하고 각 배열의 길이까지도 쉽게 구할 수 있습니다!
예제 코드
가변 배열을 선언, 초기화하고 for 문과 foreach 문을 사용하여 요소에 접근하는 예제 코드를 작성해보겠습니다.
이 예제에서는 가변 배열을 선언하고 초기화한 후, for 문과 foreach 문을 사용하여 각 요소를 출력합니다.
for 문은 인덱스를 사용하여 각 요소에 직접 접근하고, foreach 문은 배열의 각 요소를 순서대로 처리합니다.
가변 배열은 각 배열의 길이가 다를 수 있으므로, 각 행을 개별적으로 처리하는 데 유용합니다!
코드가 길때 접는법 #region 과 #endregion (0) | 2024.08.29 |
---|---|
C# Random이용해서 rotto 생성 (0) | 2024.08.12 |
C# Date Time 구조체 (0) | 2024.08.09 |
int.Parse vs int.TryParse vs Convert.ToInt32 차이 (0) | 2024.07.30 |
1. C# 배열의 선언 초기화 사용방법 (Array)
-> 배열이란 ?
: 배열이란 관련있는, 비슷한 데이터를 효과적으로 관리하기 위한 자료구조입니다.
: 배열을 이용하면 연관되어있는 데이터들을 for문과 결합하여 손쉽게 순회 할 수 있습니다.
-> C#에서의 배열 선언 방법
(0) 기본 모양
- 자료형[] 변수이름 = new 자료형[N] { 초기화 하거나 안하거나};
(1) 배열의 요소 개수를 지정하고 선언과 동시에 초기화 하는 방법
- int[] arr1 = new int[5] { 11, 12, 13, 14, 15 };
- 위 코드를 보면 new int[N] 대괄호 사이에 배열의 사이즈를 N으로 지정하고, 초기화 까지 하는 것을 볼 수 있습니다.
(2) 배열의 요소 개수를 지정하지 않고 선언과 동시에 초기화 하는 방법
- int[] arr1 = new int[] { 11, 12, 13, 14, 15 };
- 위 코드를 보면 new int[] 대괄호 사이에 배열의 사이즈를 지정하지 않고, 초기화 까지 하는 것을 볼 수 있습니다.
(3) 배열의 요소 개수를 지정하고, 추후에 배열의 인자들을 초기화 하는 방법
-
int[] arr3 = new int[5]; for(int i=0; i<5; ++i)
{
arr3[i] = i + 11;
}- 위 코드를 보면 배열의 사이즈를 N으로 지정해 놓고 나중에 반복문 for를 이용하여 배열의 값을 초기화 하는 것을 볼 수 있습니다.
-> 배열의 생김새와 접근 방법- 위에서 선언한 배열을 보면 컴퓨터에 아래와 같이 저장이 됩니다.
- 이렇게 메모리에 순서대로 값들이 저장이 됩니다.
- 배열에 저장한 값에 접근을 하기위해서 우리는 index라는 것을 이용할 것인데요.
- "배열의이름[index]"을 이용하여 접근을 할 것입니다. 위에서 보시는바와 같이 index는 0부터 시작해서 N-1번 까지 존재합니다. 즉 여기서 사이즈가 5인 배열을 선언을 했으면 index는 0, 1, 2, 3, 4 까지 존재할 수 있는 것 입니다.
-> 실제 코드에서 배열을 사용해보자.- 보통 배열의 필요성을 이야기하면서, 배열에 대한 예시를 들때 보통 시험 점수를 이야기 합니다.- 예를들어 배열을 사용하지 않고 '국어' '영어' '수학' '과학' '역사' 점수를 입력하고 평균을 출력한다고 하면. 아래와 같을 것 입니다.1) 배열을 사용하지 않았을때,
1
2
3
4
5
6
7
8
9
10
11
12
|
static void Main(string[] args)
{
int korean = 60;
int english = 50;
int math = 90;
int science = 80;
int history = 30;
int sum = korean + english + math + science + history; //여기!
float average = average = sum / 5;
Console.WriteLine("평균 : " + average);
}
|
cs |
: 이렇게 배열을 사용하지 않았을때 평균을 구한다고 하면, 모든 과목을 더해야하는 상황이 오게 됩니다. 이때 저렇게 모든 과목들을 일일히 더해주는 방법이 과연 효율적일까요?
: 만약에 과목이 10개 20개 100개 라고 하면.... 누가 저렇게 노가다로 코드를 짜고싶을까요?
2) 배열을 사용했을때.
1
2
3
4
5
6
7
8
9
10
11
12
|
static void Main(string[] args)
{
int[] scoreArr = new int[] { 60, 50, 90, 80, 30 };
int sum = 0;
for (int i = 0; i < 5; ++i)
{
sum += scoreArr[i];
//배열은 "변수명[index]"를 통해 접근합니다.
}
float average = average = sum / 5;
Console.WriteLine("평균 : " + average);
}
|
cs |
: 이렇게 배열을 사용하게되면, for문을 이용해서 한번에 해결 할 수 있습니다.
3) 결과
- 결과는 동일합니다
2. C# 다차원 배열의 선언과 사용방법 (Multi-dimensional Arrays)
-> 다차원 배열이란?
: 2차원 배열은 1차원 배열이 n개가 있는것이고
: 3차원 배열은 2차원 배열이 m개가 있는 것이라 생각하면 됩니다.
: 게임같은데서는 5x5 같은걸 이용해서 빙고판? 같은걸 생각하거나
: 위에서 예를 들었던 성적표를 철수 성적표, 영희 성적표 해서 똑같은게 두세개 있다고 생각하면 됩니다.
-> C#에서 다차원 배열 선언방법
(0) 기본 모양
- 자료형 [ , , ...] 변수이름 = new 자료형[ , , ...] { 초기화 하거나 안하거나};
(1) 2차원 배열 - 선언과 동시에 초기화 하기
- int [ , ] arr1 = new int[2,3] { {31, 32, 33}, {34, 35, 36} };
- 빨간색으로 표시한 수를 보고 말씀을 드리면 "사이즈가 3인 1차원 배열이 2개"가 존재한다. 라고 보면됩니다.
- 자세한 것은 아래 사용법을 보시면됩니다.
(2) 2차원 배열 선언방법 - 선언 후에 초기화 하기.
- int[,] arr1 = new int[2, 3];
int num = 30;
for (int i = 0; i < 2; ++i)
{
for(int j=0; j<3; ++j)
{
arr1[i, j] = num + 1;
}
}
- 이런 방식으로도 사용할 수 있습니다.
(3) 3차원 배열도 비슷하게 선언하면 됩니다. (n차원 배열도 마찬가지 입니다.)
- int [, ,] arr3 = new int[2,3,4];
-> 2차원 배열의 생김새와 접근방법
- 위에서 선언 후 초기화한 배열을 보면 아래와 같습니다.
- 실제 메모리에서는 2차원 배열이라 하더라도 연속적으로 저장이 됩니다만, 사람이 보기 편하게 아래와 같이 표현을 합니다.
- 배열에 접근하는 방법은 1차원 배열과 마찬가지로 index를 이용해서 접근하는데 2차원 배열이기 때문에 index가 두개가 있습니다.
- arr[n, m] 입니다. 우리가 위에서 배열을 선언하길 arr[2,3]으로 선언을 했기 때문에
: n의 범위는 0~2 이고
: m의 범위는 0~3 입니다.
- 실제로 코드에서 2차원 배열의 값에 접근할때는 arr[0,1] 이런식으로 접근하며 이중 for문을 이용해서 많이 접근합니다.
-> 2차원 배열 코드 예제
- 철수와 영희의 중간고사 평균을 구해야하는 코드를 작성해야 한다면,
- 철수와 영희는 2명이고 과목은 각각 5개 씩이라 생각해봅니다.
1) 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
static void Main(string[] args)
{
int[,] arrScore = new int[2, 5] { { 90, 80, 70, 42, 30 },
{24, 50, 100, 52, 70} };
int[] arrSum = new int[2] { 0, 0 };
//arrSum 배열에 철수와 영희의 시험점수의 합을 넣습니다.
//arrSum[0] 철수
//arrSum[1] 영희
for(int n=0; n<2; ++n)
{
for(int m=0; m<5; ++m)
{
arrSum[n] += arrScore[n, m];
}
}
//평균을 출력합니다.
for(int i=0; i<2; ++i)
{
float average = arrSum[i] / 5;
Console.WriteLine("평균[" + i + "] : " + average);
}
}
|
cs |
: 위처럼 2차원 배열을 이용해서 철수와 영희의 성적을 표현해 보았고, 평균까지 구했습니다.
: 또한 2중 반복문을 이용해서 2차원 배열을 순회하는것을 확인할 수 있습니다.
2) 결과
3. C# 가변 배열의 선언과 사용 방법 (Jagged array)
(와 드디어 가변배열이네요, 사실 가변 배열때문에 C#의 배열을 포스팅 한건데 글을 쓰다보니 위에설명이 길어졌네요. 부디 도움이 되었길 희망합니다.)
-> 가변배열이란 ?
: 다차원 배열과 비슷하지만 비슷하지 않은 그런 썸과 같은 배열입니다.
: 기본 가변배열을 생각하면 길이가 다양한 1차원 배열들을 가지고 있는 배열이라고 생각하면 됩니다.
: 막대그래프를 눕혀둔 느낌이랄까요?
: 보통 "배열의 배열"이라는 표현을 합니다.
-> C#에서 가변배열을 선언하는 방법
(1) 가변배열의 기본 모양
- 자료형 [][] 변수이름 new 자료형[N][];
: 위와 같으며, N은 1차원 배열들의 개수를 말하고 뒤의 대괄호는 표기하지 않습니다.
: 그 이유는 1차원 배열의 길이가 다 다르기 때문에 표기할 수 없기 때문입니다.
(2) 가변배열을 선언과 동시에 초기화 하는 방법.
- int [][] jaggedArr = new int[3][]
{
new int[] {31, 32, 33},
new int[] {41, 42, 43, 44, 45, 46, 48, 70, 71, 72, 74, 76},
new int[] {0, 1, 5, 7, 2, 1}
};
- 위와 같은 방법로 가변배열을 선언과 동시에 초기화를 할 수 있습니다.
(3) 가변배열을 선언 후에 따로 초기화 하는 방법.
- int [][] jaggedArr = new int[3][];
- 위와 같이 정의를 한 후에 아래 코드처럼 따로따로 초기화를 해줍니다.
- jaggedArr[0] = new int[] {31, 32, 33};
- jaggedArr[1] = new int[] {41, 42, 43, 44, 45, 46, 48, 70, 71, 72, 74, 76};
- jaggedArr[2] = new int[] {0, 1, 5, 7, 2, 1};
(4) 다차원 배열을 가지고 있는 가변 배열을 선언과 동시에 초기화 하는 방법
- 만약에 2차원 배열을 가지고 있는 가변배열을 선언해주고 싶다면, 아래와 같이 하시면 됩니다.
(복잡하네요)
- int [][ , ] jaggedArr2 = new int[3][ , ]
{
new int[ , ] { { 31, 32} , {33, 34}, {35, 36} },
new int[ , ] { { 1, 2, 3, 4} , {5, 6, 7, 8} },
new int[ , ] { { 11, 12, 13, 14}, {15, 16, 17, 18}, {19, 20, 21, 22}, {23,24,25,26} }
};
(5) 다차원 배열을 가지고 있는 가변 배열을 선언하고, 따로 초기화 하는 방법
- 2차원 배열을 가지고 있는 가변배열을 선언해보겠습니다.
- int [][ , ] jaggedArr2 = new int[3][ , ];
- jaggedArr2[0] = new int[,] { { 31, 32 }, { 33, 34 }, { 35, 36 } };
- jaggedArr2[1] = new int[,] { { 1, 2, 3, 4 }, { 5, 6, 7, 8 } };
- jaggedArr2[2] = new int[,] { { 11, 12, 13, 14 }, { 15, 16, 17, 18 }, { 19, 20, 21, 22 }, { 23, 24, 25, 26 } };
-> C#의 가변 배열 사용법 및 생김새
- int [][] jaggedArr = new int[3][]
{
new int[] {31, 32, 33},
new int[] {41, 42, 43, 44, 45, 46, 48, 70, 71, 72, 74, 76},
new int[] {0, 1, 5, 7, 2, 1}
};
- 위 가변배열의 의 모습을 한번 눈에 띄게 표현을 해보면, 아래와 같습니다.
- 이렇게 jaggedarr[n] 은 각각의 1차원 배열을 가리키며, jaggedarr[n][m]은 n번째 배열의 m번째 인덱스를 말합니다.
-> C# 가변배열 예제.
(1) 소스코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
static void Main(string[] args)
{
//가변배열 선언과 초기화
int[][] jaggedArr = new int[3][]
{
new int[] {31, 32, 33},
new int[] {41, 42, 43, 44, 45, 46, 48, 70, 71, 72, 74, 76},
new int[] {0, 1, 5, 7, 2, 1}
};
//가변배열 출력
for(int i=0; i<3; ++i)
{
Console.Write("jaggedArr[" + i + "] : ");
int size = jaggedArr[i].Length; //각 1차원 배열의 길이
for (int j = 0; j < size; ++j)
{
Console.Write(jaggedArr[i][j] + " ");
}
Console.WriteLine(); //한줄 띄어쓰기.
}
}
|
cs |
: 위 코드와 같은 방법으로 가변배열을 선언과 초기화를 할수 있습니다.
: "배열.Lengh"를 이용해서 원하는 인덱스에 해당하는 배열의 길이를 가지고 와서 그 길이만큼 각 배열의 값을 출력합니다.
(2) 결과
마지막으로 한번 더 강조하자면,2차원배열에서의 접근방법은 arr[1, 2] 이고,가변배열에서의 접근방법은 arr[1][2] 입니다.
+++++++++++
GetLength()를 이용해 array배열 길이 확인가능
에게 제자리에서 지정된 어레이 내에서 요소의 순서를 반대로 하면 다음을 사용할 수 있습니다. Array.Reverse() 방법. 솔루션은 보조 어레이을 사용하지 않고 지정된 어레이의 기존 요소를 덮어쓰는 방식으로 작동합니다.
다음 예에서는 어레이의 값을 반대로 하는 방법을 보여줍니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
using System;
public class Example
{
public static void Main()
{
int[] array = { 2, 4, 6, 8 };
Array.Reverse(array);
Console.WriteLine(String.Join(',', array));
}
}
/*
결과: 8,6,4,2
*/
|
원래 어레이의 역 복사본을 생성하려면 다음을 사용할 수 있습니다. Enumerable.Reverse() 방법. 기본 어레이을 수정하지 않고 역순으로 요소가 있는 새 시퀀스를 생성합니다. 다음 코드 예제에서는 다음을 사용하여 어레이을 반전합니다. Reverse() 방법.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
using System;
using System.Linq;
public class Example
{
public static void Main()
{
int[] array = { 2, 4, 6, 8 };
int[] reverse = Enumerable.Reverse(array).ToArray();
Console.WriteLine(String.Join(',', reverse));
}
}
/*
결과: 8,6,4,2
*/
|
또 다른 솔루션은 입력 어레이과 동일한 유형 및 크기의 새 어레이을 만들고 소스 어레이의 요소를 역순으로 채운 다음 새 어레이의 내용을 소스 어레이에 복사하는 것입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
using System;
public static class Extensions
{
public static void reverse<T>(this T[] array)
{
int n = array.Length;
T[] aux = new T[n];
for (int i = 0; i < n; i++) {
aux[n - 1 - i] = array[i];
}
for (int i = 0; i < n; i++) {
array[i] = aux[i];
}
}
}
public class Example
{
public static void Main()
{
int[] array = { 2, 4, 6, 8 };
array.reverse();
Console.WriteLine(String.Join(',', array));
}
}
/*
결과: 8,6,4,2
*/
|
위의 구현에는 다음이 필요합니다. O(n) 보조 어레이를 위한 추가 공간. 아래와 같이 어레이을 제자리에서 수정하여 이를 방지할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
using System;
public class Example
{
private static void swap(int[] array, int i, int j)
{
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
public static void Main()
{
int[] array = { 2, 4, 6, 8 };
int n = array.Length;
for (int i = 0; i < n/2; i++) {
swap(array, i, n-i-1);
}
Console.WriteLine(String.Join(',', array));
}
}
/*
결과: 8,6,4,2
*/
|
c# 메서드(1) (0) | 2024.08.07 |
---|---|
c# 배열의 선언과 초기화방법 (0) | 2024.08.07 |
c# 배열 - array, list (0) | 2024.08.07 |
c# 반복문 (0) | 2024.08.06 |
c# 조건문 (0) | 2024.08.06 |
배열의 선언 방법은 데이터 형태[], 변수명, 테이터 형태의 길이로 표현됩니다. 접근방법은 배열의 인덱스로 각 데이터에 접근할 수 있으며 변수와 동일하게 각 변수의 값은 변경할 수 있습니다. 일반 변수와 배열을 비교하면서 배열의 선언 방법과 값 할당 방법을 알아보겠습니다.
아래 코드는 정수 형태의 값을 7개 저장할 수 있는 배열을 numbers라는 이름으로 선언하는 내용입니다.
int[] numbers = new int[7];
아래는 비교를 위해 일반 정수 변수를 7개 선언 방법입니다.
int number1, number2, number3, number4, number5, number6, number7;
두 가지 방법을 비교해 보면 어떤 게 더 편한지 이야기할 것도 없습니다. 예시에서 보시는 7개의 정수는 일일이 선언해도 큰 차이가 없지만 만약 정수가 100개라면 엄청난 차이가 있습니다.
아래 코드는 선언된 배열에 값을 할당하는 코드입니다. 각 정수 값에 인덱스 넘버를 이용해 할당하는데 인덱스 넘버는 0부터 시작됩니다. 예시에서 7개의 정수배열을 선언했으니 사용 가능한 인덱스 번호는 0부터 6까지 7개의 인덱스입니다.
numbers[0] = 0;
numbers[1] = 1;
numbers[2] = 2;
numbers[3] = 3;
numbers[4] = 4;
numbers[5] = 5;
numbers[6] = 6;
아래는 비교를 위한 일반 정수 변수의 값 할당 방법입니다.
number1 = 0;
number2 = 1;
number3 = 2;
number4 = 3;
number5 = 4;
number6 = 5;
number7 = 6;
두 가지 값 할당 방법은 차이가 없습니다. 선언부와 마찬가지로 몇 개 안 되는 변수는 일일이 할당 가능하지만 변수의 수가 많은 경우 입력 자체가 고통입니다. 이런 경우 효율적인 값 할당을 위해 이전 시간에 배운 반복문을 배열과 함께 사용합니다.
for문을 사용해서 값을 입력하는 코드입니다.
int[] numbers = new int[7];
// 선언된 배열에 .Length는 배열의 길이값 입니다.
// 여기서 numbers는 길이가 7로 선언되었기 때문에
// numbers.Length는 7로 치환하여 해석하면 됩니다.
for(int i=0; i < numbers.Length; i++)
{
numbers[i] = i;
}
numbers.Length가 7로 치환되어 위의 for문은 아래의 코드와 100% 동일한 코드입니다.
int[] numbers = new int[7];
for(int i=0; i < 7; i++)
{
numbers[i] = i;
}
코드는 i변수가 0부터 반복하여 6이 될 때까지 총 7회 반복되며 매번 명령 블록 내에서 배열의 0부터 6번 인덱스에 접근해서 i 값을 할당합니다.
아래는 배열의 선언과 동시에 값을 할당하는 코드입니다. for 반복문에서는 각인 덱스에 접근해서 할당된 값을 출력합니다.
int[] numbers = new int[] {0, 1, 2, 3, 4, 5, 6};
for(int i=0; i < numbers.Length; i++)
{
Console.WriteLine(numbers[i]);
}
이제 배열의 개념에 추가로 리스트에 대한 내용을 알아보겠습니다. 배열과 리스트의 메모리 구조는 내부적으로 복잡하지만 차이점을 작동 관점에서 단순하게 이야기해서 배열은 길이가 예측이 가능할 때 사용하고 리스트는 불가능할 때 사용합니다. 배열은 선언할 때 길이를 정하지만 리스트는 배열과는 다르게 데이터의 길이를 가변적으로 사용할 수 있는 것이 가장 큰 특징이자 차이점입니다. 여기서는 리스트의 간략한 기능만 설명하고 자세한 내용은 다음 포스팅인 함수 설명에 추가하여 설명하겠습니다.
일단 List를 사용하기 위해서는 using System.Collections.Generic; 구문으로 네이스 페이스를 추가해야 합니다.
using System;
using System.Collections.Generic;
선언은 아래와 같습니다. 리스트는 <> 표기 안에 들어가는 데이터 형태를 기준으로 생성되며 numbersList를 통해 정해진 데이터 형태를 언제든지 저장했다 지웠다 할 수 있습니다.
List<int> numbersList = new List<int>();
리스트에 값을 추가하거나 삭제할 때 함수를 이용하는데 아직 배우지 않은 내용이니 여기서는 값을 추가하는 기능 Add(), 삭제하는 RemoveAt() 기능만 설명하겠습니다.
아래는 1항에서 사용되었던 예시를 리스트로 변경하여 작성한 코드입니다. 배열은 인덱스를 통한 변수에 접근하여 값을 할당하는 개념이었고 리스트의 경우는 마치 바구니에 숫자를 Add()라는 기능으로 추가하는 개념입니다.
using System;
using System.Collections.Generic;
namespace Program
{
class Program
{
static void Main(string[] args)
{
List<int> numbersList = new List<int>();
for(int i=0; i < 7; i++)
{
// 리스트에 정수 저장공간과 값할당이 동시에 이루어진다.
// Add() 함수에 인자로 정수를 전달한다.
numbersList.Add(i);
}
// 데이터 추가 후 numbersList의 길이는 7이 되었다.
Console.ReadKey();
}
}
}
리스트도 인덱스의 개념이 있습니다. 추가된 순서대로 인덱스 번호가 부여된다고 생각하면 됩니다. 실제로 리스트에 있는 데이터를 액세스 할 때 배열과 동일한 문법으로 사용할 수 있습니다. 다만 리스트의 데이터 공간은 추가와 삭제는 리스트 기능으로만 가능합니다. 아래는 이해를 위해 코드를 추가한 예시 코드입니다.
using System;
using System.Collections.Generic;
namespace Program
{
class Program
{
static void Main(string[] args)
{
List<int> numbersList = new List<int>();
// numbersList에 정수 0 부터 6까지 순차적으로 입력한다.
for(int i=0; i < 7; i++)
{
numbersList.Add(i);
}
// numbersList에 0번인덱스의 저장공간과 값을 동시에 삭제한다.
numbersList.RemoveAt(0);
// numbersList의 길이만큼 반복하며 각 인덱스에 저장된 정수값을 출력한다.
for(int i=0; i < numbersList.Count; i++)
{
Console.WriteLine(numbersList[i]);
}
Console.ReadKey();
}
}
}
아래는 이전 포스팅에서 배우지 못한 마지만 반복 문법인 foreach와 for문의 차이점 비교표 입니다. foreach는 처음부터 끝까지 별도의 처리가 필요 없고 동일한 작업을 지시할 때 사용되는 반복문입니다. foreach의 () 안의 내용은 각 배열이나 리스트를 이루고 있는 데이터 형태 - 변수 이름 - in키워드 - 배열 or리스트 형태로 되어있고 명시한 변수 이름을 기준으로 명령 블록에서 각 요소별로 명령을 실행하는 구조입니다. 추가로 배열의 길이는 배열.Length로 사용했지만 리스트는 .Count로 길이를 읽어 올 수 있습니다.
for 문법 | foreach 문법 |
|
c# 배열의 선언과 초기화방법 (0) | 2024.08.07 |
---|---|
c# 배열뒤집기 (0) | 2024.08.07 |
c# 반복문 (0) | 2024.08.06 |
c# 조건문 (0) | 2024.08.06 |
c# 두 변수의 값 바꾸기(Swap) (0) | 2024.08.01 |
class Program
{
static void Main(string[] args)
{
// for 루프
for (int i = 0; i < 10; i++)
{
Console.WriteLine("Loop {0}", i);
}
}
}
static void Main(string[] args)
{
string[] array = new string[] { "AB", "CD", "EF" };
// foreach 루프
foreach (string s in array)
{
Console.WriteLine(s);
}
}
static void Main(string[] args)
{
// 3차배열 선언
string[,,] arr = new string[,,] {
{ {"1", "2"}, {"11","22"} },
{ {"3", "4"}, {"33", "44"} }
};
//for 루프 : 3번 루프를 만들어 돌림
for (int i = 0; i < arr.GetLength(0); i++)
{
for (int j = 0; j < arr.GetLength(1); j++)
{
for (int k = 0; k < arr.GetLength(2); k++)
{
Debug.WriteLine(arr[i, j, k]);
}
}
}
//foreach 루프 : 한번에 3차배열 모두 처리
foreach (var s in arr)
{
Debug.WriteLine(s);
}
}
static void Main(string[] args)
{
int i=1;
// while 루프
while (i <= 10)
{
Console.WriteLine(i);
i++;
}
}
static void Main(string[] args)
{
int i=1;
// do ~ while 루프
do
{
Console.WriteLine(i);
i++;
} while (i < 10);
}
using System;
using System.Collections.Generic;
namespace MySystem
{
class Program
{
static void Main(string[] args)
{
List<char> keyList = new List<char>();
ConsoleKeyInfo key;
do
{
key = Console.ReadKey();
keyList.Add(key.KeyChar);
} while (key.Key != ConsoleKey.Q); // Q가 아니면 계속
Console.WriteLine();
foreach (char ch in keyList) // 리스트 루프
{
Console.Write(ch);
}
}
}
}
c# 배열뒤집기 (0) | 2024.08.07 |
---|---|
c# 배열 - array, list (0) | 2024.08.07 |
c# 조건문 (0) | 2024.08.06 |
c# 두 변수의 값 바꾸기(Swap) (0) | 2024.08.01 |
c# + 연산의 추가기능 (0) | 2024.08.01 |
int a = -11;
if (a>=0)
{
val = a;
}
else
{
val = -a;
}
// 출력값 : 11
Console.Write(val);
switch (category)
{
case "사과":
price = 1000;
break;
case "딸기":
price = 1100;
break;
case "포도":
price = 900;
break;
default:
price = 0;
break;
}
using System;
namespace MySystem
{
class Program
{
static bool verbose = false;
static bool continueOnError = false;
static bool logging = false;
static void Main(string[] args)
{
if (args.Length != 1)
{
Console.WriteLine("Usage: MyApp.exe option");
return;
}
string option = args[0];
switch (option.ToLower())
{
case "/v":
case "/verbose":
verbose = true;
break;
case "/c":
continueOnError = true;
break;
case "/l":
logging = true;
break;
default:
Console.WriteLine("Unknown argument: {0}", option);
break;
}
}
}
}
c# 배열 - array, list (0) | 2024.08.07 |
---|---|
c# 반복문 (0) | 2024.08.06 |
c# 두 변수의 값 바꾸기(Swap) (0) | 2024.08.01 |
c# + 연산의 추가기능 (0) | 2024.08.01 |
c# 연산자 (0) | 2024.08.01 |