HW1

연습문제 (1)

단원 : C# 기초

목표 : C# 프로그램 기초

주요 연습 내용 : Visual Studio 2010, C# 입출력, 변수, 메소드, 제어문 사용 연습

준비자료 : TodayMoneyExchangeConverter.cs

   1323862212.hwp

연습문제 Ex1 (Due by 9/28 24시까지)

-cyber 강의실 (cyber.dku.edu)source code, executable file, solution/project VC# file, 보고서를 학번_이름_Ex1.zip으로 묶어서 낼 것. 보고서 (30%)

[연습문제]

0. Visual C# Console Application의 프로젝트를 생성한다.

1. 오늘의 환율 계산기 TodayMoneyExchangeConverter 클래스를 작성하라. (30%)

– enum Currency { KRW, USD, JPY, EUR };를 사용
– enum ExchangeMethod { BASIS, SELL, BUY };를 사용
– void GetKeyboardInput() 함수는 콘솔창에서 키보드로 통화, 환율기준, 환전금액을 입력받아서 처리

+ 힌트: while 문을 사용하여 미국/일본/유럽연합 또는 USA/JAPAN/EURO 아닌 경우 다시 입력을 받음 마찬가지고 while 문을 사용하여 매매기준율/팔때/살때 또는 BASIS/BUY/SELL 아닌 경우 다시 입력을 받음
+ 힌트: Console.ReadLine() 함수는 string을 반환하므로, double로 변환하기 위하여 TryParse 함수 사용 => boolValue = double.TryParse(string, out doubleValue)

CurrencySign GetCurrencySignFromName(string str) 메소드는 USD/JPY/EUR 하나를 반환
ExchangeMethod GetExchangeMethodFromString(string str) 메소드는 BASIS/BUY/SELL 하나를 반환
– double GetTodayCurrencyExchangeRateBy(string name, ExchangeMethod exchange) 메소드는 통화와 환율기준으로 네이버 오늘의 환율시세에서 찾아서 반환
– void Print()
메소드는 환전된 금액을 화면에 출력

2. Main 함수에서는 TodayMoneyExchangeCalculator 객체를 생성하고 키보드 입력으로, 환전하려는 통화(미국/일본/유로), 환율기준(매매기준율/외화를 살 때/외화를 팔 때)를 입력받아서 환율시세를 찾고 환전금액()을 계산하여 환전된 금액(입력에 따라서 USD/JPY/EUR)을 출력하는 routine 등을 추가한다. (20%)
– do..while 문을 사용하여 다른 사람을 하려면 다시 처음으로 돌아갈 수 있도록 함

3. Main 함수에서 본인이 더 테스트해보고 싶은 TodayMoneyExchangeConverter 클래스의 Methodroutine을 추가하라. (20%)
예를 들어, 출력을 테이블로 나타내어 보여준다거나
다른 통화들 (유로와 달러) 간의 환율 계산을 추가

Boxing과 Unboxing을 최소화하라

Boxing은 값 형식 (value type)을 참조 형식 (reference type)으로 변경하는 것이다.
Boxing을 수행하면 힙 상에 새로운 reference type 객체가 생성되고 value type의 객체가 가지고 있던 값이 reference type 객체 내부로 복사된다.
새로 생성된 reference type 객체는 내부적으로 value type 객체의 복사본을 포함하고, value type에서 제공하였던 interface를 그대로 재구현한다.

Unboxing은 참조 형식 (reference type)을 값 형식 (value type)으로 변경하는 것이다.
만약 reference type 객체 내부에 포함된 value type 객체의 값을 얻고자 시도하면 복사본을 만들어서 돌려준다.

Console.WriteLine(“Numbers: {0}, {1}, {2}”, 10, 20, 30);
Console.WriteLine()은 System.Object의 배열을 인자로 받는데, 정수들은 모두 value type이기때문에 value type의 인자로 전달하기 위해서는 reference type으로 boxing이 수행된다.
Boxing과 Unboxing 동작은 필요시 자동적으로 일어나며, 이 과정에서 컴파일러는 어떠한 경고도 발생시키지 않는다. WriteLine(…)을 호출할 때에는, 아래와 같이 value type을 string type instance로 변경하는 것이 좋다.
Console.WriteLine(“Numbers: {0}, {1}, {2}”, 10.ToString(), 20.ToString(), 30.ToString());
이 코드는 string type을 사용하기 때문에 value type들은 더이상 System.Object 로 변경되지 않는다.

Instance Method vs Static Method

Static Method (일면 Class Method)
-메서드 선언에 static 한정자가 있는 경우 해당 메서드를 정적 메서드라고 한다.
-정적 메서드는 class method나 static member field 조작을 위한 메소드이다.
-정적 메서드 내에서 클래스의 instance field나 method는 접근 불가능하다.
-정적 메서드는 특정 인스턴스에서는 작동되지 않으므로, 정적 메서드 내에서 this를 참조하면 컴파일 타임 오류가 발생한다.

Instance Method
-인스턴스 메서드는 클래스의 지정된 인스턴스에서 작동한다.
-인스턴스 메서드 내에서는 this로 액세스할 수 있다.

