'분류 전체보기'에 해당되는 글 144건

  1. 2011.09.27 검색창의 숨겨진 기능들?!
  2. 2011.09.23 [MFC] 메인프레임을 얻어와서 View에 접근하기.
  3. 2011.09.21 [자료구조] 스택 ( stack ) 의 구현. 연결 자료구조.
  4. 2011.09.21 [자료구조] 스택 ( stack ) 의 구현. 순차 자료구조.
  5. 2011.09.21 [MFC] mfc로 툴만들기( 탭 컨트롤 ) - 2 2
  6. 2011.09.21 [MFC] mfc로 툴만들기( 탭 컨트롤 ) - 1
  7. 2011.09.21 코레일 어플 GLORY로 할인카드 적용하여 예매하기 2
  8. 2011.09.20 피자, 치킨이 비싼 이유가 따로 있었다?! 1
  9. 2011.09.15 [C,C++] 함수 오버로딩(Function Overloading)
  10. 2011.09.14 [C,C++] 디폴트(DeFault) 매개 변수
  11. 2011.09.14 [C,C++] 이름공간(namespace)
  12. 2011.09.14 [C,C++] 인-라인(in-line) 함수
  13. 2011.09.08 [자료구조] 스택(stack) 이란...
  14. 2011.09.07 인터넷으로 전기요금납부!
  15. 2011.09.06 [자료구조] 연결 자료구조
  16. 2011.09.06 [자료구조] 순차 자료구조 - 선형 리스트의 구현
  17. 2011.09.04 [자료구조] 순차 자료구조 - 선형 리스트.
  18. 2011.09.04 맹장염과 충수염??
  19. 2011.09.01 후쿠시마 원전 작업자 첫 사망.
  20. 2011.08.28 [C,C++] 가변 인자란 ...
  21. 2011.08.28 [C,C++] getchar() 의 문제점.. 2
  22. 2011.08.27 [C,C++] scanf 와 fgets
  23. 2011.08.27 화면 전환, cvFlip()
  24. 2011.08.27 인터넷으로 주민세 내기~ ( 감액 or 환급 받기 )
  25. 2011.08.26 금값 폭락?!
  26. 2011.08.26 대구 스타디움을 다시 갔다왔습니다...
  27. 2011.08.23 [C,C++] sprintf 사용하기... 2
  28. 2011.08.23 [C,C++] 문자열에 대하여...
  29. 2011.08.22 대구에 무지개가 떳습니다.~
  30. 2011.08.22 [C,C++] 배열의 초기화..
검색창의 숨겨진 기능들?!

우리가 흔히 써왓던 검색창 들에도 숨겨진 기능들이 있다고 한다...

아래의 기사에서 잘 설명이 되어있다..

기사 본문 보기

간단히 우리가 검색을 하다보면, 한 분야에 관련된 검색을 원할 때가 있다..

기본적으로 네이버에서는 통합검색을 하지만,

블로그만 보고 싶다던지, 카페, 이미지만 검색을 하고 싶을 수도 있다..

그럴 떄는..

검색어에.을 찍고 해당 분야를 적으면 된단다..

검색어.이미지 이렇게 입력하고 검색하면 이미지에 관련된 검색만 해주는 식이

다.. 테스트를 해보니 정말 된다..

굳이 방대한 양의 통합 검색보다 검색 시간이 줄어드는 것 같다.

또 통합검색 이후에 다시 클릭을 하면 손이 한번 더 가지만, 애초에 검색할 내

용을 구체화 해서 검색한다면, 클릭 한번을 줄일 수도 잇다.

그리고 더 놀라운 기능은.. 다음은 다른 포털 검색도 지원해 준다는 사실이다..

머 유투브도 포함이니 포털이라고 만은 볼 수 없으려나..

어쨋든 하는 방법은 검색어/포털명 을 넣으면 그 포털에서 검색해준다고 한다.

검색어/네이버 이렇게 입력하면 네이버에서 검색해 주는 식이다....

생각보다... 검색창은 숨겨진 기능이 많이 있는거 같다.. 앞으로도 주의 깊게

살펴 봐야 겠다..

머 하지만 간단히 생각하면 줌에서 검색할 때 검색 포털을 지정하면, 그 포털에

서 자동 검색이 되기 때문에.. 놀라운 기능은 아니지만,

그래도 한번쯤 재미삼아 해보기엔 나쁘지 않은 듯.

검색창의 숨겨진 기능들?!
Posted by 바람처럼..
|

지금까지 툴 만들기를 따라왔다면, 이제 값을 넣어볼 차례인데...

mfc는 구조가 특이하게 클래스 별로 각자 역할을 분리하고 있다...

우리가 보는 왼쪽 화면은 View 클래스에서 담당하고 있는데..

화면에 무언가를 그리고 싶다면 이 View 클래스를 이용해야한다..

일단 간단한 그림을 띄워보려 했으나.. 실패하였다...

View 접근하기 위해서는

값을 변경할 다이얼로그에 cpp에 메인프레임의 헤더와 뷰 헤더를 추가하고,

CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();

CmapToolView* pView = (CmapToolView*)pFrame->GetActiveView();

이렇게 얻어와서 pView를 이용해서 접근하면 된다고.. 검색해 보면 나온다..

그래서 그렇게 했는데 값이 제대로 들어가지를 않는다 -_ -;;;

내가 잘못넣었는지는 몰라도.. 메인 프레임 값은 잘 가져오는 것 같은데..

GetActiveView()에서 제대로 View 포인터를 리턴하지 않는 듯 했다...

난감한 상황에서 예전에 한번.. 분할 창으로 쓸때... 스플리터로 접근한 방법이

생각났다.. 

MFC는 구조가 언뜻보면 꼬여있는 듯 보이듯이.. 서로 참조할 방법을 여러가지

가지고 있다...

그래서 해결한 방법은.. .메인프레임에서..

CUItoolView* pView = (CUItoolView*)m_wndSplitter.GetPane(0,0) ;

이 한줄로 값을 얻어왔다....

휴.... 스플리터로 분리하면서 0번과 1번으로 분리되었으므로,

0번 윈도우를 참조하면.. 그 것이 바로 View 클래스 인 것이다...

헤매지말고 바로 얻어서 사용하도록 하자...


Posted by 바람처럼..
|


이전 포스팅의 순차 자료구조를 이용한 스택은 구현하기는 쉽지만, 물리적으로
크기가 고정된 배열을 사용하기 때문에 스택의 크기를 변경하기가 어렵고 메모

리의 낭비가 생길 수 있다는 문제가 있다. 이러한 순차 자료구조의 문제는 연결
자료구조를 사용함으로써 해결할 수 있다.

연결 자료 구조 중에서 단순 연결 리스트를 이용하여 스택을 구현하면 스택의

원소는 연결리스트의 노드가 된다. 스택에 원소를 삽입할 때 마다 연결 리스트

에 노드를 하나씩 연결한다. 그리고 스택 원소의 순서는 연결 리스트 노드의 링

크를 사용하여 표현한다. 스택의 top을 표현하기 위해서 노드에 포인터 top을

사용한다. 스택의 초기 상태는 포인터 top을 NULL 포인터로 설정하여 표현한

다.

다음은 간단히 구현해본 연결 자료구조 스택 소스 이다...

#include <stdio.h>

typedef struct stackNode{

 int data ;
 struct stackNode *link ;

}stackNode ;

stackNode* top ;

void push(int Num)
{
 stackNode* temp = new stackNode ;
 temp->data = Num ;
 temp->link = top ;
 top = temp ;
}

int pop()
{
 int Num ;
 stackNode* temp = top ;

 if(top == NULL )
  return 0 ;
 else
 {
  Num = temp->data ;
  top = temp->link ;
  delete temp ;
  return Num ;
 }
}

void printStack()
{
 stackNode* p = top ;
 
 printf("STACK [") ;

 while(p)
 {
  printf(" %d ", p->data ) ;
  p = p->link ;
 }
 printf(" ] \n ") ;
}

void main()
{
 top = NULL ;
 
 printStack() ;

 push(1) ;

 printStack() ;

 push(2) ;

 printStack() ;

 push(3) ;

 printStack() ;

 pop() ;

 printStack() ;

 pop() ;

 printStack() ;

 pop() ;

 printStack() ;
}

순차 구조와 거의 비슷하지만, 각 함수별로 저장하는 방식만 조금 다를 뿐이

다... 그리고 할당된 메모리를 해제하는 부분이 값을 빼는 부분에만 있기 때문

에 값을 많이 넣고, 그냥 종료해버리면 메모리누수가 생길 것이다..

이 것은 조금만 고민하면 알 수 있는 것이니 소스를 조금씩 개인적으로 수정해

서 쓰길 바란다..

Posted by 바람처럼..
|


스택은 수차 자료구조인 1차원 배열을 이용하여 스택을 구현할 수 있다. 1차원

배열인 stack[n]을 사용할 때 n은 배열 크기로서 배열원소의 갯수를 나타내는

데, 이것이 스택의 크기다. 스택에 원소가 쌓이는 순서는 배열의 인덱스로 표현

한다. 따라서 스택의 첫 번째 원소는 stack[0]에 저장되고, 스택의 두 번째 원

소는 stack[1]에 저장되고, 스택의 i번째 원소는 stack[i-1]에 저장된다.

스택이 top을 표현하기 위해서 배열 stack의 마지막 원소의 인덱스를 변수 top

에 저장한다. 변수 top에 0부터 n-1까지의 인덱스를 저장하게 되므로 스택의 초

기 상태에는 -1을 저장한다..

아래는 간단히 구현한 스택의 소스 이다.

#include <stdio.h>

#define STACK_SIZE 100

int stack[STACK_SIZE] ;

int top = -1 ;

void push(int Num)
{
 if( top >= STACK_SIZE - 1)
  return ;
 else stack[++top] = Num ;
}

int pop()
{

 if( top == -1)
  return 0 ;
 else return stack[top--] ;
}

void printStack()
{
 printf("Stack [ ") ;
 
 for( int i = 0 ; i <= top ; ++i )
  printf("%d ", stack[i]) ;
 
 printf("] \n") ;

}


void main()
{
 printStack() ;

 push(1) ;

 printStack() ;

 push(2) ;

 printStack() ;

 push(3) ;

 printStack() ;

 pop() ;

 printStack() ;

 pop() ;

 printStack() ;

 pop() ;

 printStack() ;
}

정말 간단한 구조이기 때문에 그냥 스택이 이런거구나 하는데만 쓰면 된다..

Posted by 바람처럼..
|

1에 이어서 계속...

이전 포스팅 보기

이전 포스팅의 마지막에서 OnInitialUpdate 함수를 추가하고, 내용을 입력하면

