U E D R , A S I H C RSS

큐와 스택/문원명

큐와 스택 처리 인데요...

여기서 의문점은 string헤더 파일을 include하지 않고 배열을 char *형으로 하고 #1,#2,#3을 strcpy를 사용하여 고치고 실행한 후,
처음에 "empty"로 초기화 하거나 PUSH를 할때, 배열의 모든값이 한개의 값으로 변경된다는 점 입니다...아직도 그 이유를 모르고 있음..

AnswerMe 해당 코드를 올려주세요.#1, #2, #3 를 어떻게 바꾸시는지 모르겠습니다. 그리고 이 페이지 이름 정리 해주세요.

~cpp 
 #1 : strcpy(array[i], "empty");
 #2 : strcpy(array[0], "empty"); 
 #3 : strcpy(array[tail], "empty");
가능하다면, 전체 코드를 올려주세요. 지금 제 생각대로라면, 불가능한 코드를 말씀하시는 것 같아서요. --NeoCoin

문제의 전체 코드는 다음과 같습니다. --문원명
밤(10시 이후)에 답변드리겠습니다. 저에게는 상당한 학습의 기회가 될것 같군요. 재미있네요. 일단, 글로 표현하기에 자신이 없거든요. 주변의 사람들을 붙잡고 물어보는 것도 좋은 방법이 될것 같습니다. 그리고, 학교 교제의, call By Value, call By reference 와 Pointer 관련 부분을 읽으시면 좋겠습니다. --NeoCoin

설명이 복잡한것 같습니다. 안본셈 치세요 --;;
~cpp 
#include <iostream>  
#include <string>

using namespace std;  
const int ASIZE = 5;  


// VC++ 7.0 에서 컴파일 한 결과, 실행하면 디버그 모드에서 조차 실행되지 않습니다.
// VC++ 6.0 이라면, 아마 release 모드에서 실행이 되지 않을것입니다. 
void main()  
{  
    std::string a;
    char * array[ASIZE];    // Pointer의 배열입니다. 즉, 문자를 저장할 공간은 아닙니다.
                            // char 를 가리킬수 있는 주소를 저장할수 있는 32bit 값들의 Pointer들 5개
                            // 배열입니다.
                            // 각 Pointer들은 의미 없는 값들로 채워져 있습니다.(컴파일러 의존)
    int tail = 0, status = 3;  
    int select, count;  
    for(int i = 0 ; i < ASIZE ; i++)  
        strcpy(array[i], "empty");    // Pointer가 가르키는 부분이 우연히 접근 가능한 메모리 공간이라면
                                    // 덮어 씌웁니다. VC++ 6.0 Debug 모드에서는 디버그 정보를 위해서
                                    // 코드 주변에 접근 가능한 공간을 두기 때문에 에러가 없이 넘어가는
                                    // 것으로 보입니다. 경험상 debug 모드에서는 어느정도 수용가능한
                                    // 주소로 초기값이 세팅되어 있었습니다. Release 모드로 바꾸어서 컴파일 해보세요.
    do  
    {  
        cout << "1. PUSH   2. Pop   3. Stack   4. Queue   5. Show   6. Exit" << endl;  
        cin >> select;
        switch(select)  
        {  
        case 1 :   
            cout << "입력 : ";  
            if (tail == ASIZE)   
            {  
                cout << "오버 플로우 입니다." << endl;   
                break;  
            }  
            cin >> array[tail];  // array[tail] 은 아직까지 의미없는 메모리 영역을 가리키는
                                 // 하나의 Pointer입니다. 그 영역에 임의로 문자를 채우는 것이므로
                                 // 안전을 보장할수 없습니다. 접근 가능한 메모리 영역이라면, 입력 받은 만큼
                                 // 덮어 씌웁니다.                         
                                 
                                 
            tail++;  
            break;  
        case 2 :  
            if(status == 4)                 //큐  
            {  
                strcpy(array[0], "empty");   
                tail--;  
                for(count = 0 ; count < tail ; count++)  
                    array[count] = array[count+1];  // string의 경우와 달리, Pointer 값만 복사됩니다.
                                                    // string 이라면, call by value 로 class간 
                                                    // 실제 복사가 이루어 집니다.  계속 같은 값에 세팅되는 이유는
                                                    // 이코드 때문입니다. 배열상의 모든 char 포인터가 결국 같은 곳을 가리키게 됩니다.
                                                    // 그래서 종반에는 한곳을 바꾸면 모두가 바뀝니다.
            }  
            else                            //스택  
            {  
                tail--;  
                strcpy(array[tail], "empty");  // 위의 이유로, 역시 의미없는 영역에 대한 복사 입니다.

            }  
            break;  
        case 3 :   
            status = 3;  
            break;  
        case 4 :  
            status = 4;  
            break;  
        case 5 :   

            for(count = 0 ; count < tail ; count++)  
            {  
                cout << array[count] << "]    ";  // 역시, 의미없는 영역을 가리키는 Pointer를 출력하려는 시도
                                                // 입니다. 앞서, empty+null 이라는 값을 메모리에 억지로 
                                                // 씌웠기 때문에, 값이 출력 될수 있습니다.
            }  
            cout << endl;  
            break;  
        case 6 :   
            break;  
        default :  
            cout << " 1부터 6까지의 수를 입력하세요 " << endl;  

        }  

    }while(select != 6);  
}  

