• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            我住包子山

            this->blog.MoveTo("blog.baozishan.in")

            #

            zju 1004 Anagrams by Stack 我的很不規范的程序

            #include <iostream>
            #include <string>
            using namespace std;

            string stack,requare,start,newStr;
            string table;
            int num=0,i=0;
            void check(string& start,string& stack);
            void print(){
            ? if(newStr==requare)
            ? cout<<table<<endl;
            }
            void pushStack(char item,string& start,string& stack){
            ?table+='i';
            ?stack+=item;
            ?check(start,stack);

            }
            void popStack(string& start,string& stack){
            ?table+='o';
            ?newStr+=stack[stack.size()-1];
            ?stack.erase(stack.size()-1);
            ?check(start,stack);
            }
            void delPush(){
            ? table.erase(table.size()-1);
            ? stack.erase(stack.size()-1);

            }
            void delPop(){
            ? stack+=newStr[newStr.size()-1];
            ? table.erase(table.size()-1);
            ? newStr.erase(newStr.size()-1);
            }

            void check(string& start,string& stack){
            ?if (num==start.size()*2) {
            ??print();?
            ??return;
            ?}
            ?
            ??
            ??? if((newStr.size()+stack.size())!=start.size()){
            ??? num++;
            ??? pushStack(start[i++],start,stack);
            ??? delPush();
            ??? num--;
            ??? i--;
            ??? }
            ??? if(stack.empty()&&i<start.size()) return;
            ??? num++;
            ??? popStack(start,stack);
            ??? delPop();
            ??? num--;
            ?
            ?
            }


            int main(){


            ?cin>>start>>requare;

            ?check(start,stack);
            ?return 0;
            }

            ?

            很不規范的地柜,還有好多個清理狀態的函數。。。
            什么時候才能改進阿!!!!!!!!

            posted @ 2006-09-04 11:39 Gohan 閱讀(749) | 評論 (2)編輯 收藏

            實習快3個禮拜了

            學的東西不少,各方面都有,自己很多東西都還欠缺。
            今天開始給三期工作寫一些數據庫PL/SQL的過程。
            打算大二學的東西:
            (vc#+asp).net? php
            繼續學習vc++
            努力學習c++ datastruct
            要熟悉數據庫相關編程,大二期間爭取能想點東西練手。。。。
            路長長...

            posted @ 2006-08-02 00:07 Gohan 閱讀(291) | 評論 (0)編輯 收藏

            Win32 Console Applications - Part 4 of 6 from adrianxw.dk

            Win32 Console Applications - Part 4.

            So far all of the console output I have shown have been in black and white. This part of the tutorial demonstrates how I did this!

            Now, before you start getting all excited, let me say from the start, the range of colours available is not huge. You may want to compile and run these programs for yourself, the .jpg's I use on the web site show up fine on the monitor connected to the machine I am using now, but when viewed on my older machine, appear very dark and fuzzy.

            We will use the Win32 API function SetConsoleTextAttribute(). This function takes 2 arguments. The first is the standard output handle, we have covered that already. The second is a 16bit WORD bit mask containg 0 or more bits.

            It is not necessary to concern yourself over the values of the various bits. There are a series of constants defined in windows.h, (actually in wincon.h but that is included in windows.h), which symbolically allow you to build the required value, it is very easy. Look at this program and it's output.

            #include <windows.h>
            #include <iostream.h>
            
            int main()
            {
                HANDLE hOut;
            
                hOut = GetStdHandle(STD_OUTPUT_HANDLE);
            
                SetConsoleTextAttribute(hOut,
                                        FOREGROUND_RED);
                cout << "This text is red." << endl;
            
                SetConsoleTextAttribute(hOut,
                                        FOREGROUND_GREEN);
                cout << "This text is green." << endl;
            
                SetConsoleTextAttribute(hOut,
                                        FOREGROUND_BLUE);
                cout << "This text is blue." << endl;
            
                return 0;
            }
            

            A dingy red green and blue. Being bits, they can be OR'd together to make combinations, the next program shows the result of OR'ing the bits together.

            #include <windows.h>
            #include <iostream.h>
            
            int main()
            {
                HANDLE hOut;
            
                hOut = GetStdHandle(STD_OUTPUT_HANDLE);
            
                SetConsoleTextAttribute(hOut,
                                        FOREGROUND_RED | 
                                        FOREGROUND_GREEN);
                cout << "This text is yellow." << endl;
            
                SetConsoleTextAttribute(hOut,
                                        FOREGROUND_GREEN | 
                                        FOREGROUND_BLUE);
                cout << "This text is cyan." << endl;
            
                SetConsoleTextAttribute(hOut,
                                        FOREGROUND_BLUE | 
                                        FOREGROUND_RED);
                cout << "This text is magenta." << endl;
            
                SetConsoleTextAttribute(hOut,
                                        FOREGROUND_RED | 
                                        FOREGROUND_GREEN | 
                                        FOREGROUND_BLUE);
                cout << "This text is white." << endl;
            
                return 0;
            }
            
            

            The bitwise OR operator "|" combines the requested bits. Thus red | green gives yellow, green | blue gives cyan, blue | red gives magenta and all three combined gives white. The order is unimportant, red | blue gives the same result as blue | red.

            Another bit that can be OR'd in is FOREGROUND_INTENSITY. All the colours I've shown so far are a bit dim, adding the intensity bit brightens them up. This program shows the use and results of the intensity bit.

            #include <windows.h>
            #include <iostream>
            using namespace std;
            
            int main()
            {
                HANDLE hOut;
            
                hOut = GetStdHandle(STD_OUTPUT_HANDLE);
            
                SetConsoleTextAttribute(hOut,
                                        FOREGROUND_RED);
                cout << "Red     " << flush;
                SetConsoleTextAttribute(hOut,
                                        FOREGROUND_RED |
                                        FOREGROUND_INTENSITY);
                cout << "Red" << endl;
            
                SetConsoleTextAttribute(hOut,
                                        FOREGROUND_GREEN);
                cout << "Green   " << flush;
                SetConsoleTextAttribute(hOut,
                                        FOREGROUND_GREEN |
                                        FOREGROUND_INTENSITY);
                cout << "Green" << endl;
            
                SetConsoleTextAttribute(hOut,
                                        FOREGROUND_BLUE);
                cout << "Blue    " << flush;
                SetConsoleTextAttribute(hOut,
                                        FOREGROUND_BLUE |
                                        FOREGROUND_INTENSITY);
                cout << "Blue" << endl;
            
                SetConsoleTextAttribute(hOut,
                                        FOREGROUND_RED | 
                                        FOREGROUND_GREEN);
                cout << "Yellow  " << flush;
                SetConsoleTextAttribute(hOut,
                                        FOREGROUND_RED | 
                                        FOREGROUND_GREEN |
                                        FOREGROUND_INTENSITY);
                cout << "Yellow" << endl;
            
                SetConsoleTextAttribute(hOut,
                                        FOREGROUND_GREEN | 
                                        FOREGROUND_BLUE);
                cout << "Cyan    " << flush;
                SetConsoleTextAttribute(hOut,
                                        FOREGROUND_GREEN | 
                                        FOREGROUND_BLUE |
                                        FOREGROUND_INTENSITY);
                cout << "Cyan" << endl;
            
                SetConsoleTextAttribute(hOut,
                                        FOREGROUND_BLUE | 
                                        FOREGROUND_RED);
                cout << "Magenta " << flush;
                SetConsoleTextAttribute(hOut,
                                        FOREGROUND_BLUE | 
                                        FOREGROUND_RED |
                                        FOREGROUND_INTENSITY);
                cout << "Magenta" << endl;
            
                SetConsoleTextAttribute(hOut,
                                        FOREGROUND_RED | 
                                        FOREGROUND_GREEN | 
                                        FOREGROUND_BLUE);
                cout << "White   " << flush;
                SetConsoleTextAttribute(hOut,
                                        FOREGROUND_RED | 
                                        FOREGROUND_GREEN | 
                                        FOREGROUND_BLUE |
                                        FOREGROUND_INTENSITY);
                cout << "White" << endl;
            
                return 0;
            }
            

            Black is also a colour, and is made by having no foreground colors set, no red and no green and no blue is nothing, is black. So in all we have 15 colours. I did warn you not to get excited.

            In addition to changing the foreground colour, we can also change the background colour. The same colours are available.

            #include <windows.h>
            #include <iostream>
            using namespace std;
            
            int main()
            {
                HANDLE hOut;
            
                hOut = GetStdHandle(STD_OUTPUT_HANDLE);
            
                SetConsoleTextAttribute(hOut,
                                        BACKGROUND_RED);
                cout << "Red     " << flush;
                SetConsoleTextAttribute(hOut,
                                        BACKGROUND_RED |
                                        BACKGROUND_INTENSITY);
                cout << "Red     " << endl;
            
                SetConsoleTextAttribute(hOut,
                                        BACKGROUND_GREEN);
                cout << "Green   " << flush;
                SetConsoleTextAttribute(hOut,
                                        BACKGROUND_GREEN |
                                        BACKGROUND_INTENSITY);
                cout << "Green   " << endl;
            
                SetConsoleTextAttribute(hOut,
                                        BACKGROUND_BLUE);
                cout << "Blue    " << flush;
                SetConsoleTextAttribute(hOut,
                                        BACKGROUND_BLUE |
                                        BACKGROUND_INTENSITY);
                cout << "Blue    " << endl;
            
                SetConsoleTextAttribute(hOut,
                                        BACKGROUND_RED | 
                                        BACKGROUND_GREEN);
                cout << "Yellow  " << flush;
                SetConsoleTextAttribute(hOut,
                                        BACKGROUND_RED | 
                                        BACKGROUND_GREEN |
                                        BACKGROUND_INTENSITY);
                cout << "Yellow  " << endl;
            
                SetConsoleTextAttribute(hOut,
                                        BACKGROUND_GREEN | 
                                        BACKGROUND_BLUE);
                cout << "Cyan    " << flush;
                SetConsoleTextAttribute(hOut,
                                        BACKGROUND_GREEN | 
                                        BACKGROUND_BLUE |
                                        BACKGROUND_INTENSITY);
                cout << "Cyan    " << endl;
            
                SetConsoleTextAttribute(hOut,
                                        BACKGROUND_BLUE | 
                                        BACKGROUND_RED);
                cout << "Magenta " << flush;
                SetConsoleTextAttribute(hOut,
                                        BACKGROUND_BLUE | 
                                        BACKGROUND_RED |
                                        BACKGROUND_INTENSITY);
                cout << "Magenta " << endl;
            
                SetConsoleTextAttribute(hOut,
                                        BACKGROUND_RED | 
                                        BACKGROUND_GREEN | 
                                        BACKGROUND_BLUE);
                cout << "White   " << flush;
                SetConsoleTextAttribute(hOut,
                                        BACKGROUND_RED | 
                                        BACKGROUND_GREEN | 
                                        BACKGROUND_BLUE |
                                        BACKGROUND_INTENSITY);
                cout << "White   " << endl;
            
                return 0;
            }
            

            A space character will just show up as the coloured background. That is how I made the Danish flag at the top of this section.

            It is possible to set both the foreground and background colours, here for example, I set the background to low intensity yellow and the foreground to high intensity cyan.

            #include <windows.h>
            #include <iostream>
            using namespace std;
            
            int main()
            {
                HANDLE hOut;
            
                hOut = GetStdHandle(STD_OUTPUT_HANDLE);
            
                SetConsoleTextAttribute(hOut,
                                        BACKGROUND_GREEN |
                                        BACKGROUND_RED |
                                        FOREGROUND_GREEN | 
                                        FOREGROUND_BLUE |
                                        FOREGROUND_INTENSITY);
                cout << "Intense Cyan on yellow background." << endl;
            
                return 0;
            }
            

            You can use any combination you like of the available colours, although obviously, setting the foreground and background colour to the same value is a little pointless. Remember also, that setting no foreground bits gives black text, and no background bits, a black background.

            A common "gotcha" is forgetting that both the foreground AND background must be set at each call. If you want to write first in green then in red on a yellow background you must set the background in both calls, otherwise the function assumes you want to return to a black background.

            #include <windows.h>
            #include <iostream>
            using namespace std;
            
            int main()
            {
                HANDLE hOut;
            
                hOut = GetStdHandle(STD_OUTPUT_HANDLE);
            
                SetConsoleTextAttribute(hOut,
                                        BACKGROUND_GREEN |
                                        BACKGROUND_RED |
                                        FOREGROUND_GREEN | 
                                        FOREGROUND_INTENSITY);
                cout << "Green " << flush;
                SetConsoleTextAttribute(hOut,
                                        BACKGROUND_GREEN |
                                        BACKGROUND_RED |
                                        FOREGROUND_RED |
                                        FOREGROUND_INTENSITY);
                cout << "Red" << endl;
            
                return 0;
            }
            

            If you are going to do a lot of colour changes, rather than OR'ing everything together each time, you may prefer to do it once using a #define. Here, I #define FRI to be Foreground Red Intense, BC to be Background Cyan, FW to Foreground White and BNULL to Background "Nothing" i.e. black. Using these in a small test program does not really make much difference, but in large programs with many colour changes, the code can be much shorter using this technique.

            #include <windows.h>
            #include <iostream>
            using namespace std;
            
            #define FRI FOREGROUND_RED |\
                        FOREGROUND_INTENSITY
            #define FW  FOREGROUND_RED |\
                        FOREGROUND_GREEN |\
                        FOREGROUND_BLUE
            #define BC  BACKGROUND_GREEN |\
                        BACKGROUND_BLUE
            #define BNULL 0
            
            int main()
            {
                HANDLE hOut;
            
                hOut = GetStdHandle(STD_OUTPUT_HANDLE);
            
                cout << "Normal " << flush;
            
                SetConsoleTextAttribute(hOut,
                                        FRI | BC);
            
                cout <<"coloured" << flush;
            
                SetConsoleTextAttribute(hOut,
                                        FW | BNULL);
            
                cout << " and back." << endl;
            
                return 0;
            }
            

            Note the backslashes in the #defines, this is necessary when extending a #define onto more than one line. You don't have to do this of course if you are happy with long lines/horizontal scrolling. Finally, in this section, here is a header file that contains a full set of #defines. To use it, copy the code and paste it into a file with a .h extension, say "ShortColours.h" for example. Put a copy of this file into the same directory as your code file, and include it into your program like this.

            #include "ShortColours.h"
            

            Enclosing the header file name in quotes rather than a less than/greater than pair tells the compiler to look in the same directory as the code.

            #ifndef SHORTCOLOURS_H
            #define SHORTCOLOURS_H
            
            #define FW FOREGROUND_RED | \
                       FOREGROUND_GREEN | \
                       FOREGROUND_BLUE
            #define FR FOREGROUND_RED
            #define FG FOREGROUND_GREEN
            #define FB FOREGROUND_BLUE
            #define FY FOREGROUND_RED | \
                       FOREGROUND_GREEN
            #define FC FOREGROUND_GREEN | \
                       FOREGROUND_BLUE
            #define FM FOREGROUND_BLUE | \
                       FOREGROUND_RED 
            #define FWI FOREGROUND_RED | \
                        FOREGROUND_GREEN | \
                        FOREGROUND_BLUE | \
                        FOREGROUND_INTENSITY
            #define FRI FOREGROUND_RED | \
                        FOREGROUND_INTENSITY
            #define FGI FOREGROUND_GREEN | \
                        FOREGROUND_INTENSITY
            #define FBI FOREGROUND_BLUE | \
                        FOREGROUND_INTENSITY
            #define FYI FOREGROUND_RED | \
                        FOREGROUND_GREEN | \
                        FOREGROUND_INTENSITY
            #define FCI FOREGROUND_GREEN | \
                        FOREGROUND_BLUE | \
                        FOREGROUND_INTENSITY
            #define FMI FOREGROUND_BLUE | \
                        FOREGROUND_RED | \
                        FOREGROUND_INTENSITY 
            #define FNULL 0
             
            #define BW BACKGROUND_RED | \
                       BACKGROUND_GREEN | \
                       BACKGROUND_BLUE
            #define BR BACKGROUND_RED
            #define BG BACKGROUND_GREEN
            #define BB BACKGROUND_BLUE
            #define BY BACKGROUND_RED | \
                       BACKGROUND_GREEN
            #define BC BACKGROUND_GREEN | \
                       BACKGROUND_BLUE
            #define BM BACKGROUND_BLUE | \
                       BACKGROUND_RED 
            #define BWI BACKGROUND_RED | \
                        BACKGROUND_GREEN | \
                        BACKGROUND_BLUE | \
                        BACKGROUND_INTENSITY
            #define BRI BACKGROUND_RED | \
                        BACKGROUND_INTENSITY
            #define BGI BACKGROUND_GREEN | \
                        BACKGROUND_INTENSITY
            #define BBI BACKGROUND_BLUE | \
                        BACKGROUND_INTENSITY
            #define BYI BACKGROUND_RED | \
                        BACKGROUND_GREEN | \
                        BACKGROUND_INTENSITY
            #define BCI BACKGROUND_GREEN | \
                        BACKGROUND_BLUE | \
                        BACKGROUND_INTENSITY
            #define BMI BACKGROUND_BLUE | \
                        BACKGROUND_RED | \
                        BACKGROUND_INTENSITY 
            #define BNULL 0
            
            #endif
            

            This program produces the same output as the last.

            #include <windows.h>
            #include <iostream>
            #include "ShortColours.h"
            using namespace std;
            
            int main()
            {
                HANDLE hOut;
            
                hOut = GetStdHandle(STD_OUTPUT_HANDLE);
            
                cout << "Normal " << flush;
            
                SetConsoleTextAttribute(hOut,
                                        FRI | BC);
            
                cout <<"coloured" << flush;
            
                SetConsoleTextAttribute(hOut,
                                        FW | BNULL);
            
                cout << " and back." << endl;
            
                return 0;
            }
            

            The colour support is not great, but at the end of the day, it can be good enough. Consider, there are probably many of you that have played, or at least seen "BattleChess", where the pieces animated battle when one captured another. I bet nobody played it for long, because after you've seen the animations, they simply slow the game down, and the AI behind the graphics was actually not very good.

            You build a really good chess playing AI and put it behind a simple interface like this, people will use it over and over, because, it is good enough to get the job done.



            ----------

            In part 2 of the tutorial, I showed you how to use ReadConsoleOutputCharacter() to retrieve the characters at one or more screen buffer locations. By itself, it is not capable of recovering the foreground and background attributes those characters were written with. This information is also available, the API routine used is ReadConsoleOutputAttribute(), and is really very similar to ReadConsoleOutputCharacter(). The prototype is shown here.

            BOOL ReadConsoleOutputAttribute(
              HANDLE hConsoleOutput,
              LPWORD lpAttribute,
              DWORD nLength,
              COORD dwReadCoord,
              LPDWORD lpNumberOfAttrsRead
            );
            

            This program sets the foreground colout to FOREGROUND_GREEN | FOREGROUND_RED and outputs a string. It then uses ReadConsoleOutputAttribute() to retrieve the attribute of the character at (4,0). The result is 6, this is because FOREGROUND_GREEN is defined to have the value 0x0002 and FOREGROUND_RED 0x0004. 2+4=6. It may be tempting to use the numerical values rather than the defined constants, but this is not a good idea. At some time in the future, MicroSoft may change the values associated with the constants, (unlikely, but a reserved possibility). Using the constants, the code will still work, use the values and the results may be unpredictable.

            #include <windows.h>
            #include <iostream.h>
            
            int main()
            {
                HANDLE hOut;
                WORD Attribute;
                COORD Where;
                unsigned long NumRead;
            
                hOut = GetStdHandle(STD_OUTPUT_HANDLE);
            
                SetConsoleTextAttribute(hOut,
                                        FOREGROUND_GREEN | 
                                        FOREGROUND_RED);
            
                cout << "This text is yellow." << endl;
            
                Where.X = 4;
                Where.Y = 0;
                ReadConsoleOutputAttribute(hOut,
                                           &Attribute,
                                           1,
                                           Where,
                                           &NumRead);
            
                cout << "Attribute is " << Attribute << endl;
            
                return 0;
            }
            

            The output looks like this.

            ReadConsoleOutputAttribute

            In the next part of the tutorial, we'll investigate keyboard and mouse events.

            posted @ 2006-07-20 22:54 Gohan 閱讀(1448) | 評論 (0)編輯 收藏

            Win32 Console Applications - Part 3 of 6 form adrianxw.dk

            Win32 Console Applications - Part 3.

            I recommend you compile and run this program. It will display the printable characters available to your console. If your console is a different size from mine, you may need to adjust the values for x and y, but this should be trivial. The rest of the tutorial assumes your character map is the same as mine - it should be, but it is possible if you have a different language set loaded into your system the positions of some of these characters may be different, run this, check them and modify the values used later accordingly, (frankly, I've worked with several language settings and never seen the character map to be different, but I'm told it is possible!).

            #include <windows.h>
            #include <iostream>
            using namespace std;
            
            int main()
            {
                HANDLE hOut;
                int i;
                int x = 0;
                int y = 0;
                COORD Position;
            
                hOut = GetStdHandle(STD_OUTPUT_HANDLE);
            
                for (i=32; i<=255; i++)
                {
                    Position.X = x;
                    Position.Y = y;
                    SetConsoleCursorPosition(hOut,
                                             Position);
            
                    cout.width(3);
                    cout << i << " " << (unsigned char)i << flush;
            
                    ++y;
                    if(y > 20)
                    {
                        y = 0;
                        x += 6;
                    }
                }
            
                Position.X = 0;
                Position.Y = 22;
                SetConsoleCursorPosition(hOut,
                                         Position);
                return 0;
            }
            

            Of particular interest to this part of the tutorial are the values between 179 and 218. Shown below is the relevent part of the output from the program.

            Char Map

            If you remember part 1 of this tutorial, I said the "normal" characters in the console font filled a 7x11 grid in a larger 8x12 character cell which had the top and row and right column blank to allow for spacing. As you can see from the picture above, these are not normal characters, some have already merged with those above and below them to give some strange glyphs that look like a cross between sanskrit and klingon! Here is the same character range more spread out and easier to see.

            Char Map2

            Unlike the normal alpha-numerics, (0-9, A-Z, a-z), and puntuation characters, where space between the individual characters is important for clarity, these characters do not have space above and to the right, they run all the way to the edge of their character cell and are designed to be merged. With these characters one can draw lines, boxes and grids. Have a look at this program output for some idea of what you can do.

            Boxes

            The figures look a little stupid when drawn this size, but I have done this to keep the size of the image files down, so they load faster, you can make them any size, and if you inspect the character map, you will see that these are not the only possibilities.

            To draw these examples, I wrote a very crude function which draws a character at a specified location on the screen, it is shown here.

            void At(int x, int y, unsigned char What)
            {
                static HANDLE hOut;
                static bool First = TRUE;
                COORD Position;
            
                if(First)
                {
                    hOut = GetStdHandle(STD_OUTPUT_HANDLE);
                    First = FALSE;
                }
            
                Position.X = x;
                Position.Y = y;
                
                SetConsoleCursorPosition(hOut,
                                         Position);
                
                cout << What << flush;
            
                return;
            }
            

            As you can see, there is no error or range checking, it simply assumes you know what you are doing. The function retrieves the standard output handle and stores it statically the first time the it is invoked.

            This code snippet shows the calls necessary to draw the first box.

                At(9, 0, (unsigned char) 218);
                At(10, 0, (unsigned char) 196);
                At(11, 0, (unsigned char) 191);
                At(9, 1, (unsigned char) 179);
                At(10, 1, (unsigned char) 32);
                At(11, 1, (unsigned char) 179);
                At(9, 2, (unsigned char) 192);
                At(10, 2, (unsigned char) 196);
                At(11, 2, (unsigned char) 217);
            

            Given the character table above and this simple example, (32 is the space character by the way), you should have enough information to create all kinds of boxes, grids, mazes, forms etc. The very playable adventure game "Caverns of Moria" known to many VAX/VMS and UNIX users had a user interface that could easily be copied using these simple graphics.

            ----------

            Whilst drawing boxes or at any time it becomes appropriate, you may want to hide or modify the appearance of the cursor. You can do this with another API routine, SetConsoleCursorInfo(). This takes 2 parameters, the standard output handle, and a pointer to a CONSOLE_CURSOR_INFO structure. This is another relatively simple Windows defined structure. It is looks like this.

            typedef struct _CONSOLE_CURSOR_INFO {
                DWORD  dwSize; 
                BOOL   bVisible; 
            } CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO; 
            

            The first value is a simple integer in the range 1-100, it specifies how much of the character cell the cursor occupies is filled. The program here sets the cursor size to 50. The 3 pictures below show the sizes 1, 50 and 100, you can, of course, use any integer in the range. Note the use of the "&" in front of the ConCurInf, remember, the routine expects a pointer to the structure you have declared.

            #include <windows.h>
            
            int main()
            {
                HANDLE hOut;
                CONSOLE_CURSOR_INFO ConCurInf;
            
                hOut = GetStdHandle(STD_OUTPUT_HANDLE);
            
                SetConsoleTitle("Size 50");
            
                ConCurInf.dwSize = 50;
                ConCurInf.bVisible = TRUE;
            
                SetConsoleCursorInfo(hOut,
                                     &ConCurInf);
            
                return 0;
            }
            
            Cursor1

            Cursor50

            Cursor100

            The other value is a boolean field and indicates whether the cursor is visible or not. A value of TRUE, (the default), means the cursor is visible, FALSE and it is invisible. The followng program turns the cursor off.

            #include <windows.h>
            
            int main()
            {
                HANDLE hOut;
                CONSOLE_CURSOR_INFO ConCurInf;
            
                hOut = GetStdHandle(STD_OUTPUT_HANDLE);
            
                SetConsoleTitle("No Cursor");
            
                ConCurInf.dwSize = 10;
                ConCurInf.bVisible = FALSE;
            
                SetConsoleCursorInfo(hOut,
                                     &ConCurInf);
            
                return 0;
            }
            
            CursorOff

            To turn the cursor back on, call the function again with the bVisible member set TRUE.

            It is a good idea to set up both values, especially the first time you call the function. If you set up bVisible but leave dwSize uninitialised, the unspecified value may be zeroed, or contain a random value, in either case, it could be out of the range 1-100, and the routine will fail. Similaly, if you want to change the size of the cursor, and don't set bVisible to be TRUE, your compiler may have zeroed the uninitialised field and the cursor will disappear instead of changing size. As always, if you check the return value of the call, you will see if any errors have happened along the way.

            Remember, the cursor is there to show where the character insertion point is. Setting the cursor to invisible does not change that. Remember also, the cursor is very useful, it shows your user "where they are" on your screen, if you take it away, you must be sure you have other means available that enable your user to navigate the screen.

            In the next part of this tutorial, we'll explore the colour issues.

            posted @ 2006-07-20 22:49 Gohan 閱讀(393) | 評論 (0)編輯 收藏

            [基礎]Win32 Console Applications - Part 2 of 6 from adrianxw.dk

            Win32 Console Applications - Part 2.

            I started part 1 of this tutorial by showing the classic "Hello Worlrd!" program. The output looked like this.

            Hello World

            By default, Windows places the path of the executable in the window title. You can change this to a word or phrase of your choice. Here is the Hello World! program modified to do this.

            #include <windows.h>
            #include <iostream>
            using namespace std;
            
            int main()
            {
                SetConsoleTitle("Hello!");
                cout << "Hello World!" << endl;
                return 0;
            }
            

            Notice I've now added the windows.h header to the program, and a call to SetConsoleTitle(). The output now looks like this.

            Hello World

            Later on, we'll see that knowing the name of your window can be useful, and setting it yourself is, of course, an easy way of knowing it!

            As an aside, almost all of the API routines return a status indicating success or failure. For clarity of the example code in these tutorials, I am not checking this value. To be more professional, you should check the return values of API routines you call. Even if you cannot recover from the error, it is often useful in debugging to know what routine failed, and if possible, why. This program shows the checking of the return status and aborts the program if the routine fails, (note the inclusion of process.h for the exit() API routine). You should refer to your compiler's help or MSDN to see what the return values of a routine are.

            #include <windows.h>
            #include <process.h>
            #include <iostream>
            using namespace std;
            
            int main()
            {
                int Status;
            
                Status = SetConsoleTitle("Hello!");
                if (Status == 0)
                {
                    Status = GetLastError();
                    cout << "SetConsoleTitle() failed! Reason : " << Status << endl;
                    exit(Status);
                }
            
                cout << "Hello World!" << endl;
                return 0;
            }
            
            ----------

            All consoles have 3 "standard handles" and many of the console handling functions require a "handle" to perform I/O.

            A "handle" is simply a 32 bit integer. It is the way Windows differentiates between objects of the same type. Consider the console, it has a title bar, minimize, maximize and close buttons, one or more scroll bars, etc. It is, when you think about it, quite a complicated thing, and somewhere there must be a lot of data that the system is using to make it all work. Windows hides all of that complexity from you, you can play with all this data if you want to of course, but the point here is, you don't have to if you don't want to. Windows looks after it all for you, and all you have to do is tell it the handle of whatever it is you want to use. Once you get into full Windows programming, you'll find a lot of things are used by supplying a "handle". If you don't understand right now, don't worry about it, a handle is easy to get, and easy to use.

            To get the standard handles, declare variable of type HANDLE and initialise them with a call to GetStdHandle(). This program, (which doesn't actually do anything!), illustrates the process. We'll use the standard handles later.

            #include <windows.h>
            
            int main()
            {
                HANDLE hIn;
                HANDLE hOut;
                HANDLE hError;
            
                hIn = GetStdHandle(STD_INPUT_HANDLE);
                hOut = GetStdHandle(STD_OUTPUT_HANDLE);
                hError = GetStdHandle(STD_ERROR_HANDLE);
            
                return 0;
            }
            

            The standard input handle is used with routines that read data from a console, the standard output handle with routines that send data to a console. The standard error handle also outputs to the console by default, and frankly is not used very much, just be aware of it.

            There are a couple of routines ReadConsole() and WriteConsole() that perform I/O using these handles, but for now at least, we'll continue with the standard C++ I/O functions.

            ----------

            Now we've got the handles, lets do something with them, let's move the cursor around. To do this we'll need to use a COORD structure. This is a very simple structure containing an x and y coordinate. It is declared like this.

            typedef struct _COORD {
                SHORT X;
                SHORT Y;
            } COORD; 
            

            To move the cursor, you simply set up the COORD to the coordinates you want the cursor moved to and call the SetConsoleCursorPosition() API function. Here is a simple program which does just that.

            #include <windows.h>
            #include <iostream>
            using namespace std;
            
            int main()
            {
                HANDLE hOut;
                int i;
                COORD Position;
            
                hOut = GetStdHandle(STD_OUTPUT_HANDLE);
            
                for(i=0; i<10; i+=2)
                {
                    Position.X = i;
                    Position.Y = i;
                    SetConsoleCursorPosition(hOut,
                                             Position);
                    cout << "*" << flush;
                }
            
                return 0;
            }
            

            The output looks like this.

            Move Cursor

            As you see, each iteration of the loop moves the cursor two rows down and two columns right. To return the cursor to the "home" position, (top left corner), send it to (0,0). Creative use of this function can give pleasing effects.

            ----------

            The next routine I want to show you is FillConsoleOutputCharacter(). This routine allows you to write a whole load of characters to the console in one go. The function prototype is shown here.

            BOOL FillConsoleOutputCharacter(
              HANDLE hConsoleOutput,
              TCHAR cCharacter,
              DWORD nLength,
              COORD dwWriteCoord,
              LPDWORD lpNumberOfCharsWritten
            );
            

            A bit more complicated then any of the routines we've used so far, but really very easy to use. The first parameter is the handle to the output buffer, you know how to get that. The next is the character you want to write, easy enough. The next, is how many times you want it to write the character out, still easy. Next is a COORD telling it where to start, we've already covered that. Finally, the routine wants a place where it can tell you how many characters it actually wrote, this has to be therefore, the address of a variable in your program. You may be wondering why this argument is there at all, but consider the situation where your screen buffer is, for example, 5000 characters long. If you tell the routine to output 5100, it will not error, it will fill the 5000 characters, and then tell you that it did that by setting the value accordingly. If you're not interested, ignore it, but you must supply a place for the routine to use, in this case, I've passed the address of the "Written" variable like this &Written.

            This program uses FillConsoleOutputCharacter() to draw a line of 15 "X" characters starting at (4,4), the unsuprising output of the program is also shown below.

            #include <windows.h>
            #include <iostream>
            using namespace std;
            
            int main()
            {
                HANDLE hOut;
                COORD Position;
                DWORD Written;
            
                hOut = GetStdHandle(STD_OUTPUT_HANDLE);
            
                Position.X = 4;
                Position.Y = 4;
            
                FillConsoleOutputCharacter(hOut,
                                           'X',
                                           15,
                                           Position,
                                           &Written);
            
                return 0;
            }
            
            Fill Console

            See what happens if I change the call to output 150 instead of 15 characters, (I've shrunk the picture to make it load faster - changing the call did not change the screen resolution!!!).

            Fill Console

            The point to note is that when the routine reached the end of the line, it continued at the beginning of the line below. Suppose, instead of line 5 column 5 I'd said (0,0), and suppose I'd used a space character instead of an 'X', and suppose I'd told it to draw enough characters to completely fill the screen buffer - hey - I've cleared the screen! Clearing the screen is THE most common console related question that comes up in the forums, there's the answer.

            ----------

            It is also possible to read one or more characters from a specific position in the screen buffer. To do that, we use the ReadConsoleOutputCharacter() API routine. This routine has very similar parameters to the last, it's prototype is shown here.

            BOOL ReadConsoleOutputCharacter(
              HANDLE hConsoleOutput,
              LPTSTR lpCharacter,
              DWORD nLength,
              COORD dwReadCoord,
              LPDWORD lpNumberOfCharsRead 
            );
            

            As before, the first is the standard handle. Next, remember, we are reading now, so the routine wants somewhere to write the information to, so it needs a pointer to a place where it can store characters. The rest of the parameters are as before, the number of characters to process, the start point, and a pointer to a place it can write the actual number read.

            This program uses the routine twice, once to retrieve the single character at the (0,0) position, and a second time to retrieve 5 characters starting from position (4,0). If the number of characters requested is longer than the current line, reading continues from the first character of the line below as before. Again, as before, if the number requested is more than there are in the buffer, the characters up to the end of the buffer are returned, the actual number appearing in the final parameter.

            #include <windows.h>
            #include <iostream>
            using namespace std;
            
            int main()
            {
                HANDLE hOut;
                char Letter;
                char Letters[5];
                COORD Where;
                DWORD NumRead;
                int i;
            
                hOut = GetStdHandle(STD_OUTPUT_HANDLE);
            
                cout << "A line of little consequence." << endl;
            
                Where.X = 0;
                Where.Y = 0;
                ReadConsoleOutputCharacter(hOut,
                                           &Letter,
                                           1,
                                           Where,
                                           &NumRead);
                cout << "Letter at (0,0) is " << Letter << endl;
            
                Where.X = 4;
                ReadConsoleOutputCharacter(hOut,
                                           Letters,
                                           5,
                                           Where,
                                           &NumRead);
                cout << "5 letters starting from (4,0) ";
                for (i=0; i<5; i++)
                {
                    cout << Letters[i];
                }
                cout << endl;
            
                return 0;
            }
            

            The output from the program looks like this.

            ReadConsoleOutputCharacter

            It would have been quite permissable to dimension the Letters array to 6, read the 5 characters from the console then manually set the final character to NULL. In that way, the cout could have taken the name of the string, (as it is now NULL terminated), instead of writing the characters out individually in a loop.

            In the next part of the tutorial, we'll look at the limited graphical capabilities of consoles, drawing lines, boxes and grids.

            Win32 Console Applications - Part 2.

            I started part 1 of this tutorial by showing the classic "Hello Worlrd!" program. The output looked like this.

            Hello World

            By default, Windows places the path of the executable in the window title. You can change this to a word or phrase of your choice. Here is the Hello World! program modified to do this.

            #include <windows.h>
            #include <iostream>
            using namespace std;
            
            int main()
            {
                SetConsoleTitle("Hello!");
                cout << "Hello World!" << endl;
                return 0;
            }
            

            Notice I've now added the windows.h header to the program, and a call to SetConsoleTitle(). The output now looks like this.

            Hello World

            Later on, we'll see that knowing the name of your window can be useful, and setting it yourself is, of course, an easy way of knowing it!

            As an aside, almost all of the API routines return a status indicating success or failure. For clarity of the example code in these tutorials, I am not checking this value. To be more professional, you should check the return values of API routines you call. Even if you cannot recover from the error, it is often useful in debugging to know what routine failed, and if possible, why. This program shows the checking of the return status and aborts the program if the routine fails, (note the inclusion of process.h for the exit() API routine). You should refer to your compiler's help or MSDN to see what the return values of a routine are.

            #include <windows.h>
            #include <process.h>
            #include <iostream>
            using namespace std;
            
            int main()
            {
                int Status;
            
                Status = SetConsoleTitle("Hello!");
                if (Status == 0)
                {
                    Status = GetLastError();
                    cout << "SetConsoleTitle() failed! Reason : " << Status << endl;
                    exit(Status);
                }
            
                cout << "Hello World!" << endl;
                return 0;
            }
            
            ----------

            All consoles have 3 "standard handles" and many of the console handling functions require a "handle" to perform I/O.

            A "handle" is simply a 32 bit integer. It is the way Windows differentiates between objects of the same type. Consider the console, it has a title bar, minimize, maximize and close buttons, one or more scroll bars, etc. It is, when you think about it, quite a complicated thing, and somewhere there must be a lot of data that the system is using to make it all work. Windows hides all of that complexity from you, you can play with all this data if you want to of course, but the point here is, you don't have to if you don't want to. Windows looks after it all for you, and all you have to do is tell it the handle of whatever it is you want to use. Once you get into full Windows programming, you'll find a lot of things are used by supplying a "handle". If you don't understand right now, don't worry about it, a handle is easy to get, and easy to use.

            To get the standard handles, declare variable of type HANDLE and initialise them with a call to GetStdHandle(). This program, (which doesn't actually do anything!), illustrates the process. We'll use the standard handles later.

            #include <windows.h>
            
            int main()
            {
                HANDLE hIn;
                HANDLE hOut;
                HANDLE hError;
            
                hIn = GetStdHandle(STD_INPUT_HANDLE);
                hOut = GetStdHandle(STD_OUTPUT_HANDLE);
                hError = GetStdHandle(STD_ERROR_HANDLE);
            
                return 0;
            }
            

            The standard input handle is used with routines that read data from a console, the standard output handle with routines that send data to a console. The standard error handle also outputs to the console by default, and frankly is not used very much, just be aware of it.

            There are a couple of routines ReadConsole() and WriteConsole() that perform I/O using these handles, but for now at least, we'll continue with the standard C++ I/O functions.

            ----------

            Now we've got the handles, lets do something with them, let's move the cursor around. To do this we'll need to use a COORD structure. This is a very simple structure containing an x and y coordinate. It is declared like this.

            typedef struct _COORD {
                SHORT X;
                SHORT Y;
            } COORD; 
            

            To move the cursor, you simply set up the COORD to the coordinates you want the cursor moved to and call the SetConsoleCursorPosition() API function. Here is a simple program which does just that.

            #include <windows.h>
            #include <iostream>
            using namespace std;
            
            int main()
            {
                HANDLE hOut;
                int i;
                COORD Position;
            
                hOut = GetStdHandle(STD_OUTPUT_HANDLE);
            
                for(i=0; i<10; i+=2)
                {
                    Position.X = i;
                    Position.Y = i;
                    SetConsoleCursorPosition(hOut,
                                             Position);
                    cout << "*" << flush;
                }
            
                return 0;
            }
            

            The output looks like this.

            Move Cursor

            As you see, each iteration of the loop moves the cursor two rows down and two columns right. To return the cursor to the "home" position, (top left corner), send it to (0,0). Creative use of this function can give pleasing effects.

            ----------

            The next routine I want to show you is FillConsoleOutputCharacter(). This routine allows you to write a whole load of characters to the console in one go. The function prototype is shown here.

            BOOL FillConsoleOutputCharacter(
              HANDLE hConsoleOutput,
              TCHAR cCharacter,
              DWORD nLength,
              COORD dwWriteCoord,
              LPDWORD lpNumberOfCharsWritten
            );
            

            A bit more complicated then any of the routines we've used so far, but really very easy to use. The first parameter is the handle to the output buffer, you know how to get that. The next is the character you want to write, easy enough. The next, is how many times you want it to write the character out, still easy. Next is a COORD telling it where to start, we've already covered that. Finally, the routine wants a place where it can tell you how many characters it actually wrote, this has to be therefore, the address of a variable in your program. You may be wondering why this argument is there at all, but consider the situation where your screen buffer is, for example, 5000 characters long. If you tell the routine to output 5100, it will not error, it will fill the 5000 characters, and then tell you that it did that by setting the value accordingly. If you're not interested, ignore it, but you must supply a place for the routine to use, in this case, I've passed the address of the "Written" variable like this &Written.

            This program uses FillConsoleOutputCharacter() to draw a line of 15 "X" characters starting at (4,4), the unsuprising output of the program is also shown below.

            #include <windows.h>
            #include <iostream>
            using namespace std;
            
            int main()
            {
                HANDLE hOut;
                COORD Position;
                DWORD Written;
            
                hOut = GetStdHandle(STD_OUTPUT_HANDLE);
            
                Position.X = 4;
                Position.Y = 4;
            
                FillConsoleOutputCharacter(hOut,
                                           'X',
                                           15,
                                           Position,
                                           &Written);
            
                return 0;
            }
            
            Fill Console

            See what happens if I change the call to output 150 instead of 15 characters, (I've shrunk the picture to make it load faster - changing the call did not change the screen resolution!!!).

            Fill Console

            The point to note is that when the routine reached the end of the line, it continued at the beginning of the line below. Suppose, instead of line 5 column 5 I'd said (0,0), and suppose I'd used a space character instead of an 'X', and suppose I'd told it to draw enough characters to completely fill the screen buffer - hey - I've cleared the screen! Clearing the screen is THE most common console related question that comes up in the forums, there's the answer.

            ----------

            It is also possible to read one or more characters from a specific position in the screen buffer. To do that, we use the ReadConsoleOutputCharacter() API routine. This routine has very similar parameters to the last, it's prototype is shown here.

            BOOL ReadConsoleOutputCharacter(
              HANDLE hConsoleOutput,
              LPTSTR lpCharacter,
              DWORD nLength,
              COORD dwReadCoord,
              LPDWORD lpNumberOfCharsRead 
            );
            

            As before, the first is the standard handle. Next, remember, we are reading now, so the routine wants somewhere to write the information to, so it needs a pointer to a place where it can store characters. The rest of the parameters are as before, the number of characters to process, the start point, and a pointer to a place it can write the actual number read.

            This program uses the routine twice, once to retrieve the single character at the (0,0) position, and a second time to retrieve 5 characters starting from position (4,0). If the number of characters requested is longer than the current line, reading continues from the first character of the line below as before. Again, as before, if the number requested is more than there are in the buffer, the characters up to the end of the buffer are returned, the actual number appearing in the final parameter.

            #include <windows.h>
            #include <iostream>
            using namespace std;
            
            int main()
            {
                HANDLE hOut;
                char Letter;
                char Letters[5];
                COORD Where;
                DWORD NumRead;
                int i;
            
                hOut = GetStdHandle(STD_OUTPUT_HANDLE);
            
                cout << "A line of little consequence." << endl;
            
                Where.X = 0;
                Where.Y = 0;
                ReadConsoleOutputCharacter(hOut,
                                           &Letter,
                                           1,
                                           Where,
                                           &NumRead);
                cout << "Letter at (0,0) is " << Letter << endl;
            
                Where.X = 4;
                ReadConsoleOutputCharacter(hOut,
                                           Letters,
                                           5,
                                           Where,
                                           &NumRead);
                cout << "5 letters starting from (4,0) ";
                for (i=0; i<5; i++)
                {
                    cout << Letters[i];
                }
                cout << endl;
            
                return 0;
            }
            

            The output from the program looks like this.

            ReadConsoleOutputCharacter

            It would have been quite permissable to dimension the Letters array to 6, read the 5 characters from the console then manually set the final character to NULL. In that way, the cout could have taken the name of the string, (as it is now NULL terminated), instead of writing the characters out individually in a loop.

            In the next part of the tutorial, we'll look at the limited graphical capabilities of consoles, drawing lines, boxes and grids.

            posted @ 2006-07-20 22:46 Gohan 閱讀(694) | 評論 (0)編輯 收藏

            [基礎]Win32 Console Applications - Part 1. of 6

            Win32 Console Applications - Part 1.

            Hello World

            Okay, hands up, who here started out with something like this, possibly in another language, possibly on another OS, but whatever, with something like that. I'm willing to bet there are a good few people who can say "yes, that was me". You don't really want to see the source do you? Oh all right then.

            #include <iostream>
            using namespace std;
            
            int main()
            {
                cout << "Hello World!" << endl;
                return 0;
            }
            

            8 lines. Could be less, by why make things harder to read? This is really the great strength of a Windows Console Application, you really do not need to do much in order to make a working program. That is why I use consoles. If I want to test out a bit of non GUI code, and I don't have a suitable application I can use as a framework, I knock together a quick console application, and I'm sure just about every other Windows programmer does as well. The user interface only needs to be sophisticated enough to get the job done.

            Some of the other tutorials on the site demostrate powerful techniques, but do it in a Console App because that's all that was needed.

            Can you do anything else with a Console App? Of course, the answer is yes, you can, and these tutorials demostrate some of the things that can be done with a console. Believe it or not, a huge number of questions concerning consoles crop up in help forums every week, so people are interested. If you are, read on.

            ----------

            What is a Console? It is a Window, a special kind, yes, but it is a Window. You will frequently hear these things called "DOS boxes" because DOS had a character based UI, but this term is incorrect. There is no DOS under the NT cored WIndows operating systems, (NT, 2000, XP), and yet you can use a console. Why? Because it is a Window. (There are actually DOS emulators for these platforms - but this is a totally unrelated topic.)

            What makes a Console window special is that it is character based rather than pixel based. A normal window, like this browser window for example, (unless you're using a REALLY basic browser), is measured in pixels, each pixel is individually addressable and modifiable. With a character based medium, that is not the case, the smallest unit that can be addressed and thus modified is a character cell.

            A console's display area consist of rows and columns of character cells. It is a grid or two dimensional array or matrix of cells, all these terms are in use - they amount ot the same thing. Traditionally, the character cell at the top left is the origin or "home" position, and is designated (0,0) in an imaginary (x,y) grid. The character cell to it's immediate right is (1,0), the next (2,0) and so on. The cell just below (0,0) is (0,1), the one below that (0,2) and so on. On a typical console there are 80 cell positions across the screen, and 25 down, thus on such a console, the bottom right cell will be (79,24) remembering the grid is zero based. The little picture below shows graphically the cell numbers of the upper left portion of a larger screen or the entire grid of a 4x4 console of course.

            CellGrid

            Incidently, the reason for chosing 80x25 is historical. In the days before graphical terminals were widely available, people used character based terminals called "Visual Display Units", or VDU's. These typically had an 80x25 screen layout. I was one of those who used these beasts.

            ----------

            Each character cell can contain one and only one character. I'll illustrate an artifact of this below. I type 5 "w" characters, then on the line below, 5 "i" characters...

            wwwww
            iiiii

            ... notice the length of the lines. Assuming you are using a modern browser, you should see that the upper line is longer than the lower. Now I'll write a console app which does the same, here is the output...

            FixedFont

            ... as you see, since each cell can only hold a single character, the last "i" character is directly below the last "w". There can be no proportional spacing in a console with the default font, (it is possible to simulate a very crude form of proportional spacing if only a few letters are used - but forget it - it's not worth the hassle).

            Okay, so we've got a grid of cells, what is in a cell? Simply, a cell is another grid, each cell being 8 pixels wide and 12 high. The characters that make up the font must be represented within this grid including any spacing - that's right, the pixels of one cell lie directly adjacent to the pixels of the next. This is somewhat limiting, and accounts for the rather poor quality of the console font, but as we will see later, it does have some advantages. The pictures below show how the "w" and "i" characters are encoded into a cell.

            w Grid i Grid

            Notice the blank column on the right of the "w", this ensures that two adjacent "w" characters will have at least a single pixel space between them. If you look at the last picture, you will see that is the case. Also notice, the dot over the "i" does not go to the top of the cell, this ensures that any character on the line above an "i" that has a descender, an extension below the normal line, "y" for example, will still have at least a one pixel gap between the descender and a "high" character. Thus, normal characters are represented by 7x11 grids with a blank row at the top and a blank column on the right side.

            The pixels marked with a "X" in the pictures above are rendered in the foreground colour, those in the empty pixels positions, in the background colour. By default, the foreground is white, the background black. Later on in the tutorial, I will show you how to change these colours, within limits.

            ----------

            There is a one pixel wide gap around the outside edge of the consoles display area. This prevents the top, bottom and edge characters merging with the frame. You cannot write into this gap. Thus a console's display area is 2+(8x) pixels wide, where x is the number of character cells in a row, and 2+(12y) pixels high where y is the number of visible rows, (there may be more rows above or below the current view as determined by the position of the scroll bar).

            I'm afraid this first page has really been rather a lot of dry theory. A lot of what you can do with consoles assumes you understand this material though, so read it through, and if later on in this tutorial, you find something that sounds weird, try reading this page again!

            In the next part, I'll show you how to name your Console, obtain the consoles standard handles, move the cursor about, write blocks of characters and clear the screen.

            posted @ 2006-07-20 22:39 Gohan 閱讀(460) | 評論 (1)編輯 收藏

            3天實習小結

            3天時間學的東西不多,范圍卻比較廣。
            cb會進行各種數據庫聯接了,從本地Access數據庫,到測試用的Oracle服務器。
            對團隊工作流程有所認識。
            閱讀了本公司前不久完成的價值頗高的源程序的冰山一角,剩下的有空慢慢看吧。
            對于版本控制所用CVS軟件有點體會。

            目前最欠缺的,因為我們主要是做超大數據庫相關編程,我對數據庫的內容所知很少,
            SQL-Command亟待學習一下。
            另外自己在看侯捷的Dissecting MFC,剛開始看。。。從深處認識體會微軟這個龐大的Framework
            。。。。。。

            下周繼續實習吧。

            posted @ 2006-07-15 22:38 Gohan 閱讀(295) | 評論 (0)編輯 收藏

            John Carmack密碼:0x5f3759df

            有人在Quake III的源代碼里面發現這么一段用來求平方根的代碼:

            /*
            ================
            SquareRootFloat
            ================
            */
            float SquareRootFloat(float number) {
            long i;
            float x, y;
            const float f = 1.5F;

            x = number * 0.5F;
            y = number;
            i = * ( long * ) &y;
            i = 0x5f3759df - ( i >> 1 ); //注意這一行
            y = * ( float * ) &i;
            y = y * ( f - ( x * y * y ) );
            y = y * ( f - ( x * y * y ) );
            return number * y;
            }
            0x5f3759df? 這是個什么東西? 學過數值分析就知道,算法里面求平方根一般采用的是無限逼近的方法,比如牛頓迭代法,抱歉當年我數值分析學的太爛,也講不清楚。簡單來說比如求5的平方根,選一個猜測值比如2,那么我們可以這么算
            5/2 = 2.5; 2.5+2/2 = 2.25; 5/2.25 = xxx; 2.25+xxx/2 = xxxx ...

            這樣反復迭代下去,結果必定收斂于sqrt(5),沒錯,一般的求平方根都是這么算的。而卡馬克的不同之處在于,他選擇了一個神秘的猜測值0x5f3759df作為起始,使得整個逼近過程收斂速度暴漲,對于Quake III所要求的精度10的負三次方,只需要一次迭代就能夠得到結果。

            好吧,如果這還不算牛b,接著看。

            普渡大學的數學家Chris Lomont看了以后覺得有趣,決定要研究一下卡馬克弄出來的這個猜測值有什么奧秘。Lomont也是個牛人,在精心研究之后從理論上也推導出一個最佳猜測值,和卡馬克的數字非常接近, 0x5f37642f。卡馬克真牛,他是外星人嗎?

            傳奇并沒有在這里結束。Lomont計算出結果以后非常滿意,于是拿自己計算出的起始值和卡馬克的神秘數字做比賽,看看誰的數字能夠更快更精確的求得平方根。結果是卡馬克贏了... 誰也不知道卡馬克是怎么找到這個數字的。

            最后Lomont怒了,采用暴力方法一個數字一個數字試過來,終于找到一個比卡馬克數字要好上那么一丁點的數字,雖然實際上這兩個數字所產生的結果非常近似,這個暴力得出的數字是0x5f375a86。

            Lomont為此寫下一篇論文,"Fast Inverse Square Root"

            John Carmack, ID的無價之寶

            來源blog:http://jan.yculblog.com/

            posted @ 2006-07-14 23:13 Gohan 閱讀(1312) | 評論 (0)編輯 收藏

            昨天,今天,明天。

            昨天早上回來的家。
            大學一年中學到的東西沒有太多。書...還是只消化了3本多點...
            很多雜亂無章的東西需要學吧。
            今天,仍然看看書,上上機。準備明天的實習生活。
            我明天會去當地影響最大的IT公司進行業余實習,其實不能說實習,
            算是學習。知道明天會用到cb,oracle,進行COM組件編程,我還一點都不會。
            其實至于vc我也只是console coder...不過沒事,當作去學習吧。
            明天,期待是美好的一天,我會彌補大一知識的空白,實踐,實踐,實踐。
            希望早日變強。

            posted @ 2006-07-11 20:42 Gohan 閱讀(239) | 評論 (0)編輯 收藏

            □□□□×□=□□□□

            mop上有人問這個如何編程實現
            題目是123456789這9個數字組成一個等式,不可重復
            □□□□×□=□□□□
            我的想法就是枚舉
            于是:
            #include <iostream>

            using namespace std;

            long c[9]={1,1,1,1,1,1,1,1,1};
            int check(int);
            main()
            {
              
            for(c[0]=1;c[0]<10;c[0]++)
                  
            for(c[1]=1;c[1]<10;c[1]++)
                      
            if (check(1)) ;else
                      
            for(c[2]=1;c[2]<10;c[2]++)
                          
            if (check(2)) ; else
                          
            for(c[3]=1;c[3]<10;c[3]++)
                              
            if (check(3)) ;else
                              
            for(c[4]=1;c[4]<10;c[4]++)
                                  
            if (check(4)) ;else
                                  
            for(c[5]=1;c[5]<10;c[5]++)
                                      
            if (check(5)) ;else
                                      
            for(c[6]=1;c[6]<10;c[6]++)
                                          
            if (check(6)) ;
                                          
            else for(c[7]=1;c[7]<10;c[7]++)
                                              
            if (check(7)) ;
                                              
            else for(c[8]=1;c[8]<10;c[8]++){
                                                
            if (check(8)) ;
                                                
            else if((c[0]*1000+c[1]*100+c[2]*10+c[3])*c[4]==(c[5]*1000+c[6]*100+c[7]*10+c[8])) 
                                                    cout
            <<c[0]<<c[1]<<c[2]<<c[3]<<"*"<<c[4]<<"="<<c[5]<<c[6]<<c[7]<<c[8]<<endl;
                                              }

                                          
                                            


                                      
            }


              
            int check(int i){
                
            int flag=0;
                
            for (int ctr=0;ctr<i;ctr++)
                    
            if (ctr==i) ctr++;
                    
            else if(c[ctr]==c[i]) flag++;
                
            return flag;

              }

            posted @ 2006-02-19 20:15 Gohan 閱讀(234) | 評論 (0)編輯 收藏

            僅列出標題
            共16頁: First 8 9 10 11 12 13 14 15 16 
            国产激情久久久久影院| 国产亚洲欧美成人久久片| 国产亚洲欧美成人久久片| 久久久久久免费视频| 欧美日韩成人精品久久久免费看 | 国产精品女同一区二区久久| 国内精品人妻无码久久久影院 | 久久精品国产亚洲沈樵| 久久精品人成免费| 国内精品九九久久久精品| 精品久久久久中文字幕日本| 国内精品久久久久久99蜜桃| 久久精品中文字幕久久| 国产精品欧美久久久久无广告 | 久久久久亚洲AV无码专区桃色| 91性高湖久久久久| 久久人人爽人人爽AV片| 思思久久精品在热线热| 亚洲中文字幕无码久久精品1| 久久精品国产亚洲精品2020| 91精品久久久久久无码| 三级片免费观看久久| 国内精品人妻无码久久久影院导航| 亚洲AV日韩AV天堂久久| 久久中文字幕一区二区| 久久综合九色综合久99| 日韩精品久久久久久久电影蜜臀| 高清免费久久午夜精品| 久久香蕉国产线看观看猫咪?v| 中文精品99久久国产| 国产精品天天影视久久综合网| 精品免费久久久久国产一区| 一本大道久久东京热无码AV| 国内精品久久久久久野外| 亚洲午夜福利精品久久| 国产成人无码久久久精品一| 亚洲精品无码久久不卡| 久久久久久a亚洲欧洲aⅴ | 亚洲精品乱码久久久久66| 国产L精品国产亚洲区久久| 久久精品国产男包|