서 끝이 났다.. 그 이후에는...


리소스 뷰에 가서 IDD_CONTROLVIEW 다이얼 로그를 클릭하고, 저기 번개모

양인 컨트롤 이벤트 항목을 클릭하면 위와 같은 화면이 나온다...


그 중에서 TCN_SELCHANGE 함수를 만든다...


그러면 이런 함수가 추가되는데.. 여기서 값을 넣어주면, 탭의 상태가 변한다..


위의 select는 현재 클릭된 컨트롤의 값인데.. 그 값에 따라서 각 다이얼로그를

SHOW, HIDE 시켜주는 부분이다..


여기까지 완료하고 컴파일 하면.. 탭 컨트롤이 추가된 모습을 볼 수 있다..


텍스쳐 부분을 클릭하면 옆의 탭을 보여준다..

이 사진만 가지고는 티가 잘 안나니.. 컨트롤들을 추가해 보겠다..


1번 다이얼 로그에는 버튼과 스태틱 컨트롤을....

 


2번 다이얼로그에는 리스트 박스와 에디트 박스를 추가하였다..

그리고 다시 컴파일을 해보면..


1번 다이얼로그 ( Setting ) 이 선택되었을 때는 버튼과 스태틱 컨트롤이..

 


2번 다이얼로그 ( 텍스쳐 ) 에서는 리스트 박스와 에디트 박스가 나오는 것을

확인할 수 있다..

이제 진짜로 툴만들기의 기본이 끝났다고 할 수 있다..

이제부터는 왼쪽화면에서 무언가 화면을 그리고, 오른쪽 컨트롤 부분에서 값을
입력하면 실시간 대입되도록 연결만 시키면.. 멋진 툴이 될 수 있을 것이다...
Posted by 바람처럼..
|

이 포스팅은 지난 포스팅인 기본 뼈대 만들기의 프로젝트에서 이어서 진행된

다.

기본 뼈대 만들기 바로가기

먼저 왜 탭 컨트롤이 필요한지 생각해보자..

탭 컨트롤이란.. 같은 공간에 각 탭별 각각의 주제별로 아이템들을 모아서 사용

하기 좋게 만들 수 있는 것이다...

툴만들기에는 필수적 이라고 볼수있다.. 이제 차근차근 하나씩 만들어보자..

먼저..


도구 상자에서 탭 컴트롤을 추가한다...

추가 위치는 IDD_CONTROLVIEW 다이얼로그에 하면 된다..


추가를 하고 탭컨트롤이 선택된 상태에서 오른쪽 버튼을 클릭. 변수 추가를 선

택한다.


변수명은.. 각자 원하는 것으로 하면된다..


그리고 사용할 탭의 갯수 만큼 다이얼로그 삽입을 한다.. 일단 테스트 용으로 2

개만 만들었다..


다이얼로그의 버튼을 다 제거하고, 대충 예전의 모습과 비슷하게 크기를 조정

한다...


그리고 속성에서 Border를 None으로...

style을  Child로 바꾼다.. ( 다이얼로그 2개 모두. )


그리고 클래스를 저장하기 위해서 다이얼로그를 더블 클릭하면, 이런 창이 생

긴다.. 기본 클래스 CDialogEx에서..


그냥 CDialog로 바꾸고..


클래스 명을 입력한후 마침을 누른다.. ( 클래스 명은 알아서 바꿔도 상관없음)


여기까지 완료했으면.. ControlView.h 에 들어간다.. 그러면 위의 그림과 같이..
마지막 줄에 탭 컨트롤 변수가 추가되어있을 것이다.. 만약 안되어 있다면.. 다

시 위에서 부터 차근차근 보고 확인해보길 바란다..


ControlView.h 에 다이얼로그 클래스의 h 파일을 추가한 후...


변수를 추가한다...
 


생성자에서 다이얼로그 변수를 초기화 해주고, 소멸자에서는 해제를 해준다..

저 해제를 위한 매크로는 기본적으로 포함된 것이 아니기 때문에.. 위에 추가를
해주어야한다.. NULL인지 판단해서 NULL이 아닐때만 해제를 하는 매크로로써
유용하게 사용된다..

 


여기 까지 추가 했으면 클래스 뷰로 가서 CControlview를 클릭한다..


그리고 오른쪽의 재정의 창을 클릭하면, OnInitialUpdate 라는 함수가 있다..

이 함수를 추가하자..


그러면 이런 함수가 하나 생기는데.. 그 곳에다가...


이렇게 추가를 하자...

내용이 길어져서 다음 포스팅에서 계속.........
Posted by 바람처럼..
|

지난번 ktx 할인 카드 발급하기에 이어서.. 코레일에서 만든 어플인 글로리로

할인카드 적용하여 예매하는 방법을 알아보겠습니다..

평소에도 기차를 자주 타기 때문에 글로리로 예매하고 타는 경우가 많았습니

다. (물론 한 절반정도는 역에서 무인발매기에서 발매합니다.)

글로리 사용법도 알겸, 할인카드 있으신 분은 할인카드도 적용시켜서 결제하는
법을 알아보겠습니다.


글로리 어플의 첫 화면 입니다.


위의 메뉴중에 승차권 예매를 클릭합니다..


그러면 이런 화면이 나옵니다.. 여기서 차례대로 설정을 하시면 됩니다..

할인카드를 사용 안하시면.. 지금 여기서 설정을 고치고 바로 조회 버튼을 클릭

하시면 됩니다.

할인카드를 추가하시려면 승차인원을 누릅니다..

그럼 아래와 같은 화면이 나옵니다.


여기에서.. 어른이 1명 있는데 그 것을 클릭 후 왼쪽으로 드래그 하면...


이렇게 0명이 됩니다... 그 후 할인추가를 클릭하고, 위로 드래그해서 올립니다.

그럼 아래와 같은 화면이 나옵니다..


할인카드를 클릭합니다.


그럼 할인카드를 확인하는 장면이 나오는데요.. 각자 본인의 할인카드 번호를

입력하시고 입력 완료를 누르시면됩니다. 번호조회는 단지 조회만 되니까, 처

음 한번 해보시고, 조회가 되면 바로 입력 완료 누르시면 됩니다.


 그러면 이렇게 인원이 나오는데요.

이제 일반예매 부분을 아래로 드래그 합니다. 그러면..


모두 0명인데 할인에 1명이 추가되었습니다.

자 이다음에 제일 위의 승차인원을 클릭하여 다시 돌아갑니다...


그리고 검색을 합니다... 그냥 테스트니까 서울 부산을 바로 검색했네요..

 


요금을 보면.. 일반석이 55500 이네요....

이 가격은 그냥 나오는 가격입니다.. 할인 적용은 더 뒤로 가시면 확인 할 수 있

습니다.


예약하기에 들어가면, 특실과 일반실 등 현재 잔여 좌석이 있는 곳을 선택하고

예약 버튼을 누릅니다..

그러고 나면, 경고창이 하나 뜨는데.. 예약과 함께 결제를 해야.. 발매가 된다고

합니다.. 예약만 해놓으시면, 표 예매가 안된 것이니 예약만 했다고 안심하시면
안됩니다.

그래서 예약버튼을 누르고 넘어가면, 결제창이 뜨는데요..


짜쟌.. 가격이 47200원이네요..

실제로 15% 할인되면 47150 이지만.. 50원은.. 반올림 되나 봅니다...

이 것이 일요일 새벽에.. 일요일 표를 검색해서 15%만 적용되었구요..

(주말, 공휴일은 최대 15%, 할인표가 모두 소진되면 7.5% 할인됩니다.)

평일에 하시면 30% 할인된 요금으로 기차를 타실 수 있습니다..

아래의 결제를 클릭하셔서.. 신용카드 정보를 입력하시면 예매가 완료되고,

발권하기를 누르시면.. 메인 화면에서 승차권 확인 부분에서 표를 확인할 수 있

습니다..

이제 편하게 스마트 폰으로 기차 예매하고, 표 끊는 시간없이 바로 열차 타로

갑시다~

아.. 그런데.. 저는 철도 회원이라서, 회원번호 입력만으로 정보가 관리되지만,

비회원분들은 조금 기억하실 내용들이 많아서 조금 번거로우실수도 있는데

요...

가급적.. 기차 자주 타시면.. 철도회원 가입하는거 추천드립니다...
 
저는 코레일과 아무 관계가 없음을 밝힘니다 ;;
Posted by 바람처럼..
|

요즘 국감 덕분에 여러가지 정보들이 나오고 있다.

그 중에 피자나 치킨 프렌차이즈에 관한 기사가 떳다..

기사 원문 보기

얼마전에 롯데마트의 통큰 치킨이 처음 나왔을 때 프렌차이즈 들은 난리였다..

소위 대기업의 횡포라고 했었다..

그렇게 싸게 팔면 본인들은 물가 상승으로 인해 가격이 비싸진건데 상대적으로

폭리를 취한 듯 보이지 않냐는 등.. 논란이였다...

그러면서 원가 공개니 머니 하면서 난리를 쳤었는데..

실제로 판매가 중에 프렌차이즈가 가져가는 돈이 20~30%나 된다면...

그 것도 폭리가 아닐까??

정말 어릴때랑 비교하면 진짜 비싸진 것이 닭값 인것 같다... 피자는 사실 예전

부터 비쌋지만, 그래도 크게 오르지 않은 느낌이지만..

닭은 어렸을 때 몇천원이면 먹었던 것이.. 점차 올라 요즘 프렌차이즈 닭을 먹

으려면 16000~17000은 기본인 듯 하다.

물론.. 안그런 닭들도 있다는 사실이 중요하다.. 이건 반대로 보면.. 그만큼 프

렌차이즈가 아닌 곳에서 그정도 가격을 유지할 수 있다면, 그 가격차이는 프렌

차이즈 본사에 돌아간다고 볼 수도 있지 않을까?

아무튼.. 점점 신뢰를 잃어가는 업체들 덕분에... 이제 마음편히 집에서 배달음

식 시켜먹기도 겁난다.

치킨, 피자는 프렌차이즈 본사의 폭리에.. 감자탕은 뼈 재사용, 족발은 썩은 육

수...
 
물론 소수의 업체일 뿐이다.. 하지만 이런 일들이 있으면, 소비자 입장에서 어

떤 것이 좋고 어떤 것이 나쁜지 구별할 방법이 없으니.. 피할 뿐이다..

조금 더 믿고 음식을 사 먹을 수 있는 분위기로 변했으면 좋겠다..
Posted by 바람처럼..
|

 1] 함수 오버로딩의 이해

확장자가  .c로 끝나는 C 언어로 작성된 프로그램에서는 다음과 같은 함수의