class ValueClass
{
private int value = 0;
public void setValue(int value) { this.value = value; }
public int getValue() { return this.value; }
public void print() { Console.WriteLine(“value={0}”, this.value);
public static void printString(string str) { Console.WriteLine(str); }
}
class Program
{
static void main(string[] args)
{
ValueClass c = new ValueClass();
c.setValue(10); // 인스턴스 메소드
c.print(); // 인스턴스 메소드
ValueClass.printString(“test”); // 정적 메소드 (클래스명.정적메소드명)
}
}

 

Person Struct (in C#)


// Person.cs
using System;


namespace PersonStructCsharp
{
    struct Person
    {
        // instance member field
        public string name;
        public int age;


        // constructor & destructor
        public Person(string n, int a) { this.name = n; this.age = a; }


        // method
        public void SetName(string n) { this.name = n; }
        public void SetAge(int a) { this.age = a; }


        public void Print() { Console.WriteLine(“Name={0} Age={1}”, this.name, this.age); }        


        public string GetName() { return this.name; }
        public int GetAge() { return this.age; }


    }
}




// PersonStructCsharp.cs
using System;

namespace PersonStructCsharp
{
    class PersonStructCsharp
    {
        static void Main(string[] args)
        {
            Person p1; // 멤버변수가 public일경우 Person p1으로 사용가능하나
            p1.name = “고소영”; // 반드시 모든 멤버변수의 값을 초기화해야함
            p1.age = 5;         // 멤버변수가 모두다 초기화되지 않음 사용불가능
            p1.Print();           // 멤버변수가 초기화가 되야 비로소 멤버함수도 사용가능


           // 일반적으로 C#에서 struct을 사용하는 형태
           // 단 default construct 경우, string은 null로, int는 0으로 초기화를 함
            p1 = new Person();            
            p1.Print();
            p1.SetName(“이나영”);
            p1.SetAge(10);
            p1.Print();


           // 더욱 일반적으로 C#에서 struct을 사용하는 형태
            Person p2 = new Person(“소간지”, 20);
            p2.Print();
        }
    }
}

Person Struct (in C++)


// person.h
#ifndef __PERSON_H__
#define __PERSON_H__
#include <string>


struct Person 
{
public:
 // constructor & destructor
 Person() : name(“”), age(0) {}
 Person(std::string n, int a) : name(n), age(a) {}
 ~Person() {}


 // member function
 void SetName(std::string n);
 void SetAge(int a);
 void Print();


protected:
 // member variable
 std::string name;
 int age;
};


#endif




// person.cpp
#include <iostream>
#include “Person.h”


void Person::SetName(std::string n)
{
 name = n;
}


void Person::SetAge(int a)
{
 age = a;
}


void Person::Print()
{
 std::cout << “Name=” << name << ” Age=” << age << std::endl;
}



// main.cpp
#include <iostream>
#include “Person.h”
void main()
{
 Person p1(“고소영”, 5);  // 인스턴스 생성 (초기화)
 Person *p2;
 p1.Print();     // 고소영, 5 출력

 p1.SetName(“이나영”);  // 이름 지정
 p1.SetAge(10);    // 나이 지정
 p1.Print();     // 이나영, 10 출력

 std::cout << std::endl;
 p2 = new Person;  // dynamic allocation
 if (p2) {
  p2->SetName(“소간지”);
  p2->SetAge(20);
  p2->Print();   // 소간지, 20 출력
 }
 delete p2;
}

Person Struct (in C)


/* person.h */
#ifndef __PERSON_H__
#define __PERSON_H__


typedef struct _Person
{
 char name[256];
 int age;
} Person;


void SetPersonName(Person * p, char * n);
void SetPersonAge(Person * p, int a);
void PrintPerson(Person p);


#endif




/*
person.cpp: implementation of the Person struct.
*/
#include <stdio.h>
#include <string.h>
#include “Person.h”


void SetPersonName(Person * p, char * n)
{
 strcpy((*p).name, n);
}


void SetPersonAge(Person * p, int a)
{
 (*p).age = a;
}


void PrintPerson(Person p)
{
 printf(“Name=%s Age=%d\n”, p.name, p.age);
}




/* main.cpp */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include “Person.h”


void main()
{
 Person p1;  /* 변수 값 초기화 필요 */
 Person * p2;


 strcpy(p1.name, “고소영”);
 p1.age = 5;
 PrintPerson(p1);    /* 현재 값 출력 */
 SetPersonName(&p1, “이나영”); /* 변수 값 지정 */
 SetPersonAge(&p1, 10);   /* 변수 값 지정 */
 printf(“\n”);
 printf(“p1.name = %s, p1.age = %d\n”, p1.name, p1.age);


 /* dynamic memory allocation */
 p2 = (Person *) malloc(sizeof(Person));
 if (p2) {
  SetPersonName(p2, “소간지”);/* 변수 값 지정 */
  SetPersonAge(p2, 20);  /* 변수 값 지정 */
  PrintPerson(*p2);   /* 현재 값 출력 */
  printf(“\n”);
  printf(“p2->name= %s, p2->age = %d\n “, p2->name, p2->age);
 }
 free (p2);
}


C# Struct

C++에서는 struct와 class간에 차이가 거의 없으며, 차이점은 아무런 명시를 하지 않았을 때 class는 멤버가 private 권한을 가지고, struct는 멤버가 public 권한을 가진다.

C#에서는 struct와 class가 유사하나 매우 다른 특징을 가진다.
-C# struct는 Value Type (값 형식)으로, 즉 stack영역에 데이터를 생성해서 사용함
-C# struct는 Default Constructor (기본생성자)나 Destructor(소멸자)선언할 수 없음
-C# struct는 다른 struct/class를 상속받을 수 없으며 파생시킬수도 없음 (따라서, protected는 선언할 수 없음)
-C# struct는 interface를 구현할 수 있음
-C# struct는 nullable type으로 사용할 수 있음
-C# struct는 일반적으로 new를 사용해서 객체를 생성하나 (예: Person p = new Person();),
stack영역에 데이터를 생성해서 사용함

public struct Point
     {
         int x = 1;  //Illegal: cannot initialize field
         int y;

         public Point() { } //Illegal: cannot have parameterless constructor
         public Point(int x) { this.x = x; } //Illegal: must assign field y
     }

  http://www.codeproject.com/Articles/8612/Structs-in-C