c# 시간비교하기 datetime과 timespan 이용... 여러가지 비교

이거가지고 삽질 많이 했는데....
딱 이거다 하는 자료가 거의 안 보였었다.

우리나라 C#하는 사람들이 별로 없어서 그런걸까..
C#을 하는 사람이 없다기보다는.. C#으로 윈도우 프로그램을 만드는 사람이 별로 없는 것 같다.
델파이보다 오히려 더 적을지도...
아마추어들이 하려면 C++에 api mfc 핥아먹고 바로 C#으로 넘어오는 편이 더 나을 것 같은데...

--------

private void button1_Click(object sender, EventArgs e)
{
  TimeSpan asef = new TimeSpan(15,30,00);
  Console.WriteLine(asef);
  Console.WriteLine(DateTime.Now.Add(asef));//현재시간에 15시간을 더하기
  Console.WriteLine(DateTime.Now.TimeOfDay);//0시부터 현재시간까지를 TimeSpan값으로 반환
  Console.WriteLine(TimeSpan.Parse("15:30:00"));//TimeSpan값을 지정.. 문자열
}
DateTime과 TimeSpan 둘 다 시간을 표현한다.
다른점은...
DateTime은 몇월몇일몇시몇분을 달력이나 시계를 표현하고
TimeSpan은 1시간, 2시간,,,... 이런걸 표현한다고 할까..
시간과 시각?
전자시계 개념으로 설면하자면... 10분짜리 타이머를 맞춘다면... 
TimeSpan.. 알람을 맞추면..DateTime이렇게 보면 쉬울까...
DateTime - DateTime은 TimeSpan자료형이 된다.
(DateTime)2011년 2월 16일 21시 - (DateTime)2011년 2월 16일 15시 = (TimeSpan)6시간
위의 소스코드만으로도 설명은 충분할 것 같지만.... 추가하자면...
8시부터 뭔가를 실행시키고 싶다! 라고 한다면....
타이머 돌리고... System.Windows.Forms.Timer fajklefjl = new [tab] ();
if(DateTime.Now.TimeOfDay >TimeSpan.Parse("08:00:00"))
{}
 

C# Stream - FileStream, MemoryStream, NetworkStream, GZipStream

스트림의 종류들

FileStream
Close()
Read()
Seek()
Write()
MemoryStream
Close()
Read()
Seek()
Write()
NetworkStream
Close()
Read()
Seek()
Write()
GZipStream
Close()
Read()
Seek()
Write()

FileStream은 바이트 형태로 파일을 작성
문자열을 바이트 배열로 변환해야함
마지막에 파일을 닫아주지 않으면 다른 프로그램이 파일을 사용하지 못함

StreamWriter의 Write()와 WriteLIne()메소드를 호출해서 해겨

StreamWriter사용예

StreamWrite sw= new StreamWriter(@"C:\filename.txt"); //쓰기스트림
StreamReader sr = new StreamReader(@"C:\readfile.txt"); //읽기스트림
sw.WriteLine("쓰고싶은말들");
sw.Write("jlasdjlksdf");
sw.WriteLine("사과는 #{0} 껌은#{1}", apple, gum);
sw.Close();//sw닫기
sr.Close();//sr닫기
//닫는거 잘 확인해야됨

CryptoStream //스트림을 암호화하는 기능.. 암호화해서 다른 스트림으로 전송하는데 사용
Close()
Read()
Seek()
Write()

name space System;
public inerface IDisposable();
void Despose();

-BinaryReader

C#의 데이터 타입(Data Type)과 변수(Variable) 상수(Constant) 할당(Assignment)

- 데이터 타입 : 메모리를 생성하기 위한 기준
메모리의 크기Size와 형태Type 지정
예. int의 크기 : 4바이트, 형태 : 정수형 비트 조합

- 변수 : 데이터 타입에 따른 값이 입력될 수 있는 메모리공간
변수의 이름 : 식별자
변수명은
'_' 언더바로 시작해야한다.
첫번째 문자는 숫자가 아닌 문자
대소문자 구분

상수는 값을 바꿀 수 없는 변수

int a = 1;
a에 1을 할당 했음

........대강이정도

define 매크로와 inline 함수

매크로 함수

#define PI 3.14
#define SQUARE(x) ((x)*(x))

result=SQUARE(5);

result=SQUARE((5)*(5));
로 교체된다.

C++에서 in-line화

inline int ADD(int x, int y)
{
 return x+y;
}
int main()
{
 std::cout<<ADD(2,3)<<std::endl;
 return 0;
}

매크로를 이용한 함수의 in-line은 전처리기에 의해서 처리
키워드 inline을 이용한 함수의 inline은 컴파일러에 의해서 처리 - inline이 성능에 안좋다고 판단되면 무시

레퍼런스 = Reference = 참조

같은 &를
int &ref = val; //레퍼런스 선언에 사용
int *pval = &val; //포인터 주소값을 가져오는데 사용

int &ref = val;
val과 ref는 같은 것이다. 하나의 이름이 더 생긴것..

int &ref1 = val;
한개 더 선언해도 됨

int &ref2 = ref1;
레퍼런스로 레퍼런스를 선언해도 됨? 될듯