정의가 허용되지 않았다.

int function(void)
{
        return 0;
}

int function(int a, int b)
{
         return a+b;
}

위의 소스는 함수의 이름이 같기 때문에 컴파일 타임에 오류를 발생시킨다. 아

니 c 에서는 오류를 발생 시켰다. 하지만 C++로 넘어오면서 부터 달라졌다. c++

은 호출하고자 하는 함수를 찾을 떄 함수의 이름뿐 아니라 매개 변수의 정보까

지도 동시에 참조한다. 따라서 c++은 이름이 같고 매개 변수의 타입 혹은 개수

가 다른 함수들의 정의를 허용한다. 그리고 이를 가리켜 함수 오버로딩

(function overloading) 이라 한다.

2] 함수 오버로딩의 조건 

c++은 함수의 이름이 같아도 매개 변수의 타입 및 개수가 다르면 문제되지 않으

며, 이를 가리켜 " 함수가 오버로딩 되었다. " 라고 표현한다고 하였다. 다음은

대표적인 함수 오버로딩의 예이다.  

int function1(int n){.....}

int function2(char c) {.......}

위의 두 함수도 오버로딩 되었다. 함수의 이름이 같지만 매개 변수의 자료형이

다르기 때문이다.

int function(int v){.....}

int function(int v1, int v2){.......}

위의 두 함수도 오버로딩 되었다. 함수의 이름과 매개 변수의 자료형은 같지만

자료형의 개수가 다르기 때문이다.

즉, 함수 오버로딩의 기본 조건은 다음과 같다.

"함수의 이름은 같지만 매개 변수의 타입이나 개수가 달라야 한다. "

그 이외에도 함수가 오버로딩 되기 위한 조건이 하나 더 있는데 이에 대해서는

다음 기회에 언급하겠다.

3] 오해하기 쉬운 함수 오버로딩

함수 오버로딩을 처음 접하게 되면 두 개의 함수를 눈으로만 보고 잘못 판단하

는 경우가 종종있다. 예를 하나 들어 보겠다. 다음의 함수들은 오버로딩 조건을
충족하는가, 아니면 충족하지 못하고 컴파일 시 오류를 발생시키겠는가? 눈 여

겨 볼  부분은 함수의 리턴 타입이다.

 #include <iostream>

 void function(void)
{
        std::cout << "function(void  call " << std::endl;
}

int function(void)
{
        std::cout << "function(char c) call " << std::endl;
        return 1;
}

int main(void)
{
        function();
        return 0;
}

물론 위에 정의되어 있는 두 개의 function 함수는 이름은 같지만, 리턴 타입이

다르다. 그러나 리턴 타입만 가지고는 함수가 오버로딩되었다고 말할 수 없다.

결국 컴파일러는 " 난 네가 뭘 원하는지 몰라 (Ambiguous) " 라는 메시지를 출

력하게 된다. 즉, 리턴 타입만 달라서는 함수가 오버로딩되지 않는다.

 

'프로그래밍 > C,C++' 카테고리의 다른 글

[C,C++] memset, memcpy 함수 사용법!  (6) 2011.10.11
[C,C++] 더블버퍼링..  (0) 2011.10.05
[C,C++] 디폴트(DeFault) 매개 변수  (0) 2011.09.14
[C,C++] 이름공간(namespace)  (0) 2011.09.14
[C,C++] 인-라인(in-line) 함수  (0) 2011.09.14
Posted by 바람처럼..
|
디폴트(Default)란 컴퓨터 공학에서 " 기본적인 " 이라는 의미를 지닌다. 매개

변수가 무엇인지는 알고 있을 것이다. 그렇다면 기본적인 매개 변수라는 뜻이

된다.

1] 디폴트 매개 변수의 의미

함수를 다음과 같은 형태로 정의하는 것이 가능하다 .

int function(int a = 0);
{
      return a+1;
}

여기서 매개 변수를 선언하는 부분을 보면 a는 0으로 설정되어 있다. 이것이 바

로 디폴트 매개 변수이다. 그렇다면 이것이 지니는 의미는 무엇일까? 의외로 간

단하다. " 만약에 function이라는 이름의 함수를 호출하면서 인자를 전달하지

않으면 0이 들어 온 것으로 간주를 하겠다 " 는 뜻이다. 말 그대로 디폴트(기본

적으로 설정해 놓은) 매개 변수다.

2] 다양한 형태의 디폴트 매개 변수 설정

이번에는 디폴트 매개 변수의 다양한 형태를 예제를 통해서 살펴 보기로 하자.

다음에 소개하는 것은 직육면체의 넓이를 구하는 프로그램이다.

#include < iostream> 

int BoxVolume(int length, int width = 1, int height = 1); 

int main()
{
       std::cout << " [3,3,3]  :    " << BoxVolume(3,3,3) << std::endl;

       std::cout << " [5,5,def]  :    " << BoxVolume(5,5) << std::endl;

       std::cout << " [7,def,def]  :    " << BoxVolume(7) << std::endl;

       return 0;

int BoxVolume(int length, int width, int height)
{
        return length*width*height;
}

함수 BoxVolume이 아랫쪽에 정의되어 있고, 위쪽에 선언되어 있다. 이러한 형

태의 구성은 이미 C 언어를 통해서 학습한 것이다. 여기서 눈 여겨 볼 부분은

함수의 선언이다. 총 세 개의 매개 변수를 인자로 전달 받는데, 두 번째, 세 번

째 인자에만 디폴트 매개 변수를 설정해 놓았다.

 한가지 주의할 것은 이렇게 함수의 선언이 함수의 정의 이전에 존재하는 경우

디폴트 매개 변수는 선언 부분에 놓여져야 한다는 것이다.  

3] 디폴트 매개 변수와 함수의 오버로딩 

디폴트 매개 변수와 함수 오버로딩을 동시에 잘못 정의하는 경우가 있다. 다음

예제를 보자. 그리고 문제점을 지적해 보자.

#include <iostream>

int function(int a = 0)
{
        return a+1;

int function(void)
{
        return 10;
}

int main(void)
{
        std::cout << function(10) << std::endl;

        return   0;

위의 예제를 컴파일 해 보면 컴파일도 잘 되고 실행도 잘 된다. 왜냐하면 3번쨰

줄에 정의된 함수 function과 7번째 줄에 정의된 함수 function과의 관계는 오버

로딩 관계이고 main 내에서는 int형 데이터 하나를 인자로 전달 받는 함수, 즉

위쪽 함수를 호출하였으므로 문제될 것이 전혀 없다. 그러나 잠재적인 문제를

지니고 있다. 위의 예제에서 main 함수를 다음과 같이 변경한다면 어떻게 될

까?

int main(void)
{
     std::cout << function() << std::endl;

     return   0;
}

드디어 잠재적인 문제가 터지고 말았다. 위의 function 함수를 호출하면서 인자

를 전달하지 않고 있다. 그렇다면 어떤 함수를 호출 하겠는가? 문제를 위에서

정의한 두 함수 모두 호출 가능하다는데 있다. 컴파일러는 두 개의 함수 중에서
무엇을 호출해야 할 것인지를 결정 짓지를 못한다. 따라서 에러를 발생시켜 버

린다. 그러므로 이러한 형식의 함수 정의는 반드시 피해야 한다.


'프로그래밍 > C,C++' 카테고리의 다른 글

[C,C++] 더블버퍼링..  (0) 2011.10.05
[C,C++] 함수 오버로딩(Function Overloading)  (0) 2011.09.15
[C,C++] 이름공간(namespace)  (0) 2011.09.14
[C,C++] 인-라인(in-line) 함수  (0) 2011.09.14
[C,C++] 가변 인자란 ...  (0) 2011.08.28
Posted by 바람처럼..
|
이름 공간이란 다소 생소한 개념이다. C 언어에는 존재하지 않는 개념이기 때

문이다. 그러나 어려운 개념은 아니다. 이름공간이란 이름을 지니는 공간이라

는 뜻이다. 말 그대로 특정영역(공간)에 이름을 붙여주기 위한 문법적 요소이

다.

1] 등장 배경

 프로그램이 대형화되어 가면서 등장하기 시작한 문제는 이름의 충돌이다 .예

를 들어서 은행 관리 시스템을 개발하는데 있어서 세 개의 회사가 참여를 한다.
각 회사의 이름은 A, B, C 이다. 이들은 규모가 큰 관계로 일을 독립적으로 진

행하기로 하였다. 그러기 위해서는 구현해야 할 부분도 적절히 나눴다. 이제 6

개월 뒤 다시 모여서 하나의 프로젝트를 완성하기로 약속을 한다.

 6개월이라는 시간이 흘렀다. 이제 각각의 회사가 구현한 모듈을 하나로 묶고

부족한 부분을 완성 할 때가 되었다. 그런데 문제가 생기고 말았다. A라는 회사

에서 정의한 함수의 이름과 B라는 회사에서 정의한 함수의 이름이 같은 것이

아닌가! 이름 충돌이 나지 않도록 미리 약속이라도 할 것을 그랬다는 후회가 든

다. 이제는 전쟁이다! 이름하나 바꾸는 것이 어디 쉬운 일인가? A  회사의 팀장

과 B 회사의 팀장이 서로 싸우기 시작한다. 물론 싸움의 요는 이거다. " 저희가

무지 바쁘거든요? 당신네 회사에서 양보를 조금 해 주셔야 하게습니다." 그런데
문제는 산 넘어 산이다. C 라는 회사에서는 자신들이 맡은 부분을 구현하는 과

정에서 다른 회사에서 구현해 놓은 함수들을 사용했는데, 이 함수들의 이름이

회사A, B에서 구현해 놓은 함수의 이름과 또 충돌이 나는 것이 아닌가? 결국 이
프로젝트는 실패로 돌아가고 말았다.

이러한 문제를 해결하기 위해서 이름공간(namespace) 이라는 문법이 C++ 표

준에 새롭게 포함되었다.

2] 기본 원리

 한 집에 철수 라는 이름을 지니는 사람이 두 명 살고 있다면 이는 문제가 된다.
" 철수야!" 라고 부르면, 어떤 철수를 말하는지 구분 지을 수 없기 때문이다. 그

러나 서로 살고 있는 집이 다르다면 문제될 것이 없다. 201호에 사는 철수와

202호에 사는 철수는 구분 지을 수 있기 때문이다.  이것이 이름 공간의 기본 원

리이다.  다음 예제는 앞에서 이야기한 문제점을 간략화해서 코드로 옮겨 놓은

것이다. A와B라는 이름의 회사가 구현한 프로그램 모듈을 하나의 완성된 프로