입력 관련 설명, cin을 통한 ~cpp std:string에 입력과, char* 에 입력시 차이

cin 이 string을 입력 받는 코드는 ~cpp C:\Program Files\Microsoft Visual Studio\VC98\Include\istream 에 정의 되어 있습니다. 궁금하시면, Debug 모드로 따라가 보세요.
처음에 의도한 string 배열 코드는 다음과 의미가 같습니다.
~cpp 
string element;
cin >> element 
이 코드중 >> 는, string에 정의된 코드를 조금 뜯어 보면, 종단에 다음과 같은 코드를 수행합니다. 필요 부분을 발췌하였습니다.
~cpp 
    ... 생략 ...
if (_Ok)    // 입력이 종료되었나요? 기본적으로 enter, space 기준 종료
        {    // state okay, extract characters
     ...생략...
        _Str.erase();   // 저장할 string 공간 초기화 위에서 element

        _TRY_IO_BEGIN   // 예외 처리 시작

        /// 입력받을 문자열의 길이 알아내고, 저장 공간 준비
        _Mysizt _Size = 0 < _Istr.width()   
            && (_Mysizt)_Istr.width() < _Str.max_size()
                ? (_Mysizt)_Istr.width() : _Str.max_size();                 
               
        ...생략...

        /// 순회하면서, 문자를 string에 더하는 작업
        for (; 0 < _Size; --_Size, _Meta = _Istr.rdbuf()->snextc())
          ...생략...
                _Str.append(1, _Traits::to_char_type(_Meta));   // 문자를 하나씩 더한다. 이때, string 객체가 
                                                                // 스스로 메모리를 할당합니다.
         ...생략...
그러나, 다음과 같은 코드
~cpp 
char* element;
cin >> element;
는 종단의 입력값을 세팅하는 코드가 다음과 같습니다. 위와 거의 동일한 과정을 거칩니다.
~cpp 
...생략...
*_Str++ = _Traits::to_char_type(_Meta);	// _Str 은 위의 char* 형인 element 입니다. 즉, 문자를 저장하는 공간을 할당하는 코드가 없습니다.
                                              // 그래서, element가 가리키는 알수 없는 곳에 값을 저장하려고 합니다.
                                              // 만약 그공간이 OS의 보호아래 현재 프로그램이 접근할수 없는 영역이라면, 
                                              // 프로그램은 죽습니다.
...생략...


이 페이지 이름 정리 어떻게 해야하는지 잘 모르겠어요..이곳을 지우고 페이지를 새로 만들어야 하나요?
DeleteMe 질문의 의도은 두가지의 의미를 담을수 있습니다.
  1. 페이지이름고치기 방법
  2. 페이지이름 자체에 대한 고민

두 링크 모두 어느 정도 도움이 된다고 생각합니다. 근처의 선배들에게 물어보세요. 서로 고민하면서, 좋은 페이지 구조를 만들어 보세요. 이 자체가 프로그래밍의 과정과 별다를 것이 없습니다.

그리고 위키의 사용 방법이나, 철학들을 도움말을 기점으로 따라가서 읽어보시면 알수 있습니다. 그러나 단발성 게시판에 익숙한 많은 분들이 쏟아지는 정보에 두드러기가 날지도 모르겠군요. ^^;; 위는 그중 필요한 링크 입니다. --NeoCoin
ps. 초반에 데블스 캠프를 대비한 ZeroWiki의 사용 방법에 대한 정책이 부재했던것 같습니다. 하지만, 이 자체가 즐거운 학습의 기회가 될수 있을 것 같습니다.



~cpp 
#include <iostream>
#include <string>
using namespace std;
const int ASIZE = 5;

void main()
{
	string array[ASIZE];
	int tail = 0, status = 3;
	int select, count;
	for(int i = 0 ; i < ASIZE ; i++)
		array[i] = "empty";					//#1
	do
	{
		cout << "1. PUSH   2. Pop   3. Stack   4. Queue   5. Show   6. Exit" << endl;
		cin >> select;
		switch(select)
		{
			case 1 : 
				cout << "입력 : ";
				if (tail == ASIZE) 
				{
					cout << "오버 플로우 입니다." << endl; 
					break;
				}
				cin >> array[tail];
				tail++;
				break;
			case 2 :
				if(status == 4)			//큐
				{
					array[0] = "empty";		//#2
					tail--;
					for(count = 0 ; count < tail ; count++)
						array[count] = array[count+1];
				}
				else				//스택
				{
					tail--;
					array[tail] = "empty";		//#3
				}
				break;
			case 3 : 
				status = 3;
				break;
			case 4 :
				status = 4;
				break;
			case 5 : 
				
				for(count = 0 ; count < tail ; count++)
				{
					cout << array[count] << "]\t";
				}
				cout << endl;
				break;
			case 6 : 
				break;
			default :
				cout << " 1부터 6까지의 수를 입력하세요 " << endl;
		
		}

	}while(select != 6);
}
Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2009-05-27 07:09:19
Processing time 0.0970 sec