레퍼런스를 활용한 Call-By-Reference

71p
포인터를 이용한 Call-By-Reference도 가능하지만..

void swap(int *a, int *b);
//포인터를 통해 함수에 값을 전달한다.
a의 값을 변경할 때 *a라고 쓰는것도 귀찮고,
작은 조작 실수로 에러가 잘 발생한다.
가능하지만 좀 불편하다.

그래서 좀 더 안전한

레퍼런스를 이용한 Call-By-Reference를 사용

void swap(int &a, int &b);
//값을 레퍼런스로 받는다.
int main(void)
{
swap(val1, val2)
...
}

Call-By-Value는 값을 전달한다.
데이터의 복사가 발생해서 비효율적이다.
int swap(int a, int b);
인 경우에는 int값 2개를 받고 1개를 내보내지만
구조체일 경우에는 값이 커진다.

typedef struct _Account
{
    int id;
    int balance;
    char name[100];
} Account;
형태로 구조체가 선언된 상태에서..

Account ShowData(Account p) //구조체로 입력받고 구조체로 반환하려면 큰 값이 복사가 발생한다.
void ShowData(Account &p) //레퍼런스로 하면 편하기도 하고 속도도 빠르다.

레퍼런스로 리턴하는 방법
int &increment(int &val)
{
  val++;
  return val;
}
int main(void)
{
..........
 int &ref=increment(n)
........}

위 예는 main함수에서 전달받은 레퍼런스값을 반환 하는거고...
지역변수로 선언됐다면 레퍼런스로 반환할 수 없다. 80p
지역변수는 함수가 없어질 때 없어지기 때문에 레퍼런스로 반환하면 갈 길을 잃게된다.

malloc - free → new - delete , 그리고

cin<<size; //할당할 배열의 크기
int* arr=(int*)malloc(sizeof(int)*size);
arr의 포인터를 선언해서 재미보고
free(arr);
풀어준다.

왜 이따위로 복잡하게 만들었는지... 외웠는데 기억도 잘 안난다.
그냥 쓸때마다 찾아봐야지

int i, j
arr[i][j];로 쓸 수 있게 해놓음 편하잖아
컴파일러에서 자동으로 매크로처럼 돌려주면 좋을 것 같은데..

c++ 에서는 조금 더 편해졌다.

int * val = new int;
//포인터까지는 동일한데 new int로 쉽게 메모리를 할당한다.
int형태로 하니까 sizeof도 필요없고..

int * arr = new int[size];
// size는 배열의 사이즈.. 앞에서 입력받는다. cin<<size;
구조체 선언
typedef struct Person
{
 name[100];
 num[100];
} Person;

Person * arr= new Person[size];
//구조체도 가능..하겠지?

반환방법도 간단
delete val;
delete []arr;
delete []Person;

new연산자 메모리 할당 성공 실패 체크

new는 메모리 연산을 실패할 경우 NULL포인터를 리턴한다.
if(arr==NULL)
{
  cout<<"메모리 할당 실패"<<endl;
  return -1; //프로그램 종료
}

프로그램에 if가 들어가서 시스템 효율만 떨어뜨린다.

그래서...p88
#define DEBUG 1 //테스트시 1로...
//#define DEBUG 0  //최종 버전 컴파일시 0으로..

#if DEBUG==1
  cout<<"디버그 모드 "<<endl;
  if(arr==NULL)
  {
    cout<<"메모리 할당 실패"<<endl;
    return -1;
  }
#endif

#if, #endif는 컴파일 단계에서 DEBUG가 1이면 저걸 컴파일 하라는 전처리 명령 1이 아니면 컴파일 하지 않고 넘어간다.

헤더 파일을 이용한 파일 분할

Door.h
#include <iostram>
using std::cout;
using std::endl;

const int OPEN=1;
const int CLOSE=2;

class Door
{
private:
    int state;

public:
    void Open();
    void Close();
    void ShowState();
}

Door.cpp
#include"Door.h"
void Door::Open()
{
    state=OPEN;
}
void Door::Close()
{
    state=CLOSE;
}
...........생략
}

Main.cpp
#include"Door.h"

int main()
{
    Door d;

    d.Open();
    d.ShowState();

    return 0;
}

정보은닉Information Hiding, 캡슐화Encapsulation

기본 속성은 private로 되어 있다.
class Larbor
{
 int pay;
 int time;
};
라고 해 놓으면 pay와 time은 private속성을 갖는다.

class Larbor
{
private:
int pay;
int time;
public:
int SetPay(int a);
int SetTime(int a);
int GetPay(int a);
int GetTime(int a);
}

변수들을 외부에서 직접 접근을 할 수 없게 만든다.
public으로 공개된 함수를 통해서만 변수를 조작할 수 있다.

Get,Set으로 시작하는 함수들은 멤버 변수로 접근하기 위한 함수로 엑세스(Access) 메소드(함수) 라고 부른다.

캡슐화 Encapsulation
: 관련있는 데이터와 함수를 한 덩어리로 묶는것
그냥 함수랑 변수랑 관계있는걸 다 묶는거다.
캡슐화의 필요성은 : p132