그램으로 옮기는 과정에서 이름 충돌이라는 문제가 발생하였다.

 #include <iostream>

 void function(void)
{
      std::cout << "A.com에서 정의한 함수 " << std::endl;
}

void function(void)
{
      std::cout << "B.com에서 정의한 함수 " << std::endl;
}

 int main(void)
{
       function();
       return  0;
}

 위의 예제에는 A.com 이라는 회사에서 정의한 함수와 , B.com 이라는 회사에

서 정의한 함수의 이름이 같다. 따라서 컴파일 시 문제를 일으킬 것이다. 둘다

필요한 기능의 함수라서 어느것 하나를 뺄 수도 없는 상황이다. (물론 그렇다고
가정만 하자) 

다음 예제에서는 이름 공간을 정의해서 문제를 해결하고 있다. 일단 위의 예제

와 어느 부분이 달라졌는지 비교해 보자.

#include <iostream>

namespace A_COM
{
       void function(void)
       {
               std::cout << "A.com에서 정의한 함수 " << std::endl;
       }
}

namespace B_COM
{
        void function(void)
       {
                std::cout << "B.com에서 정의한 함수 " << std::endl;
        }
}

int main(void)
{

      A_COM:: function();

      B_COM:: function();

       return  0;
}

 위의 예제를 보면 namespace 라는 키워드가 등장한다. 이는 이름 공간을 구

성하겠다는 의미다. 즉 "namespace A_COM " 이라는 선언은 A_COM이라는

이름의 공간을 구성하겠다는 의미가 되며, 이름공간의 범위는 이어서 등장하는
중괄호를 통해서 지정된다. 조금 더 쉽게 이야기를 하면, " 특정 영역(공간)의

범위를 지정하고 이름을 붙여준 것" 이다. 이름 공간이 다르면 같은 이름의 변

수나 함수의 선언이 허용 된다. 하지만 한가지 주의할 것은 이름 공간 내에 선

언되어 있는 변수나 함수에 접근하는 방법이다. 다음과 같은 선언이 필요하다.

A_COM::function(); 

위 코드에서 :: 연산자를 가리켜 " 범위 지정 연산자(scope resolution

operator) " 라 한다. 즉 이름공간의 범위를 지정할 때 사용하는 것이다. 따라서

위 그림과 같은 선언은 다음과 같은 의미를 지니게 된다. 

" A_COM 이라는 이름 공간안에 선언되어 있는 function 함수를 호출하라"

 이렇듯 이름 공간 안에 선언되어 있는 변수나 함수에 접근하기 위해서는 범위

지정 연산자를 사용해서 선언되어 있는 이름공간을 지정해 줘야한다.

참고) 위의 예제들에서는 하나의 이름공간 안에 하나의 선언 및 정의만을 담고

있지만 실제로는 둘 이상의 선언 및 정의를 담을 수 있고 또 그것이 더 일반적

이다.

3] std::cout, std::cin, std::endl

 지금까지 입력 및 출력을 하고자 하는 경우에는 std::cout 과 std::cin을 사용해
왔다. 이것의 정체는 아직 모르지만 사용법만은 알고 있다. 그런데 이제는 조금
이해가 될 것이다. :: 연산자가 어떠한 의미를 지니는지 이해 했기 때문이다.

std::cout은 무슨 의미인가? std라는 이름공간 안에 존재하는 cout을 참조하겠

다는 의미이다. 물론 우리는 아직 cout의 정체를 모르고 있다. 마찬가지로

std::cin은 std라는 이름 공간 안에 존재하는 cin을 참조하겠다는 의미로 사용

된다. 아마도 다음과 같은 가정을 할 수 있을 것이다. 헤더파일 iostream에 선

언되어 있는 cout, cin, 그리고 endl은 std 라는 이름공간 안에 선언되어 있다는
결론을 내릴 수있다. 이름 충돌을 막기 위해서 c++표준에서 제공하는 다양한 함

수나 변수들을 이름공간 std 안에 선언 및 정의 했기 떄문이다.

4]using

이제 cout, cin 그리고 endl을 참조할 때 마다  " std:: " 을 앞에다 붙여줘야 하

는 이유에 대해서 알게 되었다. 그리고 이 일이 여간 귀찮은 것이 아니라는 생

각도 들기 시작한다. 오히려 접근하고자 하는 이름공간에 대한 선언이 불 필요

한 과거의 표준이 더 맘에 끌리기도 한다. 하지만 걱정하지 말자. 추가적인 선

언 하나만으로도 여러분의 이러한 불만사항을 해소할 수 있으니 말이다.

Posted by 바람처럼..
|

in-line 함수의 의미부터 파악해 보자. in은 ' 내부 '를 의미하고, line은 ' 프로그

램 라인 ' 을 의미하는 거이다. 즉 의역 해보면 " in-line 함수" 란 프로그램 라인
안으로 들어가버린 함수라는 의미를 지닌다.  

1] 매크로 함수의 정의와 장점

 우리는 C 언어를 공부하면서 매크로에 대해서 알게 되었다. 여기서는 이에 관

련해서 잠깐 복습을 하기로 하자. 매크로를 이용하면 다양한 일을 할 수 있는

데 그 중에서도 가장 대표적인 일은 함수를 만드는 일이다. 다음은 매크로를 이

용해서 함수를 정의하고 이를 호출하는 형태를 보여준다.  일반적인 순서에 의

해서 전처리, 컴파일, 링크 과정을 거쳐서 실행 파일이 생성될 것이다.  

 #include <iostream>

#define SQUARE(X)   ((X)*(X))

 int main(void)
{

       std::cout << SQUARE(5) << std::endl;

       return 0;
}

 그럼 위의 코드는 전처리 과정을 거치면서 어떻게 변하게 되는가? 다음 코드는
전처리 과정에 의해서 변경된 코드를 보여준다.

 #include <iostream>

 int main(void)
{

       std::cout << ((5)*(5)) << std::endl;

       return 0;
}

  위의 두 코드를 통해서 알 수 있는 사실은 무엇인가? 그것은 함수를 매크로로

정의하면 전처리기에 의해서 함수 호출 문장이 함수의 몸체 부분으로 완전히

대치돼 버린다는 것이다. 그렇다면 이를 통해서 얻게 되는 이점은 무엇인가? 함

수 호출 과정이 사라졌기 때문에 성능상의 이점을 맛볼 수 있다.( 함수 호출은

스택 메모리 공간의 할당도 요구하며 시간도 많이 요구된다.)

  위의 예제와 같이 함수 호출 문장이 함수의 몸체부분으로 완전히 대치되 버리

는 현상을 가리켜 " 함수가 inline화되었다." 라고 표현한다.

 참고) 매크로 함수에 대해서는 장점뿐만 아니라 단점도 알고 있어야 한다. 단

점은 함수의 구현이 까다롭고 디버깅하기 어려우며, 구현하고자 하는 함수의

크기가 크다면 프로그램의 크기가 커지게 된다는 것이다. 보자 자세한 사항은

C 언어 관련 서적을 참조하기 바란다.

 2] C++ 기반 함수의 in-line 화

 앞에서 매크로를 이용해서 함수를 in-line화 하였다. 이처럼 매크로를 이용해

서 C++의 함수도 in-line화 할 수 있다. 그러나 보다 쉬운 방법이 있다. 다음 예

제 코드는 앞에서 본 예제를 C++ 스타일로 in-line화 하고 있다.

#include <iostream>

inline int SQUARE(int x)
{
         return x*x;
}

int main(void)
{
       std::cout << SQUARE(5) << std::endl;

       return 0;
}

 함수를 정의하는 과정에서 키워드 inline을 붙여준 것을 제외한다면 일반적인

함수와 다를 바가 없다. 그렇다면 여기서 붙여준 키워드 inline은 무엇을 의미하

는 것일까? 이는 함수 SQUARE를 inline화 하라는 의미이다.

 정리하자! C++에서는 성능 향상을 목적으로 함수를 inline화 하기 위해서 매크

로를 사용할 필요가 없다. 다만 inline이라는 키워드만 붙여주면 되는 것이다.

얼마나 간편하고 좋은가?

 참고) 매크로를 이용한 함수의 in-line화는 전처리기에 의해서 처리되지만, 키

워드 inline을 이용한 함수의 in-line화는 컴파일러에 의해서 처리된다. 또한 컴

파일러에 따라서는 inline 선언이 오히려 성능 향샹에 해가 된다고 판단될 경우,
그냥 무시해 버리기도 한다.

'프로그래밍 > C,C++' 카테고리의 다른 글

[C,C++] 디폴트(DeFault) 매개 변수  (0) 2011.09.14
[C,C++] 이름공간(namespace)  (0) 2011.09.14
[C,C++] 가변 인자란 ...  (0) 2011.08.28
[C,C++] getchar() 의 문제점..  (2) 2011.08.28
[C,C++] scanf 와 fgets  (0) 2011.08.27
Posted by 바람처럼..
|


스택(stack)이란 쌓아 올린다는 의미다. 따라서 스택 자료구조라는 것은 접시

를 쌓듯이 자료를 차곡차곡 쌓아 올린 형태의 구조를 말한다.

스택 자료구조의 스택은 같은 구조와 크기의 자료를 정해진 방향으로만 쌓을

수 있고, top 이라고 정한 한 곳으로만 접근하도록 제한되어 있다.

스택에서는 top을 통해서 들어온 자료가 일정한 방향으로 차곡차곡 쌓이게 된

다. 스택에서의 top은 현재 스택의 가장 위에 있는 마지막 자료를 가리키고 있

고, 삽입되는 새 자료는 top이 가리키는 자료의 위에 쌓이게 된다. 그러면 삽입

된 자료는 스택의 마지막 자료가 되고, 이 때 top은 삽입된 자료를 마지막 자료

로 가리킨다. 스택에서 자료를 삭제할 때 에도 역시 top을 통해서만 가능하다.

따라서 스택은 시간 순서에 따라 자료가 쌓여서 가장 마지막에 삽입된 자료가

가장 먼저 삭제된다는 구조적 특징을 갖는다. 이러한 스택의 구조를 후입선출

(LIFO, Last-In-First-Out) 이라고 표현한다.

스택에서 top을 통한 삽입 연산을 push, top을 통한 삭제 연산을 pop이라고 한

다.
Posted by 바람처럼..
|

전기요금납부 계속 해야지 해야지 하는데 고지서라도 안날라오면 난감합니다.

이번달에 제가 왜 고지서가 안오지 하고 기다리다가 결국 납기일이 지났네요..

납기일을 놓치면 1% 였던가.. 하이튼 추가 요금이 더 붙으니 최대한 납기일을

지킵시다..

어쨋든 전기요금을 내지 못했던 이유가 고지서를 기다리다가 였는데요..

