1. 접근 제한자
1-1. 접근 제한자의 종류와 설명
public 모든 곳에서 해당 클래스에 접근이 가능
private 클래스 내부에서만 접근 가능
internal 같은 어셈블리 내에서만 public 으로 접근 가능
protected 클래스의 외부접근은 불가능하나 파생된 클래스에서는 가능
protected internal 같은 어셈블리 내에서만 protected 로 접근 가능

2. 접근제한자의 각 예시

 

2-1. public
namespace ConsoleApp1
{
    public class Student
    {
        public String name;
        public int age;

        public void show()
        {
            Console.WriteLine($"{this.name}학생은 올해로 {this.age}세 입니다.");
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            Student student1 = new Student();
            student1.name = "김이박";
            student1.age = 20;
            student1.show();

        }
    }
}

public 접근제한자는 Program 클래스와는 다른 클래스임에도 불구하고

무리없이 접근하여 사용가능한 것을 볼 수 있습니다. 


2-2. private 

이번에는 class는 접근제한자를 표기하지않고 필드에는 private를 직접 작성해보겠습니다.

(private는 C#의 default 접근제한자로 만약 필드의 접근제한자에 아무것도 적지않으면 자동으로 private임.)

namespace ConsoleApp1
{
    class Student
    {
        private String name;
        private int age;
        
        public void show()
        {
            Console.WriteLine($"{this.name}학생은 올해로 {this.age}세 입니다.");
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            Student student1 = new Student();
            student1.name = "김이박";
            student1.age = 20;
            student1.show();

        }
    }
}

이렇게 작성하니 뭔가 에러가 뜨는것을 확인할 수 있는데요

바로 이러한 에러가 나옵니다. '보호수준' 때문에 필드에 접근할 수 없다는 이야기도 함께 나오네요.

위에 설명과 같이 private 접근제한자는 같은 클래스 내부에서만 사용이 가능합니다.

그렇다면 같은 클래스 내부에서만 접근이 가능하다면

우리는 main영역에 다 적어주는 것과 다를 바 없는 불편한 사용을 계속 하게될까요?

아닙니다. 우리는 이러한  private필드에 public 메서드 라는 구멍을 뚫어 접근할 수 있도록 해볼 것 입니다.

이때 필요한 것이 this 인데요. 


this ?  저번 강의에도 조금 언급했듯이 this 속성은 클래스 내부의 필드 자신을 직접 가리키는 것입니다.
이를 이해하기쉽도록 예시를 사용하겠습니다.

namespace ConsoleApp1
{
    class Student
    {
        private String name;
        private int age;
        
        public String getName()
        {
            return name;
        }
        public void setName(String name)
        {
            this.name = name;
        }

        public int getAge(int age)
        {
            return age;
        }
        public void setAge(int age)
        {
            this.age = age;
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            Student student1 = new Student();
            student1.name = "김이박";
            student1.age = 20;
            student1.show();

        }
    }
}

여러가지 메소드가 추가되었습니다.

잘 보시면 this.name = name , this.age=age 라는 부분을 보실 수 있는데요.

이 부분은 그림으로 설명드리면

이렇게 사용되고 있는 것입니다.

this.name은 필드를 가리키고

name은 들어오는 매개변수를 가리키는 것입니다.

즉 이를 해석하면

필드(name) 에 메서드에 입력되는 매개변수를 담는다.

라고 보시면 됩니다.

두 변수의 이름이 같으니 이를 나누어주는 역할을 하기도 합니다!

 

 

 

 

 

 

이러한 부분의 사용까지 예시를 본면

namespace ConsoleApp1
{
    class Student
    {
        private String name;
        private int age;
        
        public String getName()
        {
            return name;
        }
        public void setName(String name)
        {
            this.name = name;
        }

        public int getAge()
        {
            return age;
        }
        public void setAge(int age)
        {
            this.age = age;
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            Student student1 = new Student();

            student1.setName("김이박");
            student1.setAge(20);

            Console.WriteLine($"{student1.getName()} 학생은 올해로 {student1.getAge()}입니다.");
            Console.WriteLine();
        }
    }
}
  • 생성자를 만든다
  • 생성자를 통해 set메서드를 사용한다.
  • 사용된 set메서드를 통해 만들어진 필드를 get메서드를 통해 가져온다.

이렇게 사용하는 것입니다. 사실 getter setter 메서드는 자바에서 흔히 사용되는 개념인데요.

C#은 자바와 통하는 부분이 많아서 이렇게 사용할 수 있다는 것을 빼와보았습니다.


2-3. protected

protected 접근제한자는 '파생된' 클래스에서만 사용이 가능하다.

위 '파생된' 이라는 부분은 굉장히 핵심적인 설명입니다.

우리가 지금까지 사용했던 class들은 각자 다른 부분을 적어두고 끌어와서 사용한다는 느낌이 강합니다.

하지만 protected의 경우 class A에서 파생된 class B에서 class A를 사용할 수 있다.  즉 클래스 B에 클래스 A 전체를 담는다는 느낌이 강하죠.

예시를 사용해서 이해를 도와보겠습니다.

아래의 예는 상속이며 이는 추후 설명하겠습니다.

namespace ConsoleApp1
{
    class Student
    {
        protected char student1 = 'A';
    }


    class A_class : Student
    {
        static void Main(string[] args)
        {
            Student st_a = new Student();
            A_class a_cl = new A_class();

            st_a.student1 = 'B'; //class Student에 student1은 protected 접근제한자이다.
                                 //따라서 Student 클래스의 파생된 클래스 A_class 에서만 
                                 //접근이 가능하다.

        }
    }
}

위 코드를 보시면 타이핑과 동시에 표시부분에 에러가 나옵니다. 아래와 같은 오류 내용을 확인 할 수 있는데요

이 내용을 보면 파생된 형식이어야 사용할 수 있다는 에러 내용까지 확인 하실 수 있습니다.

 

 

 

 

코드를 보면 생성자가 두가지 생성되어있는 것을 볼 수 있습니다. 하나는 st_a, 다른 하나는 a_cl 입니다.

student class의 생성자인 st_a 에서 접근이 안되는 것을 보니 두번째인 a_cl 에서 접근해보도록 하겠습니다.

namespace ConsoleApp1
{
    class Student
    {
        protected char student1 = 'A';
    }


    class A_class : Student
    {
        static void Main(string[] args)
        {
            Student st_a = new Student();
            A_class a_cl = new A_class();

            
            a_cl.student1 = 'B';
        }
    }
}

이 코드에서는 Student 클래스에 있는 student1 에 접근 할 수 있는 것을 확인 할 수 있습니다.


다음편은 생성자, 소멸자입니다.

'C#' 카테고리의 다른 글

[C#_10_(1)] Class  (0) 2021.10.08
[C#_9] 배열 (Array)  (0) 2021.10.07
[C#_8] 메서드 method  (0) 2021.10.02
[C#_7] 반복문 제어 (Break, Continue, goto)  (0) 2021.09.29
[C#_6] 반복문(for,foreach,while,do while)  (0) 2021.09.24
Class 를 배우기 전에...
클래스를 배우기 전에 우리는 객체 지향 프로그래밍(Object Oreinted Programming, OOP) 에 관하여 알아두어야 합니다.
왜냐하면 C# 자체가 객체 지향성 프로그래밍을 더욱 원활히 하기 위해서 만들어진 언어이기 때문인데요.
이러한 객체 지향 프로그래밍은 우리에게 더욱 원활한 프로그램의 유지와 보수를 가능하게 해주기 때문입니다.
그렇다면 이러한 객체 지향 프로그래밍에는 어떤 것이 필요할까요?
이름에도 적혀있듯이 중요한 것이 객체 입니다.
객체(Object)

프로그래밍에서 객체란 클래스에서 정의한 것을 토대로 메모리에 할당된 것 으로 프로그램에서 사용되는 데이터 또는 식별자에 의해 참조되는 공간을 의미하며, 변수, 자료 구조, 함수 또는 메소드가 될 수 있다고 정의하고있습니다.

 

그러나 저는 처음에 이를 접할 때 코드를 짜보지 않고서는 이해가 조금 어려웠는데요.

그래서 사물로 예를 들어보겠습니다.

 

우리가 현재 사용하고 있는 컴퓨터나 핸드폰, 키보드나 마우스 등

'하나의 물건' 으로 보여지는 것 모든 것이 객체가 될 수 있습니다.

그런데 이러한 객체들은 각각의 행동이 있습니다.

컴퓨터는 사용된다. 핸드폰으로 전화를 건다. 등 각각의 객체가 취할 수 있는 행동이 정의되어 있습니다.

이를 상태(state) 또는 행동(behavior) 이라고 합니다.

  • 상태(state)를 C#에서 표현한다면 변수(class 내부의 변수는 필드)
  • 행동(behavior)을 C#에서 표현한다면 메서드 로 표현 할 수 있겠습니다.
  • 그리고 이러한 상태와 행동을 하나의 틀로 정의해주는 것이 바로 Class 입니다.
1. Class
/*접근제한자*/class 클래스이름
{
    /*접근제한자*/필드
    
    /*접근제한자*/ 반환타입 메소드이름(매개변수)
    {
        코드
        
        return 반환값 // 반환값이 존재할 시 - 메서드 부분 참고             
    }
}

위 코드는 클래스의 기본 형태입니다. 클래스의 이름 중 첫 글자는 대문자로 하는 것이 명명규칙입니다.(구분을 위해)

접근제한자를 적어둔 곳은 접근제한자를 사용하여 접근을 제한 시켜도 된다고 표기한 것 입니다.

접근 제한자에 관하여 다음강의에 적어두겠습니다.

 

사실 우리는 이러한 클래스를 항상 사용해왔는데요 우리가 visual studio 2019를 켜면

namespace ConsoleApp1
{//******************************************
    class Program
    {
        static void Main(string[] args)
        {
            
            
        }
    }
}//******************************************

이러한 형태로 class를 사용하고 있던 것을 알 수 있습니다.

그런데 사실 이렇게만 보면 이 class를 어떻게 사용해야 하는지 또 어떤식으로 활용되는지 잘 이해가 되지 않습니다.

그래서 작은 예를 하나 들어보겠습니다.

class Student
{
    String studentID;//필드1
    String name;//필드2
    int age;//필드3


    public void regist(String studentID, String name, int age)
    {					//메서드 생성 필드를 매개변수로 사용
    
        Console.WriteLine($"{this.name} 의 학번은 {this.studentID} 입니다.");
        if(age>20)
        {
            Console.WriteLine($"{this.age}세로 성인 공부방에 입장합니다.");
        }
        else
        {
            Console.WriteLine($"{this.age}세로 청소년 공부방에 입장합니다.");
        }
    }
}

Student 라는 클래스를 생성해 내부에 String타입의 studentID 와 name, integer 타입의 age 필드를 만들어 줬습니다.

이후 regist라는 '학원에 등록하는 행동을 하는' 메서드를 만들어 주었습니다.

※ this. 의 경우 이 class 안에 필드를 사용한다는 의미 입니다. 다음 강의에 같이 다루게 될 내용입니다.

하지만 이곳은 메인영역이 아니죠 따라서 클래스와 객체를 사용하는 방법을 알아야 합니다.

이 클래스와 객체를 사용하는 방법은 바로 생성자를 만들어주는 것 인데요.

생성자를 만들어 우리가 사용할 수 있도록 인스턴스로 변화시켜줘야 하기 때문입니다.

이러한 생성자는 객체를 초기화하는 역할을 합니다.

 

 

 

[클래스이름] [객체로 사용될 이름] = new [생성자]();

↑생성자의 기본적인 형태

바로 예시를 들겠습니다.

 static void Main(string[] args)
{
	Student student = new Student();
}

위와 같이 생성자를 만들어줍니다.

인스턴스화로 인해 아무런 형체가 없던 글은 드디어 형체를 가지고 우리가 사용할 수 있게 되었습니다.

바로 사용 예시를 들어보면

    class Program
    {
        static void Main(string[] args)
        {
            Student student = new Student();

            student.name = "강호동";
            student.age = 22;
            student.studentID = "20211008.325";
            student.regist(student.studentID, student.name, student.age);//Student클래스 메소드
            Console.WriteLine();
        }
    }

 

이 student는 class Student 와 연결이 되어있어 하나씩 꺼내서 사용 하고 있는 것인데요.

student . 을 사용해서 하나씩 꺼내와 내용에 넣어주고 있는 것 입니다.

그리고 마지막에 regist 메소드를 사용하여 출력까지의 결과를 보면

이렇게 나오는 것을 확인 할 수 있습니다.

하지만 하나만 사용해서는 이 객체지향프로그래밍의 장점을 알 수가 없죠

여러가지 객체를 만드는 것을 보면 어느정도 이해가 가실 것 입니다.

    class Program
    {
        static void Main(string[] args)
        {
            //############################ 생성자 1 ################################
            Student student = new Student();

            student.name = "강호동";
            student.age = 22;
            student.studentID = "20211008.325";
            student.regist();
            Console.WriteLine();
            
            //############################ 생성자 2 ################################
            Student student2 = new Student();//새로운 생성자 생성

            student2.name = "유재석";
            student2.age = 19;
            student2.studentID = "20211008.326";
            student2.regist();
            Console.WriteLine();

            //############################ 생성자 3 ################################
            Student student3 = new Student();//새로운 생성자 생성

            student3.name = "이수근";
            student3.age = 21;
            student3.studentID = "20211008.327";
            student3.regist();
            Console.WriteLine();

            //############################ 생성자 4 ################################
            Student student4 = new Student();//새로운 생성자 생성

            student4.name = "박명수";
            student4.age = 17;
            student4.studentID = "20211008.328";
            student4.regist();
            Console.WriteLine();
        }
    }

위 와같이 각 생성자만을 새로 만들어 새 변수에 담아 하나의 필드를 여러번 사용하는 것이 가능하다는 장점이 있습니다.  물론 이는 반복문을 통해서 더욱 간결하게 만들수 있으니 이는 여러분이 해결해보시면 좋을 것 같습니다.

 


 

오늘 사용된 전체 코드 ↓

더보기
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Student
    {
        public String studentID;
        public String name;
        public int age;

        public void regist()
        {
            Console.WriteLine($"{this.name} 의 학번은 {this.studentID} 입니다.");
            if(age>20)
            {
                Console.WriteLine($"{this.age}세로 성인 공부방에 입장합니다.");
            }
            else
            {
                Console.WriteLine($"{this.age}세로 청소년 공부방에 입장합니다.");
            }
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            //############################ 생성자 1 ################################
            Student student = new Student();

            student.name = "강호동";
            student.age = 22;
            student.studentID = "20211008.325";
            student.regist();
            Console.WriteLine();
            
            //############################ 생성자 2 ################################
            Student student2 = new Student();//새로운 생성자 생성

            student2.name = "유재석";
            student2.age = 19;
            student2.studentID = "20211008.326";
            student2.regist();
            Console.WriteLine();

            //############################ 생성자 3 ################################
            Student student3 = new Student();//새로운 생성자 생성

            student3.name = "이수근";
            student3.age = 21;
            student3.studentID = "20211008.327";
            student3.regist();
            Console.WriteLine();

            //############################ 생성자 4 ################################
            Student student4 = new Student();//새로운 생성자 생성

            student4.name = "박명수";
            student4.age = 17;
            student4.studentID = "20211008.328";
            student4.regist();
            Console.WriteLine();
        }
    }
}

 


다음에서는 접근제한자this. 에 대해서 알아보겠습니다.

'C#' 카테고리의 다른 글

[C#_10_(2)] 접근제한자, this  (0) 2021.10.18
[C#_9] 배열 (Array)  (0) 2021.10.07
[C#_8] 메서드 method  (0) 2021.10.02
[C#_7] 반복문 제어 (Break, Continue, goto)  (0) 2021.09.29
[C#_6] 반복문(for,foreach,while,do while)  (0) 2021.09.24
1. 배열

Array 라고 불리는 이 배열의 개념은 동일한 자료형의 집합체로 같은 타입의 자료를 연속된 공간에 나열하고 각 자료에 index를 부여한 것이기 때문입니다.

1-2. 배열의 선언

이전에 반복문을 할 때 잠시 배열을 언급하며 넘어갔었는데요.(반복문 게시물 2)

이 때 언급한 것이 배열의 형태 였습니다.

타입[] 배열이름 = new 자료형[배열의 길이]

이는 배열의 가장 기본이 되는 형태인데요, 이해를 돕기위해 예제를 사용해보겠습니다.

int[] intArray = new int[5];

이렇게 'int형태의 배열이며 길이가 5인 배열을 선언하겠다' 라는 것을 코드로 적어둔 것 입니다.

사실 배열을 선언하는 방법은 두 가지가 있는데요.

  • 첫 번째 : 배열의 길이를 먼저 선언하고 나중에 배열의 인자를 넣어주는 방법
  • 두 번째 : 배열의 선언과 동시에 인자를 넣어주는 방법
  • 세 번째 : index를 이용하여 인자를 넣어주는 방법 (이는 index 설명과 함께 설명하겠습니다.)

위에 사용한 예시가 바로 첫번째 방법입니다.

내부에 배열의 인자를 작성하려면 아래와 같은 방법으로 하시면 됩니다.

int[] intArray = new int[5];
intArray = new int[] { 1, 2, 3, 4, 5 };

 

두 번째 방법을 예시로 들자면 위 첫번째 방법을 한번으로 하는

int[] intArray = new int[] { 1, 2, 3, 4, 5 };

과 같은 방법과 조금 약식처럼 쓰는 아래와 같은 방법이 있습니다.

int[] intArray = { 1, 2, 3, 4, 5 };

두 번째 방법들은 배열의 인자들을 넣어주면서 길이를 자동으로 지정해주기 때문에

따로 길이를 설정해줄 필요는 없습니다.

2. index

배열을 선언하면서 내부에 인자들을 넣었으나 우리는 이 인자에 대한 접근을 몰라 출력을 해줄수가 없습니다.

일반적인 방법으로 출력한다면 결과가 이상하기 때문인데요.

static void Main(string[] args)
{
	int[] intArray = new int[5];
	intArray = new int[] { 1, 2, 3, 4, 5 };
            
	Console.WriteLine(intArray);
}

이대로 출력하게 된다면

이렇게 이상한 값이 나오게 됩니다.(게시글 마지막 부분 추가설명)

이 때 우리가 필요해진 것이 인덱스(index) 인데요.

위에서 설명했듯이 각 인자들에 index 가 부여되어있기 때문에 접근 할 수 있게 된 것입니다. 

  • 부여된 인덱스는 0부터 시작합니다.

위처럼 길이가 10인 배열을 선언하면 0~9까지의 인덱스가 부여되어 있는 것을 확인할 수 있습니다.

인덱스를 이용한 인자를 넣는 방법도 있으니

2-1. index를 이용한 배열의 출력

우리는 이러한 index를 통해 배열을 출력해볼 것 입니다.

예를 들어보겠습니다. 

static void Main(string[] args)
{
      String[] subject = new string[5];
      subject[0] = "kor";
      subject[1] = "eng";
      subject[2] = "math";
      subject[3] = "social";
      subject[4] = "science";
}

subject라는 String 타입의 배열을 선언해준 뒤 길이를 5로 설정해주었습니다.

이후 각 index를 이용하여 내부에 인자를 넣어주었습니다.

이렇게 각 index로 인자에 접근할 수 있는 것을 보니 index를 사용한다면 우리가 출력까지도 해줄 수 있을 것 같으니

시도해보겠습니다.

static void Main(string[] args)
{
      String[] subject = new string[5];
      subject[0] = "kor";
      subject[1] = "eng";
      subject[2] = "math";
      subject[3] = "social";
      subject[4] = "science";

      Console.WriteLine(subject[0]);
      Console.WriteLine(subject[1]);
      Console.WriteLine(subject[2]);
      Console.WriteLine(subject[3]);
      Console.WriteLine(subject[4]);
}

이렇게 잘 출력되는 것을 볼 수 있는데요.

잘 보니까 이전에 배웠던 것을 활용하여 출력할 수 있을 것 같은데요.

바로 반복문입니다.

2-2. 반복문을 이용한 배열 출력
static void Main(string[] args)
{
      String[] subject = new string[5];
      subject[0] = "kor";
      subject[1] = "eng";
      subject[2] = "math";
      subject[3] = "social";
      subject[4] = "science";

      for(int i=0; i<subject.Length; i++)
      {
     	 Console.WriteLine(subject[i]);
      }
}

위와같이 반복문으로 출력했을 때도

같은 결과가 나온 것을 볼 수 있습니다.

그런데 코드를 보니 조금 특이한 부분이 있죠?

바로 for문의 조건문 부분입니다.

subject 배열의 Length(길이) 만큼의 값을 준다는 것 입니다.

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            String[] subject = new string[5];

            Console.WriteLine(subject.Length);
        }
    }
}

이를 출력해보면

이렇게 5라는 값이 나온 것을 볼 수 있습니다.

이러한 length를 통해서 배열의 길이를 확인하거나

따로 배열의 길이를 책정할 필요없이 유동적 사용이 가능한 속성입니다.

유용하니 꼭 알아두시길 바랍니다.


3. 다차원 배열

다차원 배열이란 말 그대로 여러가지 차원을 가진 배열입니다.

우리가 지금까지 하나의 선과 같은 1차원 배열을 사용했다면

다차원 배열은 면 또는 상자 처럼 여러가지 차원을 가지고 있다는 이야기 입니다.

 

먼저 2차원 배열부터 알아보겠습니다.

2차원 배열은 

가로, 세로의 평면 구조를 가지고 있습니다.

따라서 이를 코드로 보면

자료형[,] 배열명 = new 자료형[행 수, 열 수];

의 기본형태를 가지고있습니다.

※자료형 뒤에 배열임을 선언할 때 ' , ' 가 있는 것을 볼 수 있는데 이는 본래 자료형의 크기를 넣을 때 행과 열로 나눌 필요가 없었기 때문입니다. 

다차원 배열의 경우는 이를 따로 선언해 줄 필요가 있기 때문에 ' , '가 들어간 것 입니다.

 

 

 

 

그렇다면 이러한 2차원 배열을 예시로 들어보겠습니다.

int[,] multiArr = new int[2, 4] { { 0, 1, 2, 3 }, { 4, 5, 6, 7 } };

이러한 2차원 배열을 도형으로 표시하면

와 같습니다.  이를 출력해보면

static void Main(string[] args)
{
    int[,] multiArr = new int[2,4]{ { 0, 1, 2, 3}, { 4, 5, 6, 7} };

    Console.WriteLine(multiArr[1,2]); // 6
    Console.WriteLine(multiArr[0,3]); // 3
    Console.WriteLine(multiArr[1,1]); // 5
}

 

위치 값에 따라 결과가0 나오는 것을 볼 수 있습니다.

 

 

 

 

 

 

 

이러한 2차원 배열 말고 3차원 4차원 배열도 있습니다만 코드가 너무 복잡해져 일반적으로는 잘 사용하지 않습니다.

자료형[,,] 배열명 = new 자료형[높이, 세로, 가로];

3차원 배열의 기본형식은 이렇습니다.

이 3차원 배열은 2차원 배열을 인자로 가지고 있는 형식입니다.

조금 복잡하니 이해를 돕기위해 예를 들면

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            int[,,] multiArr = new int[3, 2, 3]
            {
                {{1,1,1}, {1,1,2}},
                {{2,1,1}, {2,1,2}},
                {{3,1,1}, {3,1,2}}
            };
            
        }
    }
}

이를 도형으로 만든다면 아래와 같은 모형이 됩니다.

 


※ 추가설명

사실 배열을 선언할 때 배열의 이름을 설정하면 설정한 이름에 공간이 만들어져 배열의 인자가 설정된 공간으로 들어가는 형식이 아닙니다. (일반적인 변수)

배열의 이름을 설정하면 사실 배열의 실제 공간은 따로 있고 배열의 이름은 이를 직접적으로 참조하여 값을 공간으로 보내는 역할을 하는 '주소값'의 역할을 하고있는 것 입니다.


여기까지 배열이었습니다. 고생하셨습니다.

'C#' 카테고리의 다른 글

[C#_10_(2)] 접근제한자, this  (0) 2021.10.18
[C#_10_(1)] Class  (0) 2021.10.08
[C#_8] 메서드 method  (0) 2021.10.02
[C#_7] 반복문 제어 (Break, Continue, goto)  (0) 2021.09.29
[C#_6] 반복문(for,foreach,while,do while)  (0) 2021.09.24
메서드?
C# 에서 메서드란 C 또는 C++에서 함수(Function)의 역할을 하는 것.

메서드의 기본형태는

static void 메서드이름(매개변수) //매개변수의 또다른 이름은 파라미터
{
    코드
}

입니다.

 

이러한 기본형태는 사실 우리가 흔히 쓰고있었 습니다.

바로 코드를 작성할 때 우리가 가장 기본적으로 사용하고 있는 main에서 인데요

static void Main(string[] args)
//				└매개변수
{
    
}

메인 메서드는 컴퓨터가 프로그램을 실행하면 가장 먼저 찾아서 실행해주는 영역입니다.

그래서 메서드를 선언할 때 이 메인 메서드 영역 밖에서 메서드를 작성하고

그 메서드를 메인에 불러오는 형식으로 작성해주면 되는데요.

예를 들면

//예시 1
namespace ConsoleApp1
{
    class Program
    {
        static void plus(int a, int b)
        {
            Console.WriteLine(a+b);
        }
        static void Main(string[] args)
        {
            int a = 10;
            int b = 20;

            plus(a, b);
        }
    }
}

의 형식인 것입니다. 코드를 보면 class 영역 내부 main영역 외부에 작성된 메서드를 보실 수 있는데요.

  1. 프로그램 시작
  2. main메서드 실행
  3. 변수 a , b 선언
  4. plus 메서드에 변수 a,b를 매개변수로 넣고 호출
  5. plus메서드 영역으로 이동
  6. 출력문 출력
  7. plus메서드 종료
  8. 메인 메서드 종료

이러한 순서로 진행되고 있는 것입니다.


메서드를 배우면서 저는 궁금증이 들었는데요 static? void? 이것은 무엇인가? 하는 것이었습니다.

이중 static 의 경우는

이중 void는 '리턴 타입'인데요

이는 메소드를 실행하고 난 이후의 값의 타입이 무엇인가에 따라서 다르게 작성해주어야 합니다.

더보기

void : 리턴값의 타입이 없음

int   : 리턴값의 타입이 정수형

double : 리턴값의 타입이 실수형

String : 리턴값의 타입이 문자열

char : 리턴값의 타입이 문자

boolean : 리턴값의 타입이 bool

만일 리턴타입이 존재하게 작성을 한다면 우리는 반드시

내부에 return을 작성하여 그에 맞는 타입을 return해주어야합니다.(자동 형태변환)

//예시2
namespace ConsoleApp1
{
    class Program
    {
        static int plus(int a, int b)
        {
            return a+b;
        }
        static void Main(string[] args)
        {
            int a = 10;
            int b = 20;

            int c = plus(a, b);
            Console.WriteLine(c);
        }
    }
}

위 코드를 보면 예시1에서 사용했던 void가 아닌 int로 작성되어있는 것을 볼 수 있습니다.

위에 설명했던 것 처럼 int 타입으로 값을 리턴한다는 이야기 입니다.

이렇게 리턴타입이 있을경우 메인 함수에서는 그 리턴된 값을 받아줄 변수가 하나 필요하며

이 변수에 리턴된 값을 담아 출력된 것을 볼 수 있습니다.

 

위 예시1은 리턴값이 없어 메서드 기능에서 출력시킨 것


1-1. call by value (간접 참조)
1-2. call by reference (직접 참조)

이 두개를 한번에 정리하는 이유는 하나는 직접 참조이고 하나는 간접 참조이므로 둘이 비교하며 보여드리면

조금 더 이해가 쉬울 것 이기 때문입니다.

 

namespace ConsoleApp1
{
    class Program
    {
    	static void Swap(int a, int b)
        {
            int temp; 
            temp = a;
            a = b;
            b = temp;
        }// 두 변수의 값을 맞바꿔주는 swap 메서드
        
        static void Main(string[] args)
        {
            int a = 10;
            int b = 20;

            Console.WriteLine($"Swap메서드 실행 전: a={a}, b={b}");

            Swap(a, b);

            Console.WriteLine($"Swap메서드 실행 후: a={a}, b={b}");
        }
    }
}

위 코드를 보시면  a는 10 , b는 20의 값을 담고 있습니다.

이를 출력문으로 확인해주고 swap메서드를 이용하여 두 변수에 담긴 값을 맞바꿔줍니다.

이 값이 잘 바뀌었는지 확인해보면

값이 바뀌지 않은 것을 볼 수 있습니다.

이는 call by value 즉 간접참조 형식을 사용했음을 할 수 있는데요.

이는 메서드에서 매개변수 값을 복사하여 내부적으로 처리한 것 입니다.

 

위 코드는 리턴값이 없는 void Swap(int a, int b) 메서드 인 것을 확인 할 수 있습니다.

매개변수를 받으면서 int a와 int b라는 공간을 만들고 내부 코드를 돌립니다. 하지만

메인 메서드 내부에서 값을 받아주지 않았으니까 Swap()메서드 영역이 종료되면서

복사된 a와 b의 공간이 같이 사라진 것 입니다.

그래서 메인으로 돌아왔을 때 a와 b값은 그대로인 것이죠.

 

이를 해결하고 싶을 때 우리는 call by reference(직접참조) 형식을 사용하면됩니다.

예시를 들어보겠습니다.

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 10;
            int b = 20;

            Console.WriteLine($"Swap메서드 실행 전: a={a}, b={b}");

            Swap(ref a,ref b); //변경점 : ref

            Console.WriteLine($"Swap메서드 실행 후: a={a}, b={b}");
        }

        static void Swap(ref int a,ref int b) //변경점 : ref
        {
            int temp; 
            temp = a;
            a = b;
            b = temp;
        }
    }
}

이렇게 ref(erence) 를 메서드 호출과 메서드 생성시 매개변수에 넣어주면서

메모리 주소값에 직접적으로 관여해 값을 바꾸는 형식으로 해결할 수 있습니다.


2. 메서드 오버로딩 (overloading)

메서드 오버로딩은 메서드의 이름이 같을 때 매개변수의 타입과 갯수에 따라서 실행을 다르게 하는 시스템입니다.

method A(int a, int b)
{
	return a+b;
}

method A(int a, int b, int c)
{
 	return a+b+c;
}

예시와 같이 같은 이름을 가진 두개의 메서드 A가 있습니다. 

우리가 메인메서드에서 A메서드를 호출해줄 때 메서드 이름만 가지고 컴퓨터가 메서드영역을 불러온다면 [Ex) A(1,2)]

첫 A 메서드는 실행이 되어도 두번째 A메서드에서는 매개변수 부족으로 인한 오류가 나기 때문에

프로그램은 망가지게 됩니다.

이를 방지해 주는 것이 메서드 오버로딩입니다.

매개변수의 갯수 또는 타입을 구분하여 메인 메서드에서 A(1,2) 로 호출시 첫 A메서드만 호출 되는 것 입니다.

예시로 보자면

namespace ConsoleApp1
{
    class Program
    {
        static int Plus(int a, int b)// 정수형 매개변수 두개
        {
            Console.Write("int 끼리 더합니다.");
            return a + b;
        }

        static int Plus(int a, int b, int c)// 정수형 매개변수 세개
        {
            Console.Write("int 끼리 더합니다.");
            return a + b + c;
        }

        static double Plus(double a, double b)// 실수형 매개변수 두개
        {
            Console.Write("double 끼리 더합니다.");
            return a + b;
        }
        static void Main(string[] args)
        {
            Console.WriteLine(Plus(10, 20));//출력문(함수호출)
            Console.WriteLine();
            Console.WriteLine(Plus(10.5, 20.5));
            Console.WriteLine();
            Console.WriteLine(Plus(10, 20, 30));
            Console.WriteLine();
        }
    }
}

셋 다 같은 Plus 라는 이름을 가진 메서드이지만 그 결과를 보면

 

이렇게 각 메서드가 잘 호출되어 나타난 것을 알 수 있습니다.

'C#' 카테고리의 다른 글

[C#_10_(1)] Class  (0) 2021.10.08
[C#_9] 배열 (Array)  (0) 2021.10.07
[C#_7] 반복문 제어 (Break, Continue, goto)  (0) 2021.09.29
[C#_6] 반복문(for,foreach,while,do while)  (0) 2021.09.24
[C#_5] 조건문 (if, else, switch)  (0) 2021.09.23

이전강의에서 저희는 반복문을 배워보았습니다.

이 반복문은 잘못하면 무한루프에 빠진다고 이전시간에 언급했었는데요.

이 반복문을 제어할 수 있는 방법이 있습니다.

Break, continue, goto 제어문을 통해서 입니다.


1. Break

break는 '가장 가까운 반복문을 빠져나오는 역할' 을 수행하는 제어문입니다.

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            int ForEnd = 0;
            
            for(int i=0; i<10; i++)
            {
                if(ForEnd<5)
                {
                    Console.WriteLine(ForEnd);
                    ForEnd++;
                }
                else
                {
                    break;
                }

            }
        }
    }
}

코드를 해석해보자면

반복문(for)가 돌아가고 있는 중 ForEnd라는 변수가 5보다 작을 때는 변수에 담긴 수를 출력하고

ForEnd에 1씩 더한다는 내용이 if문 내부에 있습니다.`

else에 들어갈 조건은 당연하게도 'ForEnd가 5와 같거나, 보다 클 때' 인데요, 이 때 break와 가장 가까운 반복문

즉, int 형 변수 i를 사용하는 반복문을 종료한다는 것 입니다.

 결과를 보시면 ForEnd변수가 5가 됨에 따라 else문에서 break를 만나 4에서 출력이 멈춘것을 볼 수 있습니다.

위에 강조해둔 break와 가장 가까운 반복문 이라는 부분은 중요한 포인트입니다.

이를 코드로 확인해보겠습니다.

더보기
namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            
            for(int i=0; i<10; i++)
            {
                for(int j=0; j<10;j++)
                {
                    Console.WriteLine($"i : {i}, j : {j}");
                }

            }
        }
    }
}

이는 평범한 다중 for문 형태입니다.

그 결과는

이처럼  i가 9, j가 9가 될 때까지 나오는 것을 볼 수 있는데요.

이제 분기문을 사용해서 j가 3이 되었을 때 끊어보겠습니다. 

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            
            for(int i=0; i<10; i++)
            {
                for(int j=0; j<10;j++)
                {
                    Console.Write($"i : {i}, j : {j}\t");
                    if (j == 3)
                        break;
                }
                Console.WriteLine();
                Console.WriteLine();
            }
        }
    }
}

보기 편하도록 코드를 적어보았는데요. 그 결과는

이렇습니다. j가 3이 되면 j반복문이 끊어지고 다시 i반복문으로 향합니다. 

i가 1 올라가고 다시 j반복문으로 내려와 3까지 진행한후 끊어지는 것을 반복하는 모습을 볼 수 있습니다.

이처럼 break는 break와 가까운 반복문을 탈출하는 모습을 볼 수 있습니다.


2. continue

 

 

 

continue는 반복문에서 '조건을 검사하는 부분으로 가는' 제어문입니다.

예시코드를 보겠습니다.

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            
            for(int i=1; i<=5; i++)
            {
                if (i == 3)
                    continue;
                for (int j=1; j<=5;j++)
                {
                    Console.WriteLine($"i : {i}, j : {j}");
                }
                Console.WriteLine();
            }
        }
    }
}

이전 break는 반복문 자체를 탈출하여 그 뒤로는 실행이 안되었습니다.

하지만 continue는 반복문 자체를 탈출하는 것이 아닌 그 조건일 때

반복문의 조건을 검사하는 부분으로 올라가는 것이므로 3이외의 모든 코드가 나와야 합니다.

i가 3일 때 continue를 해주어서 i값이 3일 때가 없는 것을 볼 수 있습니다.


3. goto

goto문은 '지정된 레이블로 건너뛰는' 제어문입니다.

※ 레이블(Lable) : 코드 내에 데이터 위치를 나타내주는 역할

 

goto 레이블명;
...
레이블: 실행될 코드

위 코드는 goto의 기본형태입니다.

 

이를 코드로 보자면

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            for(int i=1; i<=10; i++)
            {
                if(i==3)
                {
                    goto numThree;
                }
                Console.WriteLine($"i = {i}");
            }
            numThree: Console.WriteLine("숫자 3입니다.");
        }
    }
}

i를 계속 출력하던 중 if조건문을 만나 goto 문으로 반복문 바깥부분으로 넘어가는 것을 볼 수 있습니다.

goto 문은 이렇게 반복문 탈출로도 사용할 수 있지만 위에 언급한 것 처럼

원하는 부분으로 코드를 뛰어넘는 역할을 하는 것으로 이해하면 원활한 이해가 가능할 것 같습니다.

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i=1; i<=9; i++)
            {
                if (i == 3)
                    goto Jump;//여기서 점프
                Console.WriteLine($"i = {i}");
            }

            Console.WriteLine("점프되는 부분");//건너뛰어짐으로 출력되지않음

            Jump://여기로 점프
            Console.WriteLine();//줄바꿈
            for (int k = 5; k <= 9; k++)
            {
                Console.WriteLine($"k = {k}");
            }

        }
    }
}

코드를 보시면 i가 3이 되고 Jump레이블로 이동을 시작합니다. 반복문을 종료시키고 중간에 껴있는 출력문 역시 건너뛰어 Jump레이블로가 줄바꿈과 새로운 for 반복문을 출력합니다.

 

'C#' 카테고리의 다른 글

[C#_9] 배열 (Array)  (0) 2021.10.07
[C#_8] 메서드 method  (0) 2021.10.02
[C#_6] 반복문(for,foreach,while,do while)  (0) 2021.09.24
[C#_5] 조건문 (if, else, switch)  (0) 2021.09.23
[C#_4] 출력문, 입력문, 연산자, 문자열 보간  (0) 2021.09.21
반복문

for, foreach, while, do while 4가지의 반복문이 있습니다.

전부 조금씩 다르니 포인트를 잘 잡아야 합니다.


1. for
for (int i = 0; i < length; i++)
{
	//반복될 문장
}

(for문의 기본형태)

위 코드는 for문의 기본형태입니다.

코드에서 보면 괄호 안에 지금까지와는 다르게 적혀있는 조건을 볼 수 있는데요.

각 부분으로 나누어 보자면

for (초기화식 ; 조건식 ; 증감식) 으로 보시면 됩니다.

int i라는 변수를 0에서부터(초기화식) ; length(=길이)보다 작을 때까지{조건식) ; 하나씩 올려준다(증감식)

로 해석할 수 있습니다.

 

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 0; i < 10; i++)
            {
                Console.Write(i + " ");
            }
            Console.WriteLine();
        }

    }
}

(이해를 돕기 위한 예시코드)

위 코드를 실행해보면 

위 사진과 같은 결과가 나옵니다.

0에서 부터 시작된 int i 가 10보다 작을 때 까지 하나씩 증가 되면서 출력 된 것을 알 수 있습니다.

 

기본 형태라고 적어뒀지만 그 형태에 집착하지 말아야 합니다.

이유는 초기화식;조건식; 증감식 의 변화가 가능하기 때문인데요

코드로 보자면

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 10; i >= 0; i -= 2)
            {
                Console.Write(i + " ");
            }
            Console.WriteLine();
        }

    }
}

과 같이 for문의 모든 식이 달라지는 것을 확인할 수 있습니다.

결과


1-2 이중(다중) for문

if(조건문)에서 보여드렸던 if문 안에 if문이 들어갈 수 있는 것을 기억하시나요?

for문 역시 마찬가지로 for문안에 for문이 들어갈 수 있습니다.

코드로 보겠습니다.

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 2; i < 10; i++)
            {
                for(int j = 1; j < 10; j++)
                {
                    Console.WriteLine($"{i}X{j}={i*j}");
                }
                Console.WriteLine();
            }
            
        }

    }
}

다중for문의 i반복문(외(外)반복문) 이 2일 때 j반복문(내(內)반복문)은 1~9까지 전부 돌고

다시 외반복문으로 돌아와서 i에 1을 더해 3이 되고 j가 1~9까지 도는 것

이 과정들이 i가 10이 됨과 동시에 내외반복문이 모두 종료되며 끝나는 것 입니다.

 


2. foreach

foreach문을 알려면 먼저 배열을 알아야 합니다.

하지만 배열은 나중에 다루게 될 부분이라 이번에는 대략적인 부분만 짚고 넘어가겠습니다.

배열의 기본적인 형태는 

int[] Array = {0,1,2,3,4,5};

int타입의 [배열] 배열이름 = {배열의 인자들}

배열의 내부의 인자들은 반드시 선언시 {중괄호}를 사용해서 만들어주어야 합니다.


이 배열을 foreach문을 통해서 내부 인자들을 출력해볼 것인데요.

foreach (변수타입 변수이름 in 배열)
{
	//Console.WriteLine(변수이름)
}

foreach의 기본형태

기본형태에서 변수 타입은  int, char, String 등이 올 수 있습니다.

※ 보통 var이라고 하는 컴파일러가 컴파일링 할 때 알아서 변수타입을 지정하는 유동적인 형태의 변수타입을 사용합니다.

변수이름은 우리가 편하게 알아볼 수 있는 이름 을 사용하면 됩니다.

(Ex : 배열의 인자가 숫자라면 num, 문자열이라면 str 등) 

배열에는 우리가 미리 선언한 배열의 이름을 사용해주시면 됩니다.

 

이해를 돕기 위해 예시코드를 보겠습니다.

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] intArray = { 0, 1, 2, 3, 4, 5 };

            foreach (var num in intArray)
            {
                Console.WriteLine($"num : {num}");
            }
            
        }

    }
}

예시코드에서는 배열을 먼저 선언해주고 foreach문에서 intArray에 있는 인자들을 차례대로 꺼내와

변수 num에 담아서 출력한 모습입니다.

출력된 모습


3. while

while문은 특정 조건을 만족할 때 까지 반복하는 문장입니다.

아래는 while문의 기본형태입니다.

while(조건)
{
	실행할 문장
}

if문에서 배웠던 것 처럼 while문에도 조건이라는 부분이 붙어있습니다.

조건 부분에 들어갈 연산자는 Boolean값이 나오는 연산자를 사용해야합니다.(관계연산자, 논리연산자 등)

while문은 조건이 True일 때 반복을 지속하며 False일 때 반복문을 빠져나온다는 것 입니다.

만약 조건 코드를 잘못하여 조건이 계속 True가 나오게 된다면 무한루프에 빠지게 되는 것 입니다.

 

↓ 무한루프

더보기
int a = 0;

while(a<10)
{
	Console.WriteLine(a); //무한히 0이 출력됨
}

※ 코드가 길어졌을 때 무한루프에 빠지게 된다면 심한 경우 컴퓨터에 큰 무리가 갈 수 있습니다.

무한루프 시 모습

↓ 무한루프 해결

더보기
int a = 0;

while(a<10)
{
	Console.WriteLine(a);
    	a++; //루프가 한번 돌 때 a의 값을 1씩 증가시켜 a가 10이 될 때 종료시킴
}

int 변수 a 가 1씩 증가하면서 a가 10이 될 때 조건이 False가 되면서 반복문을 탈출함

 

조건이 True, False인 만큼 Boolean타입을 넣어서 탈출 할 수도 있습니다.

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            bool tBool = true;
            int num = 0;

            while(tBool)
            {
                Console.WriteLine(a);
                num++;
                if (num == 10) 
                {
                    tBool = false;
                }
            }
        }

    }
}

Boolean 타입의 변수 tBool을 True로 사용하기 위해 선언한 뒤 조건에 넣었습니다.

이때 조건이 계속 true가 되는 것 입니다. 우리가 전에 배운 if문을 사용하여 int변수 num이 10이 될 때

Boolean 타입의 변수 tBool 을 False로 바꿔주어 반복문을 탈출 시킨 것 입니다.


4. do while

do while문은 기본적으로 while문과 동일하나 차이점이 있습니다.

우선 do while문의 기본형태입니다.

do{
	실행코드
}while(조건);

do : 실행하고

while : 반복하고

조건 : 조건을 검사한다.

이렇게 먼저 한번 실행을 진행하고 반복으로 넘어가면서 조건을 검사해 반복해주는 코드입니다.

예시로 보겠습니다.

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = 0;
            do
            {
                Console.WriteLine($"{n+1}회 실행");
                n++;
            } while (false);
        }

    }
}

코드를 보시면 일부러 while조건 부분을 false로 반복문이 실행되지 않도록 해두었습니다.

하지만 결과를 보시면

이처럼 한번은 무조건 실행되는 모습을 볼 수 있습니다.

이후 조건을 검사했는데 false라 더이상 반복을 진행하지 않은 모습역시 확인할 수 있습니다.

기본적으로 while문과 동일하나 한번은 무조건적으로 실행시켜주어야 할 때 사용하면 좋은 코드입니다.

'C#' 카테고리의 다른 글

[C#_8] 메서드 method  (0) 2021.10.02
[C#_7] 반복문 제어 (Break, Continue, goto)  (0) 2021.09.29
[C#_5] 조건문 (if, else, switch)  (0) 2021.09.23
[C#_4] 출력문, 입력문, 연산자, 문자열 보간  (0) 2021.09.21
[C#_3] 변수, 자료형  (0) 2021.09.12

조건문 : 어떠한 조건에 따라 실행 할 문장이 달라지는 것, 그 조건이 True인지 False 인지를 구분하여 실행한다.


1. if , else 문

if문의 기본 형태

if(조건)
{
	조건이 True일시 실행되는 부분
}

if문의 기본 형태를 적어드렸는데요. 여기서 조건이라는 부분을 주목 해보셔야 합니다.

"조건이 True 일 때" 라는 부분에서 우리는 이 조건이 Boolean 값을 도출 해야 한다는 것을 알 수 있습니다.

[C#_4]에서 보았던 논리연산자 와 관계연산자가 이 if(조건 )부분에 많이 사용됩니다.

예시를 들어보겠습니다.

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 10, b = 5;

            if(a>b)
            {
                Console.WriteLine("a는 b보다 크다.");
            }

            if(a<b)
            {
                Console.WriteLine("b는 a보다 크다.");
            }
        }
    }
}

예시코드를 보면 아래쪽 if문은 전혀 필요가 없는 부분인 걸 알 수 있습니다.

조건이 False라서 실행되지 않을 뿐더러 굳이 쓰지 않아도 될 조건을 하나 더 적었다는 부분에서 입니다.

a와 b는 3가지 경우가 있습니다. a가 b보다 크거나, 작거나, 같다. 인데요.

무작위 숫자 a,b가 서로 같지 않을 때 조건은 두가지로 줄어듭니다. 크거나 또는 그 반대이거나.

이 부분을 우리는 굳이 조건을 적어주지 않고 else로 대체할 것 입니다. 

if (조건)
{
    조건이 True일 경우 실행할 문장
}
else
{
    if절의 조건이 False일 경우 실행할 문장
}

(if - else의 기본형태)

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 10, b = 50;

            if(a>b)
            {
                Console.WriteLine("a는 b보다 크다.");
            }
            else
            {
                Console.WriteLine("b는 a보다 크거나 같다.");
            }
        }
    }
}

else란?  내가 적어준 조건이 False일 때 실행되는 문장을 나타냅니다.

위 코드에서는 b를 50으로 바꾸어 보았습니다.

if문에서의 조건문이 False가 되면서 else문으로 넘어가게 됩니다.

이후 else출력이 진행됩니다.

 

하지만 우리가 항상 이렇게 두 가지 상황으로만 조건을 나누어 볼 수는 없죠.

더 많은 상황이나 조건을 고려해야 한다면 어떻게 해야 할까요?

그래서 우리는 else if문을 사용해야 합니다.

if(조건)
{
	if조건이 True일 때 실행되는 문장
}
else if(조건)
{
	if조건이 False이고 else if조건이 True일 때 실행되는 문장 
}
else
{
	위 모든 조건들이 False일 때 실행되는 문장
}

(else if의 기본형태)

위 형태를 따라 예를 코드로 작성해보면

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 10, b = 5;

            if(a>b)
            {
                Console.WriteLine("a는 b보다 크다.");
            }
            else if(a<b)
            {
                Console.WriteLine("b는 a보다 크다.");
            }
            else
            {
                Console.WriteLine("a와 b는 같다!");
            }
        }
    }
}

의 형태가 될 수 있을 것 입니다.

그렇다면 else if문은 하나만 적을 수 있는 걸까요? 코드로 보겠습니다.

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 10;
            int b = 10;

            if (a > b)
            {
                Console.WriteLine("a가 b보다 큽니다");
            }
            else if (a < b)
            {
                Console.WriteLine("a가 b보다 작습니다");
            }
            else if (a == b)
            {
                Console.WriteLine("a와 b는 같습니다");
            }
            else if (a + b == 20)
            {
                Console.WriteLine("a + b는 20입니다");
            }
            else
            {
                Console.WriteLine("?????");
            }
        }

    }
}

위 코드를 잘 보고 실행시켜보면 뭔가 이상한 부분이 있을 겁니다.

바로 4번째 else if문 a + b == 20 의 조건이 True임에도 불구하고 실행되지 않은 것 인데요.

이걸로 우리는 else if문은 위에서 부터 조건을 검사하여

가장 먼저 True인 코드를 실행하고 나머지 코드를 건너뛴다는 것을 알 수 있게 되었습니다.

 

※물론 if문장 안에 if, else if, else문을 넣는 것도 else문 안에 if, else if, else를 넣는 것도 가능합니다.

※이를 다중 if문이라고 합니다.

더보기
namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 10;
            int b = 10;

            if (a > b)
            {
                Console.WriteLine("a가 b보다 큽니다");
            }
            else
            {
                if(a<b)
                {
                    Console.WriteLine("a는 b보다 작습니다.");
                }
                else
                {
                    Console.WriteLine("a는 b와 같습니다.");
                }
            }
            
        }

    }
}

2. switch

switch문 또한 조건을 보고 True, False를 검사할 때 사용됩니다.

switch (조건)
{
    case 상수:
        실행코드;
        break;

    case 상수:
        실행코드;
        break;

    default:
        실행코드;
        break;
}

switch의 기본형태

 

if문이 조건을 그대로 써주었다면 switch문은 조건에 식을 넣고 그 값을 case 상수 부분에 넣어

True일 경우 코드를 실행합니다. 그 후 break; 를 통해서 switch문을 빠져나오게 됩니다.

만일 case 상수 부분이 모두 False가 된다면 default로 넘어가게 됩니다.

즉 default 부분이 if문의 else 부분인 것 입니다.

 

switch문의 예제를 보겠습니다.

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 3;

            switch(a%2)
            {
                case 0:
                    Console.WriteLine("a는 짝수");
                    break;
                default:
                    Console.WriteLine("a는 홀수");
                    break;

            }
        }

    }
}

 3 % 2의 값은 1로 첫번째 case 문에 해당하지 않습니다.

모든 case문에 해당하지 않기 때문에 default로 넘어가게 되어 a는 홀수 가 출력됩니다.

 

※ switch()에 들어가는 모든 조건이 꼭 숫자일 필요는 없습니다.

※ stirng, char, bool값 역시 가능합니다.

더보기
namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            char day = 'D';

            switch(day)
            {
                case 'm':
                    Console.WriteLine("Monday");
                    break;
                case 't':
                    Console.WriteLine("Tuesday");
                    break;
                case 'w':
                    Console.WriteLine("Wednesday");
                    break;
                case 'T':
                    Console.WriteLine("Thursday");
                    break;
                case 'f':
                    Console.WriteLine("Friday");
                    break;
                case 'W':
                    Console.WriteLine("Weekend");
                    break;
                default:
                    Console.WriteLine("???");
                    break;
                
            }
        }

    }
}

코드에서 보는 char 변수 day는 D를 가지고 있다.

모든 case문에 속하지 않는 D를 조건으로 가진 Switch가 각 case들을 돌아본 뒤 모두 아닌 것이라 판단하고

default를 출력한 모습을 볼 수 있다.

 

1. 출력문 정리

[C#_2]에서 했던 Console.WriteLine() 과 Console.Write() 를 상기해 보자면

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!"); //줄바꿈 O
            Console.Write("Hello");            //줄바꿈 X
        }
    }
}

였습니다.

줄바꿈의 차이였었죠.

 

이후 [C#_3]에서 했던 변수 형태의 출력을 사용해보면

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            String str = "Hello World!";

            Console.WriteLine(str);
        }
    }
}

의 형식으로 변수에 담아 출력하는 것 이었습니다.


2. 입력문

입력문은 두 가지로 나뉩니다.

Console.Read() 와 Console.ReadLine() 인데요. 출력문에서 모양의 차이가 있던 것처럼 여기도 같은 차이가 있는 것 같네요! 하지만 이 두 가지의 기능은 현저히 차이가 납니다.

Console.Read() 는 '문자'를 받는 입력문

Console.ReadLine()은 "문자열"을 받는 입력문

이라는 부분에서 차이가 나는데요.

우선 Console.Read()를 알아보겠습니다.

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Write("정수를 입력해주세요 : ");
            int user = Console.Read();

            Console.WriteLine(user);
        }
    }
}

이 코드를 실행해보시면 제 설명과 다르게 무언가 어긋나 있는 것을 알 수 있습니다.

분명히 저희는 1을 입력받았고 출력 역시 1이 나와야 하는데 49라는 수가 나왔네요.

이는 '아스키 코드' 라는 것으로 컴퓨터가 자동 변환하는 것 때문인데요!

우리가 1이라고 명시한 수를 컴퓨터는 컴퓨터만의 언어인 49 라고 명시했기 때문입니다!

코드로 다시 보자면

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Write("정수를 입력해주세요 : ");
            int user = Console.Read();

            Console.WriteLine();

            Console.Write("입력한 user의 아스키 코드 : ");
            Console.WriteLine(user);
            Console.Write("입력한 문자 출력 : ");
            Console.WriteLine((char)user); //강제 형 변환
        }
    }
}

※ 1를 입력받고 컴퓨터가 아스키코드로  변환하는 것 까지 확인 

      이 후 강제 형변환을 통해 아스키코드 49를 문자로 변환시킨 코드와 결과

 

아스키 코드: https://terms.naver.com/entry.naver?docId=2270339&cid=51173&categoryId=51173

 

ASCII

초창기에는 다양한 방법으로 문자를 표현했는데, 호환 등 여러 문제가 발생했다. 이런 문제를 해결하기 위해 ANSI에서 ASCII(American Standard Code for Information Interchange)라는 표준 코드 체계를 제시했고

terms.naver.com

 

자 그럼 진짜 정수를 받고 싶다면 우리는 어떤 방식을 이용해야 할까요?

위 코드처럼 강제 형변환으로 일단 보이기는 원하는대로 보여주게 만들어도 컴퓨터가 사용하는 방식은

입력받기 ─> 아스키코드로 변환 ─> 강제형변환으로 인한 변환

이라서 우리가 원하는 '값'으로써의 역할을 하기 어렵습니다.

심지어 우리는 정수를 받거나 문자를 받을 때 한자릿수만 받는경우가 드물기도 하지요.

그래서 우리는 입력을 받을 때 문자열을 입력받는 Console.ReadLine() 을 사용할 것 입니다.

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Write("정수를 입력해주세요 : ");
            int user = int.Parse(Console.ReadLine());

            Console.WriteLine();

            Console.Write("내가 입력한 수 : ");//입력한 수가 그대로 나오는 것을 확인 할 수 있다.
            Console.WriteLine(user);

        }
    }
}

위 코드에서 문자열을 입력받는 Console.ReadLine() 를 int.Parse를 사용하여 

입력한 문자열을 정수로 바꾸어주는 것을 볼 수 있습니다.

(파싱에 관해서는 차후 다시 다룰 것 이기에 여기서는 넘어가도록 하겠습니다.)


3. 연산자 수식 연산자, 증감 연산자, 관계 연산자, 할당 연산자, 논리 연산자 등
3-1. 수식 연산자

수식 연산자에는 더하기, 빼기, 곱하기, 나누기, 나머지 를 구하는 식이 있습니다.

분류 기능
+ 피연산자 끼리의 덧셈 A + B
- 왼쪽 피연산자에서 오른쪽 피연산자를 뺄셈 A - B
* 피연산자 끼리의 곱셈 A * B
/ 왼쪽 피연산자를 오른쪽 피연산자로 나눗셈 A / B
% 왼쪽 피연산자를 오른쪽 피연산자로 나눈 후 나머지 A % B

위 표는 그 기능과 식을 정리한 것 입니다. 이를 코드로 보면

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            int A = 100;
            int B = 10;

            Console.WriteLine($"A + B : {A + B}"); //덧셈
            Console.WriteLine($"A - B : {A - B}"); //뺄셈
            Console.WriteLine($"A * B : {A * B}"); //곱셈
            Console.WriteLine($"A / B : {A / B}"); //나눗셈
            Console.WriteLine($"A % B : {A % B}"); //나머지

        }
    }
}

($은 문자열 보간으로 아래에서 설명하겠습니다.)

→결과


3-2. 증감연산자

증감연산자는 피연산자를 1만큼 증가시키는 증가연산자, 피연산자를 1만큼 감소시키는 감소연산자가 있습니다.

분류 기능
전위 증감 피연산자의 값을 1만큼 증가 A++;
피연산자의 값을 1만큼 감소 A--;
후위 증감 피연산자의 값을 1만큼 증가 ++A;
피연산자의 값을 1만큼 감소 --A;

위 표를 코드로 보자면

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 10;

            a++;

            Console.Write("전위 증가 :");
            Console.WriteLine(a);

            a--;

            Console.Write("전위 감소 :");
            Console.WriteLine(a);

            --a;
            Console.Write("후위 감소 :");
            Console.WriteLine(a);

            ++a;
            Console.Write("후위 증가 :");
            Console.WriteLine(a);

        }
    }
}

이 코드의 결과는

언뜻 보면 다른게 없어보이지만 전위증감과 후위증감은 큰 차이가 있습니다.

전위증감은 우선 피연산자의 값을 증가시키거나 감소시킨 뒤 문장을 실행하고

후위증감은 문장을 먼저 실행하고 피연산자의 값을 증가시키거나 감소시킨다는 것입니다.

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 5;
            int b = 5;

            Console.WriteLine($"a - b : {a - b}");

            Console.WriteLine($"--a - b: {--a - b}");
            //문장 실행전에 1을 감소하고 문장을 실행시킴
            
            a++;//a복구
            Console.WriteLine();
            
            
            Console.WriteLine($"a-- - b : {a-- - b}");//후위
            //문장을 실행하고 1을 감소시킴
            Console.WriteLine($"(a - b : {a - b}");

        }
    }
}


3-3. 관계 연산자

관계 연산자는 두 피연산자간의 관계를 나타내며 결과는 Boolean 값으로 도출해줍니다.

분류 기능
< 왼쪽 피연산자가 오른쪽 피연산자 보다 작으면 True 크면 False A < B
> 왼쪽 피연산자가 오른쪽 피연산자 보다 크면 True 작으면 False A > B
== 양쪽 피연산자가 서로 같으면 True 다르면 False A == B
!= 양쪽 피연산자가 서로 다르면 True 같으면 False A != B
>= 왼쪽 피연산자가 오른쪽 피연산자와 같거나 크면 True 작으면 False A >= B
<= 왼쪽 피연산자가 오른쪽 피연산자와 같거나 작으면  True 크면 False A <= B

이를 코드로 활용해보면

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 5, b = 10;


            Console.WriteLine(a < b); // 5 < 10, True
            Console.WriteLine(a > b); // 5 > 10, False
            Console.WriteLine(a == b); // 5 == 10, False
            Console.WriteLine(a != b); // 5 != 10, True
            Console.WriteLine(a >= b); // 5 >= 10, False
            Console.WriteLine(a <= b); // 5 <= 10, True

        }
    }
}

이렇게 boolean값을 확인할 수 있습니다.


3-4. 대입연산자

왼쪽 피연산자에 오른쪽 피연산자를 대입하는 연산자입니다.

우리가 기본적으로 알고있는 대입은 '=' 하나입니다. 변수에 값을 줄 때 사용하고있었는데요.

int a = 10;

대입연산자는 이처럼 대입해줄 때 대입과 동시에 연산을 진행하는 것을 말합니다.

분류 기능
= 오른쪽 피연산자를 왼쪽 피연산자에 할당 A = B
+= 왼쪽 피연산자에 오른쪽 피연산자를 더하고 그 값을 왼쪽 피연산자에 할당 A += B
-= 왼쪽 피연산자에 오른쪽 피연산자를 빼고 그 값을 왼쪽 피연산자에 할당 A -= B
*= 왼쪽 피연산자에 오른쪽 피연산자를 곱하고 그 값을 왼쪽 피연산자에 할당 A *= B
/= 왼쪽 피연산자에 오른쪽 피연산자를 나누고 그 값을 왼쪽 피연산자에 할당 A /= B
%= 왼쪽 피연산자에 오른쪽 피연산자를 나눈 나머지를 구하고
그 값을 왼쪽 피연산자에 할당
A %= B
namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 10, b = 5;

            a += b;
            Console.WriteLine(a); // a = 10 + 5; 결과: 15
                                  //    (a) + (b)
            a -= b;
            Console.WriteLine(a); // a = 15 - 5; 결과: 10
                                  //    (a) - (b)
            a *= b;
            Console.WriteLine(a); // a = 10 * 5; 결과: 50
                                  //    (a) * (b)
            a /= b;
            Console.WriteLine(a); // a = 50 / 5; 결과: 10
                                  //    (a) / (b)
            a %= b;
            Console.WriteLine(a); // a = 10 % 5; 결과:0
                                  //    (a) % (b)
        }
    }
}


3-5. 논리 연산자

논리연산자는 위 관계연산자 처럼 그 값이 Boolean값으로 나옵니다.

 

종류는 3가지고 And 연산자 , Or연산자, Not 연산자 가 있습니다.

And연산자 ( 논리곱 연산자 = && )
A B A && B
참(True) 참(True) 참(True)
참(True) 거짓(False) 거짓(False)
거짓(False) 참(True) 거짓(False)
거짓(False) 거짓(False) 거짓(False)

A와 B 모두 True 여야 결과가 True인 것을 알 수 있다.

 

Or 연산자 ( 논리합 연산자 = || )
A B A || B
참(True) 참(True) 참(True)
참(True) 거짓(False) 참(True)
거짓(False) 참(True) 참(True)
거짓(False) 거짓(False) 거짓(False)

Or 연산자는 두 피연산자중 하나라도 True 라면 True이다.

 

Not 연산자 ( 부정연산자 = ! )
A !A
참(True) 거짓(False)
거짓(False) 참(True)

Not 연산자는 피연산자가 True 라면 False를 도출하고

피연산자가 False라면 True를 도출한다.

 

위 표들을 코드로 보자면

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 10, b = 5;

            Console.WriteLine(a > 5 && b > 10); // True && False; 결과: False
            Console.WriteLine(a >= 10 || b >= 10); // True || False; 결과: True
            Console.WriteLine(!(a < b)); // !(False) 결과: True
        }
    }
}

로 모든 결과가 Boolean으로 도출된 것을 볼 수 있습니다.


3-6. 비트 연산자

비트연산자는 비트를 다루는데에 사용되는 연산자입니다.

논리연산자와 마찬가지로 3가지로 나뉘며 종류 역시 And 연산자, Or연산자, Not 연산자 로 같습니다.

비트연산자 ( & , | , ^ ) 
분류 기능
& 두 피연산자의 대응되는 비트에 논리곱(AND) 수행 A & B
| 두 피연산자에 대응되는 비트에 논리합(OR) 수행 A | B
^ 두 피연산자와 대응되는 비트에 베타적 논리합(XOR) 수행 A ^ B
  • & 연산자는 양쪽 비트가 모두 1이어야만 결과가 1이 되고, 그렇지 않으면 결과가 0이 됩니다.
  • | 연산자는 양쪽 비트 중 하나라도 1이면 결과가 1이 됩니다.
  • ^ 연산자는 양쪽 비트가 서로 달라야 결과가 1이 됩니다.
namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 5, b = 10;

            Console.WriteLine(a & b);
            Console.WriteLine(a | b);
            Console.WriteLine(a ^ b);
        }
    }
}

→ 결과

→이유!

사실 비트연산자는 이 이유를 알아야 왜 이 값이 나오는지 알게되는데

이 칸들을 좌측부터 128  64  32  16  8  4  2  1 의 8칸입니다. (2진수)

1로 표기되어있는 칸들의 수를 더하면 15라는 값이 나온것을 알 수 있습니다.


4. 문자열 보간

문자열 보간($) ?

문자열 보간이라는 것은 우리의 출력 코드가 평소

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            string a = "one";
            string b = "two";

            Console.WriteLine("숫자 1은 영어로 {0}, 숫자 2는 영어로 {1}", a, b);
            // 결과: 숫자 1은 영어로 one, 숫자 2는 영어로 two
        }
    }
}

이런식으로 작동 하고 있었다면 

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            string a = "one";
            string b = "two";

            Console.WriteLine($"숫자 1은 영어로 {a}, 숫자 2는 영어로 {b}");
            // 결과: 숫자 1은 영어로 one, 숫자 2는 영어로 two
        }
    }
}

Console.WriteLine 이후 ()의 내부 "" 의 외부에 $ 기호를 붙혀서 더욱 간편하게 사용할 수 있도록 하는 것 입니다.

  • Console.WriteLine() 사용시 내부에 "" 를 넣는다
  • -> Console.WriteLine(" ")
  • 큰 따옴표 외부에 $를 넣는다.
  • -> Console.WriteLine($" ")
  • 내부에 적고싶은 문자들의 결합을 적는다.
  • -> Console.WriteLine($" 숫자 1은 영어로 ")
  • 변수를 적고싶다면 문자열 내부에 {} 로 경계를 만들어 넣어준다
  • -> Console.WriteLine($" 숫자 1은 영어로 {a} ")

'C#' 카테고리의 다른 글

[C#_6] 반복문(for,foreach,while,do while)  (0) 2021.09.24
[C#_5] 조건문 (if, else, switch)  (0) 2021.09.23
[C#_3] 변수, 자료형  (0) 2021.09.12
[C#_2] 콘솔 출력  (0) 2021.09.07
[C#_1] C# 설치  (0) 2021.09.07
1.변수

 

저번 시간에는 출력에 관하여 코딩을 배워보았습니다. 이번 시간에는 변수와 자료형에 관하여 배워보도록 하겠습니다.

변수와 자료형에 관해서 배우려면 우선 변수를 알아야 하는데 이 [변수라는 것은 상자와 같습니다.]

각 변수는 하나의 값을 담을 수 있으며 그 값은 계속 변할 수 있습니다.

그리고 그 값에 따라 변수의 형태 (Type) 가 정해지게 됩니다.

이러한 부분에 대해 코드로 보자면

int a;
double b;
char c;

와 같은 형태로 볼 수 있는데 코드를 해석해보자면

 

(변수의 형태) (변수 이름) ; 으로 해석할 수 있습니다.

int 라고 하는 변수 형태에 [a라는 이름으된 상자]를 마련했다고 생각하면 편합니다.

 

이러한 상자에는 값을 담을 수 있는데 그 형태를 코드로 보자면

int a = 1;
double b = 1.2;
char c = 'A';

※코드를 보면  '=' 이라는 표시가 있는데 이는 수학의 '=' 과는 다른 의미 입니다.

   수학에서 '=' 은 '같다' 의 의미지만 코딩에서 '='은 [왼쪽에 있는 값을 오른쪽의 변수(상자)에 담는다.]는 의미 입니다. 

 

이 코드를 해석해보면

(변수의 형태) (변수의 이름) = 1

(변수의 형태) (변수의 이름) = 1.2;

(변수의 형태) (변수의 이름) = 'A';  인 것입니다.

 


2. 자료형

기본 자료형(Primitive Data Type) : 개발자가 별도의 코드를 만들지 않아도 언어에서 자체적으로 제공하는 데이터 형식

자료형 형식 범위 크기 부호
sbyte System.Sbyte -128~127 (0을 포함하기 때문) 8bit (1byte) O
byte System.Byte 0~255 8bit (1byte) X
short System.Int16 -32,768 ~ 32,767 16bit (1byte) O
ushort System.Uint16 0 ~ 65,535 16bit (1byte) X
int System.Int32 -2,147,483,648~2,147,483,647 32bit (1byte) O
uint System.UInt32 0 ~ 4,294,967,295 32bit (1byte) X
long System.Int64 -9,223,372,036,854,775,808 ~
 9,223,372,036,854,775,808
64bit (1byte) O
ulong System.UInt64 0 ~ 18,446,744,073,709,551,615 64bit (1byte) X
float System.Single ±1.5e-45 ~ ±3.4e38 4byte





double System.Double ±5.0e-324 ~ ±1.7e308 8byte
decimal System.Decimal ±1.0 × 1028  ±7.9 × 1028 16byte
char System.Char U+0000 ~ U+ffff 유니코드 16bit
string System.String   8bit (1byte)
bool System.Boolean   8bit (1byte)

 


2-1. 정수 자료형

 

using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            byte a = 200;
            sbyte b = -126;
            short c = 30000;
            ushort d = 40000;
            int e = 100000000;
            uint f = 1000000000;
            long g = 1000000000000000000;
            ulong h = 10000000000000000000;

            Console.WriteLine(a);
            Console.WriteLine(b);
            Console.WriteLine(c);
            Console.WriteLine(d);
            Console.WriteLine(e);
            Console.WriteLine(f);
            Console.WriteLine(g);
            Console.WriteLine(h);
        }
    }
}

위 코드는 정수 자료형 (byte, sbyte, short, ushort, int, uint, long, ulong) 에 관한 입력과 출력입니다.

 

설정해둔 숫자 외에 추가로 0을 붙이거나 1을 올려서 적으면 오버플로우나 언더플로우가 발생하게 됩니다.

 

※ 오버플로우 : 데이터 형식의 범위를 넘어가는 값일 경우 오버플로가 발생하여 제일 작은 음수 값으로 넘어가는 것.

※ 언더플로우 : 데이터 형식의 범위를 넘어가는 값일 경우 언더플로가 발생하여 제일 큰 양수 값으로 넘어가는 것.

 

 

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
           byte a = 255;
           sbyte b = -128;

            a++;//실행시 오버플로우가 발생하여 0부터 시작
            b--;//실행시 언더 플로우가 발생하여 128부터 시작

            Console.WriteLine(a);
            Console.WriteLine(b);
        }
    }
}

위 코드를 실행시켰을 때 우리는 a값에는 오버플로우가 발생하는 것을 b값에는 언더플로우가 발생하는 것을 볼 수 있습니다.

오버플로우 , 언더플로우 발생 모습


2-2. 실수 자료형
using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            float a = 123.567891011f;
            double b = 1234.567878910111213;
            decimal c = 1234.56789101112131415161718m;

            Console.WriteLine(a);
            Console.WriteLine(b);
            Console.WriteLine(c);
        }
    }
}

위 코드는 실수 자료형 (float, double, decimal) 을 입출력 하는 코드입니다.

정수 자료형의 코드와 비슷해보이지만 잘 보면 다른게 있는데 바로 float자료형의 값의 끝에는 f가 붙고

decimal 자료형의 끝에는 m이 붙어있는 것을 볼 수 있습니다.

C#의 실수 자료형의 기본은 double 이며 자료값에 f, m 을 붙히지 않으면 double 자료형으로 인식이 되는데 이를 방지하고 '이 자료는 float의 형태입니다.' 또는 'decimal의 형태입니다.'를 나타내어 주기 위해서는 f,m을 반드시 붙혀야합니다.

 

만약 이를 제거하고 실행하게 될 시

라고하는 오류를 볼 수 있으므로 꼭 float 자료형에는 'f', decimal자료형에는 'm'을 붙혀주셔야 합니다.


2-3. 문자, 문자열 자료형
namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            char a = 'A';           //문자
            String b = "Hello!";    //문자열
            
            
            Console.WriteLine(a);
            Console.WriteLine(b);
        }
    }
}

※문자(char) : 문자는 'A' , 'b' , 'a' , '!' 등과 같은 단일 기호를 말한다.

※문자열(String) : 문자열은 "Hello" , " World !" 와 같은 두개 이상의 문자 조합으로 만들어진 것이다.

 

문자와 문자열의 구분은 반드시 해주어야 하는데 이를 

작은 따옴표 '  ' (문자) 큰 따옴표 "  " (문자열)로 구분해주어야 합니다.


2-4. 논리 자료형
namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            bool a = true;
            bool b = false;

            Console.WriteLine(a);
            Console.WriteLine(b);
        }
    }
}

논리(boolean) 자료형은 참과 거짓을 나타내는 자료형입니다.

보시면 문자열(String) 자료형과 같이 비슷하게 문자열 값을 그대로 도출하는 것 처럼 보이실 수 있겠지만

따옴표의 존재 없이 변수에 참(true) 과 거짓(false)를 담고 있습니다.


2-5. 객체(object) 자료형

객체(object) 자료형은 각각의 존재를 다루는 것 입니다.

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            object a = 12345678910; //정수
            object b = 12345.678910;//실수
            object c = true;        //논리
            object d = "안녕하세요";//문자열

            Console.WriteLine(a);
            Console.WriteLine(b);
            Console.WriteLine(c);
            Console.WriteLine(d);
        }
    }
}

코드에서 볼 수 있는 것 처럼 Object 안에는 정수, 실수, 논리, 문자열 이 모두 들어가 있고 제대로 출력되고 있습니다.

※모든 자료형이 가능

이렇게 사용 할 수 있는 이유는 object(객체 자료형)가 모든 자료형의 조상격이라고 할 수 있기 때문입니다.

(※object라는 것에 대해서 제대로 이해하기 위해서는 객체, 클래스에 대한 이해가 동반되어야 하기에

      차후 추가로 설명하도록 하겠습니다.)


여기까지 C# 변수와 자료형에 대해 다루어보았습니다.

다음 게시물은 C# "출력문" 입니다. 

'C#' 카테고리의 다른 글

[C#_6] 반복문(for,foreach,while,do while)  (0) 2021.09.24
[C#_5] 조건문 (if, else, switch)  (0) 2021.09.23
[C#_4] 출력문, 입력문, 연산자, 문자열 보간  (0) 2021.09.21
[C#_2] 콘솔 출력  (0) 2021.09.07
[C#_1] C# 설치  (0) 2021.09.07

[C#_1] 에서 프로그램 다운로드를 배웠다면 오늘은 새 프로젝트 만들기와 콘솔 출력을 배워볼 것 입니다.

vs2019 새 프로젝트 만들기

 

새 프로젝트 만들기를 클릭하면 나오는 창 ↓

[카테코리 창에 C# -> Windows -> 콘솔] 을 선택 후 아래 나오는 [콘솔 앱] 을 선택.

새 프로젝트 구성 창에서 [프레임 워크의 버전을 확인]하고 [만들기]

 

위 단계를 전부 완료하면 나오는 창

창이 이렇게 나왔다면 완성이다.

 

 

1. 코드 작성 - 출력

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}

위 코드와 같이 static void Main(string[] args) 내부에 

Console.WriteLine("Hello World!") 를 입력합니다.

 

이 후 [Ctrl + Shift + B] 를 누르거나, 상단 메뉴에 [빌드 -> 솔루션 빌드] 를 눌러

코드에 문제가 있는지 없는지 검사해줍니다.

성공시
실패시

성공 하면 빌드 성공에 1이 올라가며 실행 가능하다고 나온다. [실행 : Ctrl + F5]

이를 실행해보면

Hello World! 가 출력되는 것을 볼 수 있다.

 

 

2. 코드 작성 - 출력 2

 

콘솔 출력에는 한가지 방법이 더 있는데 이는 Console Write() 이다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Write("Hello World!");
        }
    }
}

Console Write() 의 경우는 WriteLine 과 다른것이 있는데 바로 줄바꿈이다.

Console Write("Hello world!")를 출력 해보면 Console.WriteLine("Hello World!")

와 다르게 줄바꿈 없이 출력되는 것을 볼 수 있다.

이렇게 출력했다면 성공이다.

'C#' 카테고리의 다른 글

[C#_6] 반복문(for,foreach,while,do while)  (0) 2021.09.24
[C#_5] 조건문 (if, else, switch)  (0) 2021.09.23
[C#_4] 출력문, 입력문, 연산자, 문자열 보간  (0) 2021.09.21
[C#_3] 변수, 자료형  (0) 2021.09.12
[C#_1] C# 설치  (0) 2021.09.07

+ Recent posts