이 것은 인터넷으로 낸다면 예전에 고지서라던지 고객번호만 알고있다면 이번

달 고지서가 없어도 충분히 납부가 가능합니다.

먼저 전기요금납부로 검색을 합니다.


그러면 저기 전기요금납부 부분에 인터넷지로가 보이실 겁니다.

인터넷 지로를 클릭합니다.


그러면 이런 창이 하나 뜰텐데요. 여기다가 고객 번호를 입력하고 조회를 누릅

니다.


그러면 이렇게 납기일과 요금이 나옵니다..

납기일을 1주일 놓쳐서 돈이 더 올랐네요 ㅠ,ㅠ

그리고 결제 요청을 누릅니다.



인터넷으로 주민세 내기

그러면 이렇게 지난번 주민세 내는 법을 설명할 때 처럼. 공인인증서 로그인이

있습니다. 이 것은 공인인증서만 있다면 가입이 가능하기 때문에, 먼저 가입을

하시면 편합니다.


그러면 이렇게 납부 계좌를 선택할 수 있는 부분이 있는데, 계좌도 회원가입을

하면서 주로 쓰시는 은행 계좌를 등록하시면 됩니다. 은행마다 거래시간이 조

금씩 틀리니 알아보시고 사용하세요..


제가 쓰는 우리은행은 7시 부터 22시 까지 네요. 이렇게 계좌번호를 넣고,

계좌 비밀 번호를 입력한 후 납부하기를 누르면 팝업이 뜹니다..

내용이 맞으면 확인을 누르세요.


그러면 이렇게 전자서명이 나옵니다.

내용을 보시고 확인을 누릅니다.


이 화면이 공인인증서 확인을 한번 더 하고 나왔던지 아니면 그냥 되었던지는

모르겠지만, 일단 공인인증서야 애초에 로그인했던 것 처럼 입력하시면 되고

요.. 이제 기다리고 있으면....


짜쟌~ 이렇게 영수증이 뜨면 끝입니다.

에효.. 단돈 몇백원이라도.. 안내도 될 걸 내니깐 좀 아깝네요..

다들.. 고지서 기다리지 마시고, 고객 번호만 가지고 인터넷으로 전기세

내자구요~

인터넷으로 전기요금납부!인터넷으로 전기요금납부!인터넷으로 전기요금납부!
Posted by 바람처럼..
|

순차 선형 리스트는 논리적인 순서와 물리적인 순서가 같기 때문에 원소의 위

치를 찾아 엑세스 하기 쉽다는 장점이 있지만, 삽입 연산이나 삭제 연산 후에

연속적인 물리 주소를 유지하기 위해서 원소들을 이동시키는 추가적인 작업과

시간이 소요된다. 원소들의 이동 작업으로 인한 오버헤드는 원소의 개수가 많

고, 삽입,삭제 연산이 많이 발생하는 경우에 더 많이 발생한다. 또한 순차 자료

구조는 배열을 이용하여 구현하기 때문에 배열이 갖고 있는 메모리 사용의 비

효율성 문제를 그대로 갖는다.

순차 자료구조에서의 연산 시간에 대한 문제와 저장 공간에 대한 문제를 개선

한 자료 표현 방법으로 연결 자료구조 또는 비순차 자료구조가 있다. 연결 자료

구조에서는 순차 자료구조에서처럼 원소의 논리적인 순서와 물리적인 순서가

일치할 필요가 없다. 연속한 물리주소에 의해 원소의 순서를 표현하는 것이 아

니라 각 원소에 저장되어 있는 다음 원소의 주소에 의해 순서가 연결되는 방식

이기 때문에 물리적인 순서를 맞추기 위한 오버헤드가 발생하지 않는다. 하나

의 순차 자료구조를 위해서는 하나의 고정크기 메모리 공간을 사용하지만, 연

결 자료구조에서는 여러개의 작은 공간을 연결하여 전체를 표현하므로 크기 변

경이 유연하고 좀더 효율적으로 메모리를 사용할 수 있다.

연결 리스트는 리스트를 연결 자료구조로 표현한 구조로서 연결하는 방식에 따

라 단순 연결 리스트와 원형 연결 리스트, 이중 연결 리스트, 이중 원형 연결 리

스트로 나눌수 있다.

연결 자료 구조에서 원소는 연결될 다음 원소에 대한 주소를 저장해야 하기 때

문에 <원소, 주소> 의 단위로 저장해야한다. 이러한 단위 구조를 노드 라고 한

다. 노드는 원소의 값을 저장하는 데이터 필드와 다음 노드의 주소를 저장하는

링크 필드로 구성된다. 데이터 필드는 저장할 원소의 형태에 따라서 하나 이상

의 필드로 구성되기도 한다. 링크 필드는 포인터 변수를 사용하여 주소값을 저

장하며, 포인터 또는 링크, 참조 라고도 한다.

그리고 연결 자료 구조에서는 헤드 라고 불리는 시작 주소가 있다. 그 헤드는

시작 주소이면서, 첫 데이터를 가르키는 역할도 한다. 연결 리스트의 마지막 노

드는 다음에 연결되는 노드가 없으므로 링크 필드에 저장할 주소값이 없는데,

이럴때는 노드의 끝을 표시하기 위해 마지막 노드의 링크 필드에 NULL을 저장

한다. 만약 아무런 노드도 없다면 헤드에 NULL을 저장하여 널 포인터로 만들면
된다.
Posted by 바람처럼..
|


선형 리스트를 순차구조로 구현하기 위해서 배열을 사용한다. 배열은 <인덱스,
원소 > 의 쌍으로 구성되어 메모리에 연속적으로 할당되는데, 이때 인덱스는

배열 원소의 순서를 타나낸다. 배열은 순서를 가진 배열 원소들을 메모리에 연

속하여 구성하므로 프로그램 언어에서 제공하는 배열을 그대로 사용하여 구현

할 수가 있다.

그럼 가장 간단한 1차원 배열의 순차 표현을 알아보자.

1차원 배열은 인덱스를 하나만 사용하는 배열이다. 원소의 순서를 하나의 값으

로 구별할 수 있는 간단한 선형 리스트는 1차원 배열을 사용하여 표현할 수 있

다.

예를 들어 학교의 학생수에 대해서 생각해보자.

1학년에 4반이 있는데, 각 반에는 35명, 36명, 39명, 37명 이렇게 있다고 치자.

이 것을 배열을 통해 나타내면,

int student[4] =  { 35, 36, 39, 37 } ;

이렇게 표현할 수 있다.

1차원 배열 student는 int로 선언 되었으므로, 각 원소의 길이는 4바이트가 된

다. C 프로그래밍에서 배열의 인덱스는 0부터 시작하므로 배열 sale의 각 원소

의 위치는 시작 주소가 a일 때 a + ( 인덱스 * 4바이트 ) 가 된다.

이번엔 2차원 배열의 순차 표현을 알아보자. 

위의 1차원 배열과 마찬가지로 2차원배열은 학교의 학생수 분류에서 학년을 추

가해 보자.

1학년에 4반, 2학년에 4반, 3학년에 4반이 있다.

그렇게 되면, 

int student[3][4] = { { 35, 36, 39, 37 }, 
                             { 37, 36, 38, 39 }, 
                             { 34, 37 ,38 ,37 } } ;
이렇게 표현 할 수 있다.

2차원 배열의 구조를 논리적으로 표현할 때는 행과 열의 구조로 나타내지만, 실

제로 메모리에 저장될 때에는 1차원의 순서로 저장된다. 2차원의 논리적 순서

가 1차원의 물리적 순서로 변환되는 방법은 첫 번째 인덱스를 기준으로 하는 행
우선 순서와 마지막 인덱스를 기준으로 하는 열 우선 순서 방법이 있다.

간단히 말해서 행 우선 방법은 student[0][0] -> student[0][1]->student[0]

[2] 이런식으로 우선 0 의 0~3까지 그다음은 1의 0~3까지. 이런식으로 앞의 행

의 값을 쭉 넣고, 다음 행의 값을 넣는 방식이다.

그리고 열 우선 방법은 student[0][0] ->student[1][0]->student[2][0] 이렇

게 먼저 앞의 0의 0 값, 1의 0값, 2의 0값을 넣고 다음에 0의 1값, 1의 1값, 2의 1

값 이렇게 차례대로 넣는 방식이다. 

행 우선 방법과 열 우선 순서 방법에 따라 물리적 저장 순서가 다르기 때문에

배열의 원소 위치를 계산하는 방법도 달라져야 한다. 행의 갯수가 n1 이고, 열

의 갯수가 n2인 2차원 배열 A[n1][n2]의 시작 주소가 a고, 원소의 길이가 L 일

때, i행 j 열의 원소, 즉 A[i][j]의 위치는 행 우선 구조에서는 a + ( i * n2 + j ) *
L 이 되고, 열 우선 순서 구조에서는 a + (j * n1 + i) * L 이 된다.

논리 순서를 물리 순서로 변환하는 방법은 프로그래밍 언어의 컴파일러에 의해

서 결정되는데, C 컴파일러는 행 우성 순서 방법을 사용한다.

3차 배열도 이와 유사한 방법을 사용한다. 단지 배열의 크기가 지금은 행과 열

이였다면, 거기에 면이 하나 추가되는 개념이며, 논리적 구조를 물리적 구조로

바꾸는 공식은 조금만 생각하면 유추할 수 있으므로, 자세한 설명은 생략한다.
Posted by 바람처럼..
|


문제를 해결하기 위해 추상적으로 정의한 자료와 연산자는 구체적으로 구현되

어 실행되어야 하는데, 연산자의 구현은 처리할 자료를 표현하는 방법에 의해..

결정된다.

따라서 처리할 문제에 대한 자료를 가장 효율적인 방법으로 표현하는 것이 중

요하다.

자료구조에서 기본적인 자료 표현 방법으로는 순차 자료구조와 연결 자료구조

가 있다..

여기서는 순차 자료 구조를 알아보자..

가장 기초적인 자료를 표현하는 방법은 나열 하는 것이다. 동물이면 동물,

식물, 음식, 지리 등등을 나열한 목록을 list 라고 한다..

list 나열한 원소들 간에 순서를 가지고 있는 list를 선형 list 또는 순서 list라고

한다.

리스트를 표현하는 일반적인 방법은 다음과 같다..

list 이름 = ( 항목1, 항목2, 항목 3 )

선형 list는 원소들 같의 논리적인 수서와 메모리에 저장하는 물리적인 순서가

같은 구조로 되어잇는데, 이러한 구조를 순차 자료구조라고 한다..

따라서 순차 자료구조에서는 원소의 논리적인 순서대로 메모리에 연속적으로

저장된다..

즉, 순차 자료구조에서는 원소들이 순서대로 연속 저장되기 때문에 시작 위치

와 원소의 길이를 알면, 특정 원소의 위치를 알 수 있다.

시작 위치가 a고, 원소의 길이가 L 인 list에서 두번째 원소의 길이는

a + L 이고, 세번째 원소의 위치는 a + 2L 이다. 따라서 i 번째 원소의 위치는

a + (i -1 ) * L 이 된다..

 그렇다면, 선형 list 에서의 원소 삽입에 대해 알아보자...

 밥을 먹으로 갔는데, 밥집에 줄이 서있다....

일단 기다린다.. 그런데 누군가 새치기를 했다... (물론 이런경우는 없을 것이지

만 예를 들면이다..)

그렇다면 순번은 한칸씩 뒤로 밀린다...

이 것이 바로 선형 list 에서의 원소 삽입이다...

무언가 list에 순서대로 자료가 저장되어 있지만, 가운데 원소를 하나 집어 넣으

려면, 먼저 삽입할 자리를 만든 후에 그 자리에 원소를 삽입해야 된다..

그렇게 하려면, 메모리에 연속해서 저장되어 있는 자료들을, 한칸씩 뒤로 밀어

야 하겠다..

(n+1) 개의 원소로 이루어진 선형 list 에서 k번 자리에 원소를 삽입하려면,

k번 원소부터 마지막 원소인 n번째  원소까지 n - k + 1 개의 원소를 모두 한자

리씩 뒤로 밀어야 하므로 빈자리를 만들기 위한 이동 횟수는 n - k + 1 이 된다.

그렇다면 반대로 선형 list에서의 원소 삭제를 알아보자.

이번에는 반대로 차례대로 밥집의 줄을 서있는데, 갑자기 앞에 사람이 어디로

가버렸다.. 그렇다면 순서는 한칸씩 앞으로 당겨지게 된다...

이번에는 코드 상으로는 빠진 부분의 값은 뒤의 값이 덮어 버리면 되기 때문에

바로 값이 빠진 곳 부터 한칸씩 앞으로 값을 땡기기만 하면 된다...

이 것을 식으로 쓰면, (n+1)개의 원소로 이루어진 선형 list 에서 k번 자리의

원소를 삭제했다면 k+1번 원소부터 마지막 n번 원소까지 n - ( k + 1 ) + 1개의

원소를 모두 한자리씩 앞으로 옮겨야 하므로 필요한 이동 횟수는 n - ( k + 1 ) +
1 이 되어 정리하면, n - k 가 된다...

Posted by 바람처럼..
|


우리는 흔히 오른쪽 아랫배가 지속적으로 아프면.. 맹장을 의심한다...

예를 들면, '아 왜 이렇게 배가 아프지.. 맹장인가? ' 하다가.. 병원에

가보면, '아 급성 충수염이네요, 바로 수술 하셔야 겠습니다.' 라고 한다..

음.. 이 상황을 보면.. 맹장의 다른 표현이.. 충수.. 라고 생각할 수 있다..

하지만.. 충수에 대해서 직접 백과사전을 검색하보니.. 

                                                       (충수의 위치 )

맹장의 약간 아래 끝에 늘어진 가는 맹관(盲管)으로 충양돌기라고도 한다. 길이 6∼7cm, 굵기 0.5∼1cm로 맹장에 붙는 위치나 길이는 개인차가 크다.

라고 되어있고,

위치 맹장의 약간 아래 끝에 늘어진 가는 맹관

이렇게 되어있다.. 흠....

맹장의 약간 아래끝에 늘어졌다면, 맹장은 아닌 것이다.. 그렇다면 맹장을 검색

해보니.. 소장의 말단부에서 대장으로 이행하는 부위에 있는 소화관. 막창자라

고도 한다. 파충류 이상의 고등동물에 존재하는 장기이다. 사람의 맹장은 오른

쪽 하복부의 회장 개구부 아래에 있는 짧은 소화관으로, 길이 5~6cm이며, 맹장

의 뒤쪽 내부벽에서 충수가 돌출해 있다.

이렇게 되어있다.. 이제야 정확히 알 수 있는 것이..

소장에서 대장으로 넘어가는 마지막 부분이 맹장이며, 그 맹장에서 새끼손가락
 
만한 길이로, 충수가 돌출해 있는 것이다... 흔히 우리가, 생각했을 때, 맹장 부

분이 아프니, 맹장의 염증이라고 생각하기 숴워서, 맹장염 이라고 불렀지만, 그
것은 보통 충수염을 부르는 의미였고, 실제로 맹장염이라면, 다른 수술 방법이

필요하다고 한다... 충수염이라면, 충수가 뻗어 나온 부분만 절제를 하고, 봉합

하면 되지만, 맹장은 대장과 소장을 이어주는 부분이라서 좀 더 어려운 수술이

된다고 한다. 그리고 충수염으로 수술을 한번 받으면 평생 다시 발병할 일은 없

다고 하지만, 가끔 재발병하는 경우도 있다고 한다... 그 것은 처음 수술 받을

때 약간 남은 충수가 다시 염증이 생기는 증상으로, 흔하지는 않지만, 가능성은
충분히 있다... 이제 맹장과 충수. 헷갈리지 말고 써야 겠다.

Posted by 바람처럼..
|

후쿠시마 원전에서 처음으로 급성 백혈병으로 숨진 사람이 나왔다는 뉴스를

보았다... 아래는 기사 링크이다.

기사 원문 보기
 
물론 기사를 보면 이 사람의 급성백혈병 증상은 그렇게 단기간에 오는 것은 아

니라고 한다..

하지만, 후쿠시마 원전의 사고가 터진 이후로 체르노빌에 대한 다큐멘터리에서

도 말하는 내용은 만에 하나 라는 것이, 통계적으로는 만에 하나이지만, 그 것

의 당사자 입장에서는 굳이 방사능이 아니였다면, 걸리지 않았을 병들에 걸렸

다고 생각한다면 정말 방사능은 큰 재앙인 것이다..

아무튼 우리 기억속에서 또 다시 방사능에 대한 기억은 사라지고 있는 듯 하다.

물론 우리나라의 원자력 발전소 주민들은 매일매일 불안에 살아 가고 있겠지만

조금만 떨어진 곳에서는 방사능에 대한 걱정을 많이 잊은 듯 하다..

처음에 사고가 나고 일본은 주변바다에 냉각수를 방류해 버리고, 대한민국

상공의 방사능량을 시간별로 체크하고 뉴스에 내보내고 하던 것들이 엊그제

같은데.. 이제는 말도 안나온다...

그 당시에.. 어땠는가?? 가랑비만 조금 내려도 방사능 비니 머니 하면서, 애들

에게 우비에 가급적 외출도 삼가고 그 정도의 반응이였다면..

현재는 그 소동을 다 잊은 듯 하다...

올해 예상치 못한 폭우가 쏟아지고, 주가는 폭락하고, 주민 투표 문제가 붉어지

고, 요즘은 교육감문제도 나오고.. 언뜻 생각하면 우리가 지금 방사능에 신경쓸

그런 상황이 아닐 수 있다..

물론 내 생각은 원자력 발전은 정말... 필요악이다... 그리고 버릴 수 없다....

현재 우리나라에서 원자력 발전을 포기한다면, 전력을 생산해내기 위한 원가부

담에 전기세는 오를 것이 뻔하고, 그러면 물가는 또 오르고, 악순환이 될 수 밖

에 없다.. 하지만 그렇다고 원자력 발전소가 만약이라도 폭발한다면, 그 것은

이제 정말 우리 목숨이 걸린 일이라.. 타협할 여지도 없다....

그러니.. 이러지도 저러지도 못하는 것이 아닐까..

하지만, 버릴 수 없다면 최대한 대비를 하여 안전하게 쓰는 것이 우리의 안전과

직결 될 것이다....

글을 쓰다보니 의문이 드는 것이... 항상 우리나라에 큰일이 있을 때 촛불집회

에 시위 하시는 분들 보면... 그 당시의 이슈가 생기면, 우르르 몰려갔다가...

다음 이슈가 생기면 또 우르르 몰려만 가고.. 사후 처리는 없는 듯 하다..

예전에 미국산 소고기 문제일 때도.. 대학생들 반값 등록금 때에도...

방사능 때에는 시위 정도는 아니였지만, 온갖 불신과 사회 불안을 조장하고..

희망버스 문제에도.. 항상.. 그 당시 이슈만 따지고.. 그러고.. 그냥 끝이난다..

난 솔직히.. 그런 시위자체는 찬성이다.. 왜냐하면.. 사실 한명의 소시민이..

혼자 얘기한다고 사회가 달라질까?? 하지만 군중이 되면 의견을 관철하기는

좋아질 것이다.

하지만 그 군중의 모인 목적을 망각하고, 자신의 인기를 높이고, 사회의 불안만

조장하고.. 니 편 내 편을 가르고.. 이런 것이 시위의 목적이자.. 의미가 된다면.

그 것은 시위가 아니고.. 폭동이다.

말이 이상한 곳으로 샛는데.. 머 요즘 너무 망각했던 일본의 방사능 문제에..

우리도 조금씩 관심을 기울였으면 하는 바램이다...
Posted by 바람처럼..
|


가변 인자란.. 쉽게 생각하면, 인자(파라미터) 값이 변한다는 의미이다..

정확히는 인자의 개수가 변한다는 뜻이다...

같은 함수명이라도,, 파라미터를 2개, 3개,.. 이렇게 쓸 수 있다는 것이다.

그렇다면 함수 오버로딩이 아닌가 생각할 수도 있다..

하지만 그 것과는 엄연히 다르다..

흔히 우리가 쓰는 printf()를 떠올리면 이해하기가 쉽다...

printf("%d %s ",  int , char ) ;

라고 보면 똑같이 printf() 이지만.. 뒤의 파라미터들이.. 2개일 수도.. 3개일수도

아니면 더 클 수도 있다...

이럴때 쓰는 것이 가변인자이다...

가변 인자를 사용 하려면.. 일단.. 함수의 원형을 정의하면된다..

가변 인자를 이용해서.. 입력된 숫자들의 총합을 구하는 함수를 만들어 보자..

int add ( int, ... ) ;

이렇게 선언을 한다... 앞의 int만 유일하게 고정 인자고,.. 뒤의 ... 으로 뒤에는

몇개의 숫자가 오든 상관없다 ( 앞의 int를 count로 쓸 것이니 함수를 사용할 때는.. 신경을 써야한다..)

그리고 가변 인자를 쓰기 위해서는 헤더파일..

#include <stdarg.h>

를 추가한다...

그리고 가변 인자를 위한 3개의 매크로가 있다..

va_start(va_list list) ;
va_arg(va_list list, type) ;
va_end(va_list list );

이다...

va_start는 list를 초기화 한다.. 그 의미는 포인터를 list의 맨 처음을

가리키도록 하는 것이다...

이 함수를 쓰지 않으면, va_arg를 통해서 모든 인자를 다 쓰면, 처음으로 되돌

릴 수 없게된다...

va_arg는 고정 인자를 제외한 나머지 인자들을 얻기 위해 사용되며, 보통은

for()문을 이용해서 처리한다...

type위치에는 int, char 같이 가변 인자의 자료형을 넣어준다...

va_end는 가변 인자의 사용을 끝낼 때 사용하지만, 보통은 사용 안해도 무방하다..

그럼 동작이 가능한 함수를 만들어 보자...

위의 사진의 int add(int count, ...) 함수의 내부를 보면..

va_* 매크로를 이용하여서 리스트를 초기화, 값을 받고, 종료 시킨다..

그리고 실행시킨 결과 값이다....

어떤가.. 가변 인자를 잘쓰면, 좀 더 깔끔한 코드를 작성할 수 있지 않을까?

하지만, 가장 큰 주의사항들을 정리하면..

꼭, 1개 이상의 고정 인자가 있어야 한다는 점이다.....

위 사진 처럼.. int add(int count, ...)  의 int count가 고정 인자 이다..

이 것을 없얘고 int add(...) 이렇게 쓰면 에러를 일으킨다..

printf()에서 첫 인자가 꼭 "%d", "%d %s" 인 이유가 바로 여기있다..

위처럼 %* 가 있어야.. 뒤에 가변 인자가 몇개인지.. 알 수 있기

때문이다...

'프로그래밍 > C,C++' 카테고리의 다른 글

[C,C++] 이름공간(namespace)  (0) 2011.09.14
[C,C++] 인-라인(in-line) 함수  (0) 2011.09.14
[C,C++] getchar() 의 문제점..  (2) 2011.08.28
[C,C++] scanf 와 fgets  (0) 2011.08.27
[C,C++] sprintf 사용하기...  (2) 2011.08.23
Posted by 바람처럼..
|

char를 입력받을 때 흔히 쓸 수 있는 것이 getchar() 이다..

하지만 getchar()는 쓸 때 한가지 명심할 것이 있다...

getchar() 함수를 써서 값을 입력받은 후, 엔터를 치면 함수가 진행된다...

그 때 개행 문자 하나도 같이 버퍼에 쌓이게 된다...

그 후 getchar()가 실행되어서 버퍼에서 입력된 값을 받은 후..

또 다시 1번 더 getchar()를 실행해 버린다...

예를 들면.. 지금 입력된 값이 y 인지 n 인지 판단하는데..

y 값이면 y, 나머지는 n로 인식된다고 생각해보자...

y 후에 엔터를 쳤더니,

한번은 y로 인식했는데 자동으로 다음에는 n 를 한번 더 인식한다.

( 반복문일 경우임 )

이유는 처음에는 y를 입력받은 걸로 처리하고, 또 버퍼에 값이 있어서 값을 보

니.. \n 인 것이다. 그래서 y가 아니기 때문에.. n로 인식하는 것이다..

이럴때는 getchar()를 2번 연속으로 적으면 된다..

int a = getchar() ; getchar() ;

이렇게 되면 자동으로 a에는 첫 입력값, 그 후에는 그냥 버퍼에 값을 한번 더 부

를 뿐이다....

하지만 문제가 하나있다..

그냥 값 입력없이 엔터를 쳤을 때다... 그렇게 되면 처음 getchar()에서 개행 문

자로 인식 되지만, 뒤의 getchar()에서 문제를 일으킨다..

그래서 이 것을 모두 해결한 코드는..

if( a == '\n') continue;
else getchar() ;

이렇게 쓰면 된다..

'프로그래밍 > C,C++' 카테고리의 다른 글

[C,C++] 인-라인(in-line) 함수  (0) 2011.09.14
[C,C++] 가변 인자란 ...  (0) 2011.08.28
[C,C++] scanf 와 fgets  (0) 2011.08.27
[C,C++] sprintf 사용하기...  (2) 2011.08.23
[C,C++] 문자열에 대하여...  (0) 2011.08.23
Posted by 바람처럼..
|

문자를 입력받을 때 흔히, scanf나 fgets 를 사용한다...

2가지 이외에도 gets() 라는 함수인데,

이 함수는 치명적인 문제가 있다..

버퍼 오버플로우를 검사하지 않기 때문에, 10의 공간을 할당하고 나서,

12의 값을 넣어도 ( 메모리의 크기 ) 일단은 들어간다..

하지만 나중에 큰 문제를 일으킬 소지가 있다...

그리하여, scanf와 fgets를 사용한다고 치면,

scanf는 숫자, fgets는 문자열을 입력받는 것으로 사용하는 것이 좋다.....

scanf의 가장 큰 단점은 띄어쓰기를 인식 못한다는 점이다...

예를들어.. 이름을 입력하고자

char name[20] ;
scanf("%s", name ) ;

이렇게 입력하고 콘솔창에 test test test ; 이렇게 입력한다면...

출력 결과는..

test 만 나온다...

만약 다 입력 받고 싶으면,

scanf("%s%s%s", name1, name2, name3 ) ;

이런식으로 입력하면 되긴하지만.. 원하는 동작은 아니다...

그리하여 scanf가 편리하긴 하지만.. 숫자를 입력받을 때 정도만 쓰는 것이 좋다...

문자열을 입력받을 때는 fgets를 사용하려면,

fgets(name, 10, stdin ) ;

이런식으로 사용하면된다.. 가운데의 10은 버퍼의 크기이기때문에 자유롭게..

변경하면된다...

하지만 fgets도 문제가 있는데.. fgets는 자동적으로 개행문자가 삽입된다..

개행문자는,, printf같은 것을 사용할 때 다음줄로 넘어가는 \n 이다..

그렇기 때문에..

출력시에는 문제없이 출력된 것 처럼 보이나, 문자열의 크기를 비교한다던지

하면 문제가 발생할 수 있다..

그러니 꼭, 입력된 문자의 길이를 검사하여서, 개행문자를 없애고 그 자리에

/0(NULL) 을 넣어주면된다..

이 것을 코드로 표현하면..

name[strlen(name) - 1 ] = '\0' ;

처럼 넣어줘도 된다...

(단, name의 크기가 유동적이면 힘들고, 딱 배열의 크기에 맞게 설정되었을 때에 쓸 수 있다.. )

'프로그래밍 > C,C++' 카테고리의 다른 글

[C,C++] 가변 인자란 ...  (0) 2011.08.28
[C,C++] getchar() 의 문제점..  (2) 2011.08.28
[C,C++] sprintf 사용하기...  (2) 2011.08.23
[C,C++] 문자열에 대하여...  (0) 2011.08.23
[C,C++] 배열의 초기화..  (0) 2011.08.22
Posted by 바람처럼..
|

openCV를 이용해서 간단한 화면 전환 방법을 소개한다...

간단히 cvFlip() 함수를 쓰면 된다...

cvFlip 함수 원형은 다음과 같다..

cvFlip( const CvArr* src, CvArr* dst CV_DEFAULT(NULL),
                     int flip_mode CV_DEFAULT(0));

먼저 첫번째 파라미터에 현재 이미지, 두번째가 변환 후 저장될 이미지를 넣으

면 되고, 마지막, 파라미터를 0을 넣으면 상하 반전, 1을 넣으면 좌우 반전이다.


위의 사진이 0을 넣은 상하반전

,


위의 사진이 1을 넣은 좌우 반전 이다..

두 사진 모두 왼쪽이 원본이고, 오른쪽이 변환된 화면이다..
Posted by 바람처럼..
|

얼마전에 집으로 지방세 고지서가 날라왔습니다...

머.. 전부터 인터넷으로 내고 있었기 때문에...

이번엔 인터넷으로 내는 방법을 알아보겠습니다...

일단 인터넷지로를 검색합니다.


인터넷지로로는 도시가스요금, 전기요금 다 납부 가능합니다..

단, 공인인증서가 필요합니다..

공인인증서는 각 은행이나, 더 많은 결제 및 검색을 할 수 있는 4000원짜리..

유료 공인인증서를 발급하시면 됩니다..


인터넷지로 홈페이지의 첫 화면에 납부고객용 인터넷지로를 클릭합니다..


저는 이미 공인인증서를 등록해놨기 때문에, 공인인증서 로그인을 했습니다.

로그인 후에.. 지방세 항목을 클릭합니다.



그러면 위의 화면처럼 지역을 선택하는 창이 나옵니다..


그리고 확인을 눌리면 위의 사진처럼, 납부하기(상세보기) 버튼을 클릭합니다.

 


결제 방법은 계좌이체와, 신용카드 2가지가 있는데, 저는 신용카드로 결제

했습니다...


결제가 끝나면, 정상납부라고 뜨고,

 


화면 왼편의 납부확인증 보관함에서.. 납부확인증을 조회할 수 있습니다..

그리고 올해에 알게된 사실인데..

제가 작년까진 대학생이였고, 졸업 후 올해부터 회사를 다니고 있는데,

대학생 때, 군대 전역 후 세대주로 되었습니다...

그래서 2009년부터 주민세 고지서가 날라와서, 내야 되는 건가 보다..

하고 납부했었는데요...

알고보니, 학생은 면제 가능 하다고 하네요....

현재 납부는 하지 않으셨는데, 주민세 고지서가 날라왔었다면,

해당 구청에 전화를 거셔서 재학증명서를 보내시면 면제가 되구요..

저같이 2년동안 납부를 했지만, 잘못 납부된 부분에 관해서는..

졸업증명서를 제출하고, 환급받을 계좌번호를 보내면..

계좌로 환불해 준다고 하네요...

내야될 세금은 반드시 내야하겠지만, 안 내도 될 세금을 납부했으면..

꼭 알아보시고 환불 받으세요..

'잡동사니' 카테고리의 다른 글

인터넷으로 전기요금납부!  (0) 2011.09.07
맹장염과 충수염??  (0) 2011.09.04
금값 폭락?!  (0) 2011.08.26
잘못된 표현.. 수입산..  (0) 2011.08.21
ktx 싸게 타기?! 할인 카드 발급 ?!  (0) 2011.08.21
Posted by 바람처럼..
|

금값 폭락?!

잡동사니 2011. 8. 26. 16:39

요즘 금값이 많이 올라서..

금을 직접 사볼까.... 금 펀드를 가입해 볼까.. 고민했었다....

그런데... 갑자기 금값이 폭락?!?

기사 원문 보기

어제 부터 갑자기.. 금값이 1만 이상 떨어졌다고한다...

기사를 보면,.. 리먼 브라더스 사태 이후에 가장 많은 하락이 되었단다...

요즘 주식도 오르락 내리락 하다 보니...

가격은 변하지만, 현금화 시키기도 쉽고, 그리고 왠만해선 값이 떨어지지

않아서,, 금을 구입하는 사람들이 많아졌는데..

이제 금도 믿기 힘들어 진 것일까??

은행 이자는 적고...

투자는 위험성이 높고....

요즘은 더더욱 돈 벌기 힘든 상황이 된 것 같아서 안타깝다...
Posted by 바람처럼..
|


 이제 내일이면, 세계 육상선수권이 시작됩니다..


 대구 스타디움과 홈플러스 사이쯤에, 칼라 스퀘어 라고...

 여러가지 업체들이 입주한 상가같은 곳에...

 부스를 설치하고, 체감형 게임을 설치하로 갔습니다....

2일 정도 왔다갔다 하며, 찍은거라... 사진이 언제 찍힌 건지 좀 뒤죽박죽이고,

폰으로 찍어서 화질은 좀 안좋습니다..

 


칼라 스퀘어의 중앙광장(?) 이라고 해야할까요?

건물이 콜로세움처럼 주변을 삥 둘러서 있고, 가운데 광장에서 여러가지 각도

로 찍은 사진입니다..

 


롯데리아도 있군요.




 닭집, 밥집, 햄버거, 커피숍... 여러업체가 들어와있군요..




그리고 영화관도 있군요....

아직 공사진행 중이라 좀 어수선 하지만.. 

이제 곧 정리가 되겠죠..

 


이건 2일 중에 첫날에 부스 내부 정리중인 사진입니다....

어제 저녁까지 작업해서.. 이제는 거의 완성.. 한번쯤 구경들 오세요~


 설치작업중에.. 머가 빠진게 좀 있어서, 사로 나가는 길에 주차장에서 찍었습

니다. 주차장이 동서북쪽에 다 있네요... 이 곳은 북쪽편 주차장입니다...

이 시간쯤 개막식 리허설 중인가 봅니다..

노랫소리와 폭죽도 터트리네요..


밝을 때 찍으면 사진이 잘 나오는 것 같네요..


차 타고 출발하려는데 갑자기 뒤에서 '쾅' 소리가 나서 깜짝 놀라서 처다보니,

폭죽을 쏘고 있네요.. 실물은 더 좋았는데.. 타이밍이 잘....;;

그리고... 밤이 되어서야 작업이 끝나고... 이제 집으로..

가는 길에 찍은 야경 사진들입니다...


 야경은 정말 멋지네요.... 아.. 이럴땐 정말 카메라가 사고싶습니다..


내일부터 시작되는.. 세계육상선수권에서...

많은 신기록들과, 우리나라 선수들의 선전을 기대합니다...





 
Posted by 바람처럼..
|

코딩을 하다보면, 문자열에..

숫자를 넣어야 할 때가 있다..

그럴 때 유용한 것이 바로 sprintf 이다..

sprintf를 쓰기 위해서는

#include <stdio.h> 가 필요하다...

사용법은...

char buf[256] ;

int a = 9 ;

sprintf( buf , " test%d", a ) ;

이렇게 넣으면..

buf 에는 test9 라는 문자열이 저장된다...

응용하면,

char *string = "world" ;
sprintf( buf, "Hello %s %d", string, a ) ;

이렇게 쓰면,

buf에 Hello world 9 라고 저장된다...

또,

char buf[256] ;

for( int i = 0 ; i < 3 ; ++i )
{
sprinf( buf, "test %d", i ) ;
printf( "%s\n", buf ) ;
}

이렇게 쓰면,

test0
test1
test2

이런식으로 출력된다..
Posted by 바람처럼..
|

문자열은 C언어에서는 문자 배열이라고 생각하면 된다...

문자열은 여러가지 특징이 있는데, 그 것을 알아보자...

그전에 상수에 값이 들어가는 것에 대해 한번 알아보자...

a , 'a', "a" 이 3 가지의 상수가 있다고 봤을 때.. 이 것들은 모두 다르다..

a 같은 경우는 그냥 일반적인 상수라고 보면된다...

흔히, int a = 4 ; 에서 4 같이 그냥 숫자를 바로 넣는 형태이다...

'a' 는 하나의 문자 상수이다..

'a' 자체가 저장되기 때문에..

char a = 'a' ; 같이 쓸 수 있다...

그럼 내부 적으로는 char a 안에 아스키코드 형태로 97로 저장된다..

( a를 %d로 출력 하면 97이 나오고, %c로 출력하면 a 가 나오는 식이다.)

그럼 마지막으로 "a" 가 바로.. 문자열 형태이다...

단지 따옴표가 붙었을 뿐이지만.. 그 상태로 char* a ; 에 저장을 시키면..

문자열 형태로 저장된다.. ( 즉, char*가 아니라 char면 에러를 일으킨다. )

문자열 이라는 말은 제일 마지막에 /0 (NULL 문자 ) 가 들어가 있는 형태이다.

문자열을 넣을 때 우리는 ..

char* string = "Hello world" ;

이렇게 값을 넣으면 된다...

이러면 자동적으로 마지막에 널이 들어가 있다.

이 것을 메모리 상에서 보면.. string 이라는 포인터 변수가 잡히고,

그 포인터 변수가 가르키는 주소값이 바로.. Hello 의 H의 위치이다..

이 문자열의 주소 위치는 컴파일러가 알아서 저장한다..

그럼 문자열의 출력 방법을 알아보자...

printf("%s\n", string ) ;

printf( string ) ;

puts( string ) ;

이렇게 여러가지가 있는데... 단순 출력만을 한다면..

그냥 puts가 가장 가볍고 좋다..

또 배열처럼 string + 2 라고 쓰면 string 위치부터 + 2 주소값이 더해져서..

Hello의 첫번째 l 을 가리키게 되며, 그 값부터 널을 만나기 전까지 출력이 된다.

그렇다면

char *string ;

char string[] ;

의 차이점은 무엇일까??

쉽게 생각하면.. 같은 행동을 하고, 출력 하기 위한 방식도 똑같고, 각 변수명이

문자열의 첫 주소를 가진다...

하지만 이 2가지는 엄연히 다르다...

위의 *string 같은 경우는.. 포인터 변수로, 따로 포인터 변수의 4바이트 주소를

가지고, 그 주소에서 문자열의 첫 시작점의 주소를 가리킨다..

하지만 2번째 의 경우는 문자열 배열로써...

그냥 문자열의 첫번째 위치를 바로 가리키고 있다...

이 것이 가장큰 차이점이다..

그래서 string++ 을 하면 문자열의 다음 변수를 가리킬 수 있지만,

아래의 배열일 때 ,

string++을 하면 에러가 난다..

왜냐하면 string 자체는 배열명이기 때문에.. 주소값을 가지고는 있지만..

++ 연산자를 풀어보면, string = string + 1 ; 과 같은데,

배열명에는 값을 넣을 수는 없기 때문이다..

그리고 char* string = "Hello" ; 의 Hello는 문자열 상수라고 보면된다..

상수는 즉, 고유한 하나의 값이다... 1이 1이지 0이 아닌 것처럼...

그래서,

*string = 'A' ;

이렇게 값을 넣으려 그러면.. 에러가 난다...

포인터 변수가 가리키는 첫 주소값의 내용을 바꿀 수 있을 것 같지만,

그 것은 불가능하다..

하지만 반대로

char string[] = "Hello" ;

이런 배열 형태로 저장되어 있다면,

string[0]  = 'A' ; 처럼 쓰는 것은 또 가능하다 ...

문자열... 간단히 쓰고있지만, 내부적으로의 흐름을 알아야...

나중에 헷갈리지 않고 잘 쓸 수 있을 것이다...
Posted by 바람처럼..
|


오.. 요근래 계속 날씨가.. 흐리기만 하고..

가끔 맑은 날이 있었는데...

오늘 오후쯤.. 보슬비 정도만.. 내리다가..

저녁 때쯤 비가 그치니... 엄청난 무지개가 생겼군요.....

예전에도 한번 봤는데 그때는 그냥 지나갔지만..

오늘은 사진도 찍었습니다...


한개는 정말 찐하고,, 뒤의 무지개는 좀 연했지만..

정말 멋진 쌍무지개 였습니다..

화질이 조금만 더 좋았다면 아주 좋았을 텐데...

그래서 동영상도 찍었습니다.



흠.. 왠지 쌍무지개를 보니..

먼가 좋은일이 있을 것 같은 느낌이 드네요~ ^^ *

Posted by 바람처럼..
|

프로그램을 작성할 때 쓰는 가장 보편적이고, 기본적인 자료구조가..

배열이다...

하지만 배열을 초기화를 제대로 하지 않으면 여러가지 문제가 생긴다..

그래서 초기화를 하는 방법을 소개하겠다...

먼저 1차원 배열이다..

가장 기본적인 형태인..

int intp[3];

이렇게만 쓰고 출력을 해보면 쓰레기 값이 들어가 있다..

이제 초기화를 해줘야 하는데..

가장 단순한 초기화 방법은...

int intp[0] = 0 ;
int intp[1] = 0 ;
int intp[2] = 0 ;

이다.. 하지만.. 이번엔 3개 같은 경우니 가능하지만 더 많아지면..

이렇게 하면 소스 가독성이 떨어진다..

그래서 반복문을 사용해서..

for(int i = 0 ; i < 3; i++ )
      intp[i] = 0 ;

이렇게 쓰면 된다..

하지만 가장 좋은 방법은..

int intp[3] = {0} ;

이렇게 쓰는 것이다.. 단, 이 방법은 선언과 함께 사용해 주어야 한다..

방금 방법은.. 0으로 초기화 하는 방법이였고, 혹시 값을 넣어야 한다면,

다음과 같이 초기화 해주면 된다..

( 이 것도 선언과 함께 사용하여야 한다. )

int intp[3] = { 1, 2, 3 } ;

이런 식으로 말이다.. 하지만..
 
int intp[3] = { 1, 2, 3, 4 } ;

이렇게 4개를 넣으면 어떻게 될까?

머.. 동작은 상관없이 된다.. 마지막 4는 짤리겠지만 말이다...

그런데 혹시 뒤에 4개를 넣은게 맞는 것이고,

앞의 3이 잘못 되었다면... 문제가 생길 것이다..

그럴때를 대비해서..

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

처럼 넣어주면 된다...

2차원 배열도 비슷하다..

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

이렇게 선언하거나,

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

이렇게 선언하면 된다..
Posted by 바람처럼..
|