• <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>

            MyMSDN

            MyMSDN記錄開發新知道

            #

            [C++]namespace&using keyword

            有時候我們可以用namespace來組織命名空間。

            有時候我們又希望將一些較深層次的類變成我們比較容易訪問的對象。

            下面的代碼提供了一種簡單的示例來滿足這樣的需求。

            1、用namespace來組織各個類的層級關系。

            2、用using關鍵字,將深層次結構暴露到較外層。

            //============================================================================
            // Name        : namespace.cpp
            // Author      : Volnet
            // Version     :
            // Copyright   : reserve by volnet@tom.com
            // Description : namespace in C++, Ansi-style
            //============================================================================
            
            #include <iostream>
            
            namespace volnet {
                namespace extensions {
                    class _Console {
                    public:
                        void WriteLine(std::string);
                    };
                }
                using extensions::_Console;
            }
            using namespace volnet;
            _Console Console;
            
            void
            _Console::WriteLine(std::string s) {
                std::cout << s << std::endl;
            }
            
            using namespace std;
            
            int main() {
                Console.WriteLine(std::string("I'm volnet!"));
                return 0;
            }

            posted @ 2010-03-29 13:28 volnet 閱讀(1413) | 評論 (0)編輯 收藏

            Eclipse CDT 的無效路徑

            Eclipse CDT在修改內建的Includes的時候(右鍵項目,點擊屬性,C/C++ General),右邊的Delete按鈕將不可用,也就是說,無法刪除它們。

            image

            這個Includes將會影響到解決方案項目樹下的Includes。如果這些Includes實際不存在的時候,編譯后將出現警告(不影響正常使用),但是非常令人發指。

            image

            如何刪掉它們呢?

            在工作區對應的.metadata文件夾下,{workspace}\.metadata\.plugins\org.eclipse.cdt.make.core\{projectname},找到你自己的項目,并搜索一些關鍵字,比如你實際不存在的路徑,將對應的節點刪除即可。保存后重新打開Eclipse,它們應該就不復存在了。

            引用:http://zadecn.spaces.live.com/Blog/cns!85EE31844454E642!337.entry?sa=661235468
            使用Eclipse + CDT,我經常使用一些環境變量設置include path.同時當我把這個工程文件在機器之間移植的時候,我一般會修改這些環境變量的值,非常奇怪的是,Eclipse仍然會保留那些沒有使用的,無效的 include path.
            這雖然不會造成嚴重的錯誤,但是會生成警告,非常令人討厭.我一直查找刪除這些無效的include path的方法,終于查找到這樣的一句話:
            I've seen this problem too, old paths are never deleted. To manually fix the file you need to move/delete the ${projectname}.sc file found under ${workspace}/.metadata/.plugins/org.eclipse.cdt.make.core
            這樣就可以了.

            posted @ 2010-03-26 13:24 volnet 閱讀(1566) | 評論 (0)編輯 收藏

            boost::tuple

            boost::tuple<derived> tup4;
            boost::tuple<base> tup5;
            tup5 = tup4;
            tup4.get<0>().test();
            tup5.get<0>().test(); // 丟失多態性
            derived d; boost::tuple<derived*> tup6(&d); boost::tuple<base*> tup7; tup7 = tup6; tup6.get<0>()->test(); tup7.get<0>()->test(); // 恢復多態性(方法1) boost::tuple<derived&> tup8(d); boost::tuple<base&> tup9(tup8);
            // tup9 = tup8; 不能使用該方法,因為無法對引用賦值。
            tup8.get<0>().test(); tup9.get<0>().test(); // 恢復多態性(方法2)
            /*
             * tuple.cpp
             *
             *  Created on: 2010-3-25
             *      Author: GoCool
             */
            #include <stdlib.h>
            #include <iostream>
            #include <boost/tuple/tuple.hpp>
            #include <boost/tuple/tuple_io.hpp>
            #include "../header/baseClass.h"
            
            using namespace std;
            class X {
              X();
            public:
              X(std::string){}
            };
            class Y {
              Y(const Y&);
            public:
              Y(){}
            };
            class A {
            };
            bool operator==(A, A) { std::cout << "All the same to me..."; return true; }
            void f(int i);
            
            void cut_off_rule(void);
            int main(void){
                // add a new tuple
                boost::tuple<int,double,std::string>   triple(42, 3.14, "My first tuple!");
                int a = triple.get<0>();
                ++a;
                cout << a << endl;
                cout << triple << endl;
            
                cut_off_rule();
            
                boost::tuple<int, double> pair = boost::make_tuple(21, 22.5);
                cout << pair << endl;
            
                cut_off_rule();
            
                int pair_element_1 = -1;
                double pair_element_2 = -1;
                boost::tie(pair_element_1, pair_element_2) = pair;
            
                cout << pair_element_1 << "," << pair_element_2 << endl;
            
                cut_off_rule();
            
                boost::tuple<int,std::string,derived> tup1(-5,"Tuples");
                boost::tuple<unsigned int,std::string,base> tup2;
                tup2=tup1;
                tup2.get<2>().test();
                std::cout << "Interesting value: " << tup2.get<0>() << '\n';
                const boost::tuple<double,std::string,base> tup3(tup2);
                // Description    Resource    Path    Location    Type
                // assignment of read-only location    tuple.cpp    boost_tuple/src    45    C/C++ Problem
                // tup3.get<0>()=3.14;
            
                cut_off_rule();
            
                boost::tuple<X,X,X> obj = boost::tuple<X,X,X>(string("Jaba"), string("Daba"), string("Duu")); // ok
            
                cut_off_rule();
            
                double dNum = 5;
                boost::tuple<double&> numTuple(dNum);               // ok
            
                // boost::tuple<double&>(dNum+3.14);          // error: cannot initialize
                                                // non-const reference with a temporary
            
                boost::tuple<const double&>(dNum+3.14);    // ok, but dangerous:
                                                // the element becomes a dangling reference
                cut_off_rule();
            
                // char arr[2] = {'a', 'b'};
                // boost::tuple<char[2]>(arr); // error, arrays can not be copied
                // boost::tuple<char[2], Y>(arr, Y()); // error, neither arrays nor Y can be copied
            
                boost::tuple<char[2], Y>();       // ok
            
                cut_off_rule();
            
                boost::tuple<void (*)(int)> pFTuple1 = boost::make_tuple(&f);
                pFTuple1.get<0>()(10);
            
                boost::tuple<void (*)(int)> pFTuple2 = boost::make_tuple(boost::ref(f));
                pFTuple2.get<0>()(20);
            
                boost::tuple<void (&)(int)> pFTuple3(f);
                pFTuple3.get<0>()(30);
            
                boost::tuple<boost::tuple<void (&)(int)> > pFTuple4(f);
                pFTuple4.get<0>().get<0>()(40);
            
                cut_off_rule();
            
                // boost::tuple<int, char> stdPairToTuple = std::make_pair(1, 'a');
            
                cut_off_rule();
            
                boost::tuple<std::string, int, A> t1(std::string("same?"), 2, A());
                boost::tuple<std::string, long> t2(std::string("same?"), 2);
                boost::tuple<std::string, long> t3(std::string("different"), 3);
                // t1 == t2;        // true
            
                cut_off_rule();
            
                int i; char c;
                boost::tie(i, c) = std::make_pair(1, 'a');
                cout << i << " " << c << endl;
            
                cut_off_rule();
            
                boost::tie(boost::tuples::ignore, c) = std::make_pair(1, 'a');
                cout << c << endl;
            
                cut_off_rule();
            
                int myX = -1;
                double myY = -2;
                boost::tuple<int, double> f2(2);
                boost::tie(myX, myY) = f2; // #2
                cout << "myX = " << myX << ", myY = " <<myY << endl;
            }
            void cut_off_rule(void) {
                cout << "-----------------------------------" << endl;
            }
            
            void f(int i) {
                cout << "f(" << i << ")" << endl;
            }
            
            
            

            tuple是boost庫中一個類似標準std::pair庫庫,但pair只能支持兩種元素,而tuple則可以支持大于兩種的。

            更多詳解:http://www.boost.org/doc/libs/1_42_0/libs/tuple/doc/tuple_users_guide.html

            以下內容直接引自原文:


             

            Boost C++ LibrariesBoost C++ Libraries

            “...one of the most highly regarded and expertly designed C++ library projects in the world.” — Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

            C++ 
Boost

            The Boost Tuple Library

            A tuple (or n-tuple) is a fixed size collection of elements. Pairs, triples, quadruples etc. are tuples. In a programming language, a tuple is a data object containing other objects as elements. These element objects may be of different types.

            Tuples are convenient in many circumstances. For instance, tuples make it easy to define functions that return more than one value.

            Some programming languages, such as ML, Python and Haskell, have built-in tuple constructs. Unfortunately C++ does not. To compensate for this "deficiency", the Boost Tuple Library implements a tuple construct using templates.

            Table of Contents

            1. Using the library
            2. Tuple types
            3. Constructing tuples
            4. Accessing tuple elements
            5. Copy construction and tuple assignment
            6. Relational operators
            7. Tiers
            8. Streaming
            9. Performance
            10. Portability
            11. Acknowledgements
            12. References
            More details

            Advanced features (describes some metafunctions etc.).

            Rationale behind some design/implementation decisions.

            Using the library

            To use the library, just include:

            #include "boost/tuple/tuple.hpp"

            Comparison operators can be included with:

            #include "boost/tuple/tuple_comparison.hpp"

            To use tuple input and output operators,

            #include "boost/tuple/tuple_io.hpp"

            Both tuple_io.hpp and tuple_comparison.hpp include tuple.hpp.

            All definitions are in namespace ::boost::tuples, but the most common names are lifted to namespace ::boost with using declarations. These names are: tuple, make_tuple, tie and get. Further, ref and cref are defined directly under the ::boost namespace.

            Tuple types

            A tuple type is an instantiation of the tuple template. The template parameters specify the types of the tuple elements. The current version supports tuples with 0-10 elements. If necessary, the upper limit can be increased up to, say, a few dozen elements. The data element can be any C++ type. Note that void and plain function types are valid C++ types, but objects of such types cannot exist. Hence, if a tuple type contains such types as elements, the tuple type can exist, but not an object of that type. There are natural limitations for element types that cannot be copied, or that are not default constructible (see 'Constructing tuples' below).

            For example, the following definitions are valid tuple instantiations (A, B and C are some user defined classes):

            tuple<int>
            tuple<double&, const double&, const double, double*, const double*>
            tuple<A, int(*)(char, int), B(A::*)(C&), C>
            tuple<std::string, std::pair<A, B> >
            tuple<A*, tuple<const A*, const B&, C>, bool, void*>

            Constructing tuples

            The tuple constructor takes the tuple elements as arguments. For an n-element tuple, the constructor can be invoked with k arguments, where 0 <= k <= n. For example:

            tuple<int, double>() 
            tuple<int, double>(1)
            tuple<int, double>(1, 3.14)

            If no initial value for an element is provided, it is default initialized (and hence must be default initializable). For example.

            class X {
            X();
            public:
            X(std::string);
            };

            tuple<X,X,X>() // error: no default constructor for X
            tuple<X,X,X>(string("Jaba"), string("Daba"), string("Duu")) // ok

            In particular, reference types do not have a default initialization:

            tuple<double&>()                // error: reference must be 
            // initialized explicitly

            double d = 5;
            tuple<double&>(d) // ok

            tuple<double&>(d+3.14) // error: cannot initialize
            // non-const reference with a temporary

            tuple<const double&>(d+3.14) // ok, but dangerous:
            // the element becomes a dangling reference

            Using an initial value for an element that cannot be copied, is a compile time error:

            class Y { 
            Y(const Y&);
            public:
            Y();
            };

            char a[10];

            tuple<char[10], Y>(a, Y()); // error, neither arrays nor Y can be copied
            tuple<char[10], Y>(); // ok

            Note particularly that the following is perfectly ok:

            Y y;
            tuple<char(&)[10], Y&>(a, y);

            It is possible to come up with a tuple type that cannot be constructed. This occurs if an element that cannot be initialized has a lower index than an element that requires initialization. For example: tuple<char[10], int&>.

            In sum, the tuple construction is semantically just a group of individual elementary constructions.

            The make_tuple function

            Tuples can also be constructed using the make_tuple (cf. std::make_pair) helper functions. This makes the construction more convenient, saving the programmer from explicitly specifying the element types:

            tuple<int, int, double> add_multiply_divide(int a, int b) {
            return make_tuple(a+b, a*b, double(a)/double(b));
            }

            By default, the element types are deduced to the plain non-reference types. E.g.:

            void foo(const A& a, B& b) { 
            ...
            make_tuple(a, b);

            The make_tuple invocation results in a tuple of type tuple<A, B>.

            Sometimes the plain non-reference type is not desired, e.g. if the element type cannot be copied. Therefore, the programmer can control the type deduction and state that a reference to const or reference to non-const type should be used as the element type instead. This is accomplished with two helper template functions: ref and cref. Any argument can be wrapped with these functions to get the desired type. The mechanism does not compromise const correctness since a const object wrapped with ref results in a tuple element with const reference type (see the fifth example below). For example:

            A a; B b; const A ca = a;
            make_tuple(cref(a), b); // creates tuple<const A&, B>
            make_tuple(ref(a), b); // creates tuple<A&, B>
            make_tuple(ref(a), cref(b)); // creates tuple<A&, const B&>
            make_tuple(cref(ca)); // creates tuple<const A&>
            make_tuple(ref(ca)); // creates tuple<const A&>

            Array arguments to make_tuple functions are deduced to reference to const types by default; there is no need to wrap them with cref. For example:

            make_tuple("Donald", "Daisy");

            This creates an object of type tuple<const char (&)[7], const char (&)[6]> (note that the type of a string literal is an array of const characters, not const char*). However, to get make_tuple to create a tuple with an element of a non-const array type one must use the ref wrapper.

            Function pointers are deduced to the plain non-reference type, that is, to plain function pointer. A tuple can also hold a reference to a function, but such a tuple cannot be constructed with make_tuple (a const qualified function type would result, which is illegal):

            void f(int i);
            ...
            make_tuple(&f); // tuple<void (*)(int)>
            ...

            volnet:
            boost::tuple<void (&)(int)> pFTuple3(f);

            pFTuple3.get<0>()(30);

            tuple<tuple<void (&)(int)> > a(f) // ok
            make_tuple(f); // not ok

            Accessing tuple elements

            Tuple elements are accessed with the expression:

            t.get<N>()

            or

            get<N>(t)

            where t is a tuple object and N is a constant integral expression specifying the index of the element to be accessed. Depending on whether t is const or not, get returns the Nth element as a reference to const or non-const type. The index of the first element is 0 and thus N must be between 0 and k-1, where k is the number of elements in the tuple. Violations of these constraints are detected at compile time. Examples:

            double d = 2.7; A a;
            tuple<int, double&, const A&> t(1, d, a);
            const tuple<int, double&, const A&> ct = t;
            ...
            int i = get<0>(t); i = t.get<0>(); // ok
            int j = get<0>(ct); // ok
            get<0>(t) = 5; // ok
            get<0>(ct) = 5; // error, can't assign to const
            ...
            double e = get<1>(t); // ok
            get<1>(t) = 3.14; // ok
            get<2>(t) = A(); // error, can't assign to const
            A aa = get<3>(t); // error: index out of bounds
            ...
            ++get<0>(t); // ok, can be used as any variable

            Note! The member get functions are not supported with MS Visual C++ compiler. Further, the compiler has trouble with finding the non-member get functions without an explicit namespace qualifier. Hence, all get calls should be qualified as: tuples::get<N>(a_tuple) when writing code that should compile with MSVC++ 6.0.

            Copy construction and tuple assignment

            A tuple can be copy constructed from another tuple, provided that the element types are element-wise copy constructible. Analogously, a tuple can be assigned to another tuple, provided that the element types are element-wise assignable. For example:

            class A {};
            class B : public A {};
            struct C { C(); C(const B&); };
            struct D { operator C() const; };
            tuple<char, B*, B, D> t;
            ...
            tuple<int, A*, C, C> a(t); // ok
            a = t; // ok

            In both cases, the conversions performed are: char -> int, B* -> A* (derived class pointer to base class pointer), B -> C (a user defined conversion) and D -> C (a user defined conversion).

            Note that assignment is also defined from std::pair types:

            tuple<float, int> a = std::make_pair(1, 'a');

            volnet:(Eclipse with MinGW g++
            conversion from `std::pair<int, char>' to non-scalar type `boost::tuples::tuple<float, int, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>' requested

            Relational operators

            Tuples reduce the operators ==, !=, <, >, <= and >= to the corresponding elementary operators. This means, that if any of these operators is defined between all elements of two tuples, then the same operator is defined between the tuples as well. The equality operators for two tuples a and b are defined as:

            • a == b iff for each i: ai == bi
            • a != b iff exists i: ai != bi

            The operators <, >, <= and >= implement a lexicographical ordering.

            Note that an attempt to compare two tuples of different lengths results in a compile time error. Also, the comparison operators are "short-circuited": elementary comparisons start from the first elements and are performed only until the result is clear.

            Examples:

            tuple<std::string, int, A> t1(std::string("same?"), 2, A());
            tuple<std::string, long, A> t2(std::string("same?"), 2, A());
            tuple<std::string, long, A> t3(std::string("different"), 3, A());

            bool operator==(A, A) { std::cout << "All the same to me..."; return true; }

            t1 == t2; // true
            t1 == t3; // false, does not print "All the..."

            Tiers

            Tiers are tuples, where all elements are of non-const reference types. They are constructed with a call to the tie function template (cf. make_tuple):

            int i; char c; double d; 
            ...
            tie(i, c, a);

            The above tie function creates a tuple of type tuple<int&, char&, double&>. The same result could be achieved with the call make_tuple(ref(i), ref(c), ref(a)).

            A tuple that contains non-const references as elements can be used to 'unpack' another tuple into variables. E.g.:

            int i; char c; double d; 
            tie(i, c, d) = make_tuple(1,'a', 5.5);
            std::cout << i << " " << c << " " << d;

            This code prints 1 a 5.5 to the standard output stream. A tuple unpacking operation like this is found for example in ML and Python. It is convenient when calling functions which return tuples.

            The tying mechanism works with std::pair templates as well:

            int i; char c;
            tie(i, c) = std::make_pair(1, 'a');
            Ignore

            There is also an object called ignore which allows you to ignore an element assigned by a tuple. The idea is that a function may return a tuple, only part of which you are interested in. For example (note, that ignore is under the tuples subnamespace):

            char c;
            tie(tuples::ignore, c) = std::make_pair(1, 'a');

            Streaming

            The global operator<< has been overloaded for std::ostream such that tuples are output by recursively calling operator<< for each element.

            Analogously, the global operator>> has been overloaded to extract tuples from std::istream by recursively calling operator>> for each element.

            The default delimiter between the elements is space, and the tuple is enclosed in parenthesis. For Example:

            tuple<float, int, std::string> a(1.0f,  2, std::string("Howdy folks!");

            cout << a;

            outputs the tuple as: (1.0 2 Howdy folks!)

            The library defines three manipulators for changing the default behavior:

            • set_open(char) defines the character that is output before the first element.
            • set_close(char) defines the character that is output after the last element.
            • set_delimiter(char) defines the delimiter character between elements.

            Note, that these manipulators are defined in the tuples subnamespace. For example:

            cout << tuples::set_open('[') << tuples::set_close(']') << tuples::set_delimiter(',') << a; 

            outputs the same tuple a as: [1.0,2,Howdy folks!]

            The same manipulators work with operator>> and istream as well. Suppose the cin stream contains the following data:

            (1 2 3) [4:5]

            The code:

            tuple<int, int, int> i;
            tuple<int, int> j;

            cin >> i;
            cin >> tuples::set_open('[') >> tuples::set_close(']') >> tuples::set_delimiter(':');
            cin >> j;

            reads the data into the tuples i and j.

            Note that extracting tuples with std::string or C-style string elements does not generally work, since the streamed tuple representation may not be unambiguously parseable.

            Performance

            All tuple access and construction functions are small inlined one-liners. Therefore, a decent compiler can eliminate any extra cost of using tuples compared to using hand-written tuple like classes. Particularly, with a decent compiler there is no performance difference between this code:

            class hand_made_tuple { 
            A a; B b; C c;
            public:
            hand_made_tuple(const A& aa, const B& bb, const C& cc)
            : a(aa), b(bb), c(cc) {};
            A& getA() { return a; };
            B& getB() { return b; };
            C& getC() { return c; };
            };

            hand_made_tuple hmt(A(), B(), C());
            hmt.getA(); hmt.getB(); hmt.getC();

            and this code:

            tuple<A, B, C> t(A(), B(), C());
            t.get<0>(); t.get<1>(); t.get<2>();

            Note, that there are widely used compilers (e.g. bcc 5.5.1) which fail to optimize this kind of tuple usage.

            Depending on the optimizing ability of the compiler, the tier mechanism may have a small performance penalty compared to using non-const reference parameters as a mechanism for returning multiple values from a function. For example, suppose that the following functions f1 and f2 have equivalent functionalities:

            void f1(int&, double&);
            tuple<int, double> f2();

            Then, the call #1 may be slightly faster than #2 in the code below:

            int i; double d;
            ...
            f1(i,d); // #1
            tie(i,d) = f2(); // #2

            volnet:
            int myX = -1;
            double myY = -2;
            boost::tuple<int, double> f2(2);
            boost::tie(myX, myY) = f2; // #2
            cout << "myX = " << myX << ", myY = " <<myY << endl;

            See [1, 2] for more in-depth discussions about efficiency.

            Effect on Compile Time

            Compiling tuples can be slow due to the excessive amount of template instantiations. Depending on the compiler and the tuple length, it may be more than 10 times slower to compile a tuple construct, compared to compiling an equivalent explicitly written class, such as the hand_made_tuple class above. However, as a realistic program is likely to contain a lot of code in addition to tuple definitions, the difference is probably unnoticeable. Compile time increases between 5 and 10 percent were measured for programs which used tuples very frequently. With the same test programs, memory consumption of compiling increased between 22% to 27%. See [1, 2] for details.

            Portability

            The library code is(?) standard C++ and thus the library works with a standard conforming compiler. Below is a list of compilers and known problems with each compiler:

            Compiler
            Problems

            gcc 2.95
            -

            edg 2.44
            -

            Borland 5.5
            Can't use function pointers or member pointers as tuple elements

            Metrowerks 6.2
            Can't use ref and cref wrappers

            MS Visual C++
            No reference elements (tie still works). Can't use ref and cref wrappers

            Acknowledgements

            Gary Powell has been an indispensable helping hand. In particular, stream manipulators for tuples were his idea. Doug Gregor came up with a working version for MSVC, David Abrahams found a way to get rid of most of the restrictions for compilers not supporting partial specialization. Thanks to Jeremy Siek, William Kempf and Jens Maurer for their help and suggestions. The comments by Vesa Karvonen, John Max Skaller, Ed Brey, Beman Dawes, David Abrahams and Hartmut Kaiser helped to improve the library. The idea for the tie mechanism came from an old usenet article by Ian McCulloch, where he proposed something similar for std::pairs.

            References

            [1] J?rvi J.: Tuples and multiple return values in C++, TUCS Technical Report No 249, 1999.

            [2] J?rvi J.: ML-Style Tuple Assignment in Standard C++ - Extending the Multiple Return Value Formalism, TUCS Technical Report No 267, 1999.

            [3] J?rvi J.:Tuple Types and Multiple Return Values, C/C++ Users Journal, August 2001.


            Last modified 2003-09-07

            ? Copyright Jaakko J?rvi 2001. Permission to copy, use, modify, sell and distribute this software and its documentation is granted provided this copyright notice appears in all copies. This software and its documentation is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose.



             

            posted @ 2010-03-25 17:46 volnet 閱讀(1698) | 評論 (0)編輯 收藏

            貪心算法:輸入一組數,由它組合出一個最大的可以被15整除

            命題:輸入一組數,由它組合出一個最大的可以被15整除。
            思路:能被15整除的數,必然能被5和3整除,則必須要滿足整除5和整除3的特征。

            用貪心法可以組合出這些數中最大的一個。(代碼如下)如果組合不出來,則輸出impossible。否則輸出這個數。

            // Divide3.cpp : 定義控制臺應用程序的入口點。
            //
            
            #include <cstdio>
            #include <iostream>
            #include <fstream>
            
            using namespace std;
            
            #define MAX 1000
            #define IMPOSSIBLE "impossible"
            
            char str[MAX];
            // 0的ASCII碼是48,9的ASCII碼是57,因此計數器數組的大小取為58,以利于快速取值
            int counter[58];
            
            // 附加檢驗代碼,本程序中可不執行
            bool checkInput(char *s);
            // 整理所有數字,并分別統計'0'-'9'各個數的計算結果
            void collect(char *s);
            // 判斷是否涵蓋'5'或者'0'
            // 證明:能被整除的數末尾必須是或者
            bool canDivideBy5or0();
            // 判斷一個字符是不是'3' '6' '9'中的一個
            inline bool belongsTo369(char c);
            // 貪心法將數字轉換成可以被整除的數,并輸出結果
            bool connect();
            
            int main( )
            {
                freopen("input.txt", "r", stdin); //文件輸入輸出
                freopen("output.txt", "w", stdout);
            
                scanf("%s", str);
            
                // 為了加快速度略去字符串檢查,假設所有輸入都是合法的
                //if(!checkInput(str))
                //    printf("err");
            
                collect(str);
            
                // 輸出計數器
                //int i;
                //for(i='0'; i<='9'; ++i)
                //{
                //    printf("%c:%d\n", i,counter[i]);
                //}
            
                if(!canDivideBy5or0())//假如canDivideBy5or0()=false,即不能整除,則輸出impossible
                {
                    //printf("Can not be divided by 5 or 0!\n");
                    printf(IMPOSSIBLE);
                    return 0;
                }
                if(!connect())//假如connect()=false,即無法把字符數組連接起來,則輸出impossible
                    printf(IMPOSSIBLE);
            
                //printf("%s", str);
            
                return 0;
            }
            
            void collect(char *s)//分別統計字符串中'0'-'9'的出現個數
            {
                int i = 0;  //i表示字符串的第i個字符
                while(s[i] != '\0' && i < MAX)
                {
                    ++counter[s[i]];
                    ++i;
                }
            }
            
            bool canDivideBy5or0()//如果字符串中出現過或,即能被整除,則輸出true,否則輸出false
            {
                if(counter['5'] > 0)
                    return true;
                if(counter['0'] > 0)
                    return true;
                return false;
            }
            
            bool belongsTo369(char c)//判斷一個字符是不是'3' '6' '9'中的一個,如果是,則輸出true,否則輸出false
            {
                if(c == '3' || c == '6' || c == '9')
                    return true;
                return false;
            }
            
            bool connect()//把整個字符數組連接起來,并輸出
            {
                bool canConnect = true;// canConnect是一個標志,表示是否可以開始連接了?
            
                int i;
                int sum = 0;
            
                // 從最大的數開始遞減到,并將所有不是、、的數加起來,將結果存放在sum中
                for(i='9'; i>'0'; --i)
                {
                    if(counter[i] == 0 || belongsTo369(i))//如果某個數字沒有的話,比如一個序列里沒有'9'就跳過,或者如果有數字,但是它屬于,,,那也跳過。然后把剩下的數字都加起來   
                        continue;
                    sum += (counter[i] * (i - '0'));//(i - '0')因為都是字符'1','2',…所以,要-'0'得到它的數值,,…,然后乘以它的數量
            
                }
            
                int mod = sum % 3;
                if( mod == 0 )
                    canConnect = true;
                else if(mod == 1)
                {
                    canConnect = false;
                    for(i = '1'; i <= '9'; i+=3)
                    {
                        if(counter[i] != 0)
                        {
                            --counter[i];
                            canConnect = true;
                            break;
                        }
                        //else
                        //    canConnect = false;
                    }
                }
                else if(mod == 2)
                {
                    canConnect = false;
                    for(i = '2'; i <= '8'; i+=3)
                    {
                        if(counter[i] != 0)
                        {
                            --counter[i];
                            if(i=='5')
                            {        
                                if(counter['5']==0 && counter['0'] == 0)
                                {
                                    canConnect = false;
                                    break;
                                }
                            }
                            canConnect = true;
                            break;
                        }
                        //else 
                        //    canConnect = false;
                    }
                }
            
                if(!canConnect) //如果canConnect=false,返回false
                    return false;
            
                //以下為輸出。此時計數器里面的數值已經是最終方案了,根據下面的規律,用貪心法生成輸出結果
                // 貪心法:
                // 要湊齊一個最大的整數,那么它必須滿足兩個條件
                // 1、位數最多,比如和比?
                // 2、高位的數字盡量地大,比如和相比
                // 因此:應該先滿足位數最多,因為結果必然可以得到一個整除的數(定理)?
                // 則只需要滿足高位數字大即可,而既然是'9'到'0',因此依次從大到小輸出即可
                // 并且為了結果能乘除,所以最后一位必須為或者
                bool endWith5 = false;//endWith5是一個標記,如果為true表示以結尾,如果為false表示以結尾
                int j = 0;
                int r = 0;
                if(counter['0'] == 0)//如果輸入的字符串中沒有,則必然要以結尾,這部分有錯,例如:輸出
                {
                    endWith5 = true;
                    --counter['5'];//減掉的目的是為了保留一個,留在末尾才輸出
                }
                for(i = '9'; i >= '0'; --i)//計算器中的數字是'9'到'0',為了得到結果是最大的數,依次從大到小輸出數字即可
                {
                    for(j = counter[i]; j > 0; --j)
                    {
                        //printf("%c", i);
                        str[r++] = i;
                    }
                }
                if(endWith5)//如果以結尾,則在末尾輸出一個
                    //printf("5");
                    str[r++] = '5';
                str[r] = '\0';
                printf("%s", str);
                return true;
            }
            
            
            
            
            
            /*
            關于整除的理論基礎:http://www.cbe21.com/subject/maths/printer.phparticle_id=818
            
            “能被3整除的數的特征”教學實錄與評析
             
            金中
             
              
            一、復習舊知
            
             師:前面同學們學習了能被、整除的數的特征,下面老師就來檢查一下(板書出三個數字:、、),你能用、、這三個數字組成能被整除的三位數嗎?
            
             學生根據教師要求組數,教師板書出學生組數的情況:、。
            
             師:為什么這樣組數?
            
             生:因為個位上是、、、、的數能被整除……
            
             師:同樣用這三個數字,你們能組成被整除的數嗎?
            
             教師根據學生組數的情況板書出:、。
            
            師:你們是怎樣想的?
            
             生:因為個位上是或的數都能被整除。
            
             [評]鋪墊復習不落俗套,采用組數的方法,既復習了能被、整除的數的特征,又激發了學生學習的興趣。
            
             二、講授新課
            
            ?。ㄒ唬┰O置教學“陷阱”。
            
             師:如果仍用這三個數字,你能否組成能被整除的數呢?試一試。
            
             教師根據學生組數的情況板書出:、。
            
             師:這兩個數能被整除嗎?
            
             學生試除驗證這兩個數能被整除。
            
             師:從這兩個能被整除的數,你想到了什么?能被整除的數有什么特征?
            
             生:個位上是的倍數的數能被整除。(引導學生提出假設①)
            
             (二)制造認知矛盾。
            
             師:剛才同學們是從個位上去尋找能被整除的數的“特征”的,那么個位上是的倍數的數就一定能被整除嗎?
            
             教師緊接著舉出、、等數讓學生試除判斷,由此引導學生推翻假設①。
            
             師:這幾個數個位上都是的倍數,有的數能被整除,而有的數卻不能被整除。我們能從個位上找出能被3整除的數的特征嗎?
            
             生:不能。
            
            ?。ㄈ┰O疑問激興趣。
            
             師:請同學們仍用、、這三個數字,任意組成一個三位數,看看它們能不能被整除。
            
             學生用、、這三個數字任意組成一個三位數,通過試除發現:所組成的三位數都能被整除。
            
             師:能被整除的數有沒有規律可循呢?下面我們一起來學習“能被整除的數的特征。”(板書課題)
            
            ?。墼u]教師通過設置教學“陷阱”,引導學生提出能被整除的數的特征的假設,到推翻假設,引發認知矛盾,并再次創設學生探究的問題情境,不僅有效地避免了“能被、整除的數的特征”思維定勢的影響,而且進一步地激發了學生的求知欲望。
            
            ?。ㄋ模┮龑骄啃轮?。
            
             師:觀察用、、任意組成的能被整除的三位數,雖然它們的大小不相同,但它們有什么共同點?
            
             引導學生發現:組成的三位數的三個數字相同,所不同的是這三個數字排列的順序不同。
            
             師:三個數字相同,那它們的什么也相同?
            
             生:它們的和也相同。
            
             師:和是多少?
            
             生:這三個數字的和是。
            
             師:這三個數字的和與有什么關系?
            
             生:是的倍數。
            
             師:也就是說它們的和能被什么整除?
            
             生:它們的和能被整除。
            
             師:由此你想到了什么?
            
             學生提出假設②:一個數各位上的數的和能被整除,這個數就能被整除。
            
             師:通過同學們的觀察,有的同學提出了能被整除的數特征的假設,但是同學們觀察的僅是幾個特殊的數,是否能被整除的數都有這樣的特征呢?要說明同學們的假設是正確的,我們需要怎么做?
            
             生:進行驗證。
            
             師:怎樣進行驗證呢?
            
             引導學生任意舉一些能被整除的數,看看各位上的數的和能否被整除。(為了便于計算和研究,可讓學生任意舉出以內的自然數,然后乘以。)
            
             根據學生舉出的數,教師完成如下的板書,并讓學生計算出各個數各位上的數的和進行驗證。
            
             附圖{圖} 
            
             師:通過上面的驗證,說明同學們提出的能被整除的數特征的假設怎樣?
            
             生:是正確的。
            
             師:請同學們翻開書,看看書上是怎樣概括出能被整除的數的特征的。引導學生閱讀教材第頁的有關內容。
            
             師:什么叫各位?它與個位有什么不同?根據這個特征,怎樣判斷一個數能不能被整除?
            
             組織學生討論,加深能被整除的數的特征的認識,掌握判斷一個數能否被整除的方法。
            
            ?。墼u]在學生觀察的基礎上,引導他們提出能被整除的數特征的假設,并驗證假設是否正確,不僅充分調動了學生學習的主動性、積極性,而且滲透了從特殊到一般的數學思想方法,指導了學法。
            
             三、課堂練習
            
            ?。ㄒ唬┡袛嘞旅娓鲾的芊癖徽?,并說明理由。
            
             54 83 114 262 837 
            
            ?。ǘ的鼙徽龁幔磕闶窃鯓优袛嗟模坑袥]有更簡捷的判斷方法?
            
             引導學生發現:、、這三個數字本身就能被整除,因此它們的和自然能被整除。判斷時用不著把它們相加。
            
             (三)數能被整除嗎?(將中插入一些數字改編而成。)
            
             引導學生概括出迅速判斷一個數能否被整除的方法:()先去掉這個數各位上是、、的數;()把余下數位上的數相加,并去掉相加過程中湊成、、的數;()看剩下數位上的數能否被整除。
            
             (四)運用上述判斷一個數能否被整除的方法,迅速判斷、、能否被整除。
            
            ?。ㄎ澹┰谙旅婷總€數的□里填上一個數字,使這個數有約數。它們各有幾種不同的填法?
            
             □4□□56□
            
             引導學生掌握科學的填數方法:()先看已知數位上的數字的和是多少;()如果已知數位上的數字和是的倍數,那么未知數位的□里最小填“”,要填的其它數字可依次加上;如果已知數位上的數字和不是的倍數,那么未知數位的里可先填一個最小的數,使它能與已知數位上的數字和湊成是的倍數,要填的其它數字可在此基礎上依次加上。
            
             (六)寫出兩個能被整除的多位數。
            
             [評]練習設計緊扣教學重點,既注意遵循學生的認識規律,循序漸進,又注重了學生的思維訓練和科學解題方法的指導,使學生數學能力的培養落到了實處。
            
            ?。劭傇u]這節課教師采用“引導學習”的方法進行教學,有以下鮮明的特點:.充分調動了學生學習的積極性、主動性,讓他們參與數學知識形成的全過程,從而確保了學生在學習中的主體地位。.教師在整個教學過程中立足于科學地引導學生的邏輯思維,輔導學生學會研究一類數學問題的方法,指導學生掌握解題的技能技巧,體現出了教師善“導”、會“導”、科學地“導”、巧妙地“導”。.教師把數學知識的傳授、數學思想方法的滲透、學生學習方法的指導、學生的思維訓練和數學能力的培養有機地結合起來,收到優質、高效的教學效果。
            
            
            成師附小
            
            
             
            來自: 中基網>>教學參考
            www.cbe21.com    
            
            */

            posted @ 2010-03-25 17:37 volnet 閱讀(1021) | 評論 (0)編輯 收藏

            如何在Windows 7下安裝Wubi以啟動安裝在Windows下(傳統方式+EasyBCD方式)

            如何在Windows 7下安裝Wubi以啟動安裝在Windows下(傳統方式+EasyBCD方式)


            傳統方式

            1. 前提條件

              1. 本節適合“主分區+邏輯分區”的分區方式,不支持“系統分區+主分區+邏輯分區”的分區方式,也就是說,針對于Windows Vista之前的系統,均適用本節,針對Windows Vista以及之后的系統,若是采用“系統分區+主分區+邏輯分區”的方式(如全盤重裝,包括劃分分區表(重要),安裝系統),本節可能并不適合,請參看下一節“EasyBCD方法。”
            2. 操作步驟

            3. 主要是Windows XP下,大家通過在boot.ini里增加“C:\wubildr.mbr="Ubuntu"”就可以啟動Ubuntu。 而Windows 7則使用了BCD規則(也可以使用EasyBCD工具來運行(相見下文))。

              下面的規則則較為簡單:

              1. 打開XP下的ntldr,以及boot.ini,將其拷貝到Windows 7下(參考附件)
              2. 拷貝wubildr.mbr以及wubildr至主分區(C盤)(這個即便在XP下你也需要完成)
              3. 重新啟動系統即可。

              下載文件:ntldr.zip (32bit)

            EasyBCD方法

            1. 前提條件

              1. 你的Ubuntu是通過wubi的方式安裝的,Grub的方式也類似,只不過是設置的時候選擇別的選項,這里不做描述。
              2. 本節基本適合于Windows(Vista/7)(x86/x64),(XP以及之前的系統適合下面步驟2)對于步驟2中提及的方法可以實現的建議按舊方案。
              3. 本節不適合即將在當前Windows環境下全新安裝Ubuntu的用戶。
              4. Windows系統是System分區+主分區+邏輯分區 構成的。(例如:不是從XP或者其它系統升級而成的,而是全新安裝的)

            2. 操作步驟

              1. 我在舊系統(WinXP)下安裝Ubuntu(by wubi)。
              2. 我將Ubuntu放在我的移動硬盤里面,并與我的另一臺電腦共享(Win7 x86),共享方法:http://forum.ubuntu.org.cn/viewtopic.php?f=48&t=248205
              3. 我購置了新電腦,并安裝了Win7 x64,但步驟2中所提及的適用于Win7 x86的共享方法失效了。(不知是否需要將ntldr替換為x64版的方可生效?因為我沒有,所以不確定)
              4. 我下載了EasyBCD,選擇了“Add/Remove Entries”,選擇了“Linux”選項卡,并選擇Type為“wubi”,于是它在我的C:\下放置了\Device\HarddiskVolume1文件夾以及其中的內容,想必就是一個wubildr.mbr吧?查看menu.lst,主要內容如下:
              5. find --set-root --ignore-floppies \ubuntu\winboot\menu.lst
                configfile \ubuntu\winboot\menu.lst
              6. 通過EasyBCD的“ViewSettings”,看到:
              7. Entry #2

                Name: NeoSmart Linux
                BCD ID: {46ca74c9-fdd2-11de-914a-a89213a2f2bd}
                Drive: \Device\HarddiskVolume1
                Bootloader Path: \NST\NeoGrub.mbr
              8. 因為步驟5中的Drive不是盤符(對應Windows7的項,你很容易分辨出來),因此在“Change Settings”中的“Entity-Based Setting”,選擇你剛設置的Ubuntu,并選擇Drive為C盤(對應步驟2中所提及的共享方法)
              9. 在步驟2中所提及的共享方法里含有兩個文件wubildr.mbr以及wubildr。我們在Win7x64所遭遇的問題就是無法通過啟動項目的設置,讓系統啟動的時候找到這個wubildr.mbr文件,但在EasyBCD中看來,也似乎沒有地方可以改變NeoGrub.mbr的名字,那么一個折中的方案就是將wubildr.mbr的名字修改成NeoGrub.mbr,并將其放在C盤(在之前步驟的Drive中設置)下的NST目錄中,并將舊的wubildr文件拷貝至C盤(同樣等同于Drive的盤符設置)
              10. 至此,重新啟動電腦,應該就會出現你所熟悉的場景了。

            posted @ 2010-01-16 20:16 volnet 閱讀(2539) | 評論 (0)編輯 收藏

            C語言位域

            這個概念顯然是知道的,不過剛才忘了,然后寫了個程序就明白了,記錄一下,也許以后又健忘了:
             1 #include <stdio.h>
             2 typedef struct _SimpleType1 {
             3     int Variable1;    //4bytes(32bits)
             4     int Variable2;    //4bytes(32bits)
             5     int Variable3;    //4bytes(32bits)
             6     int Variable4;    //4bytes(32bits)
             7 } SimpleType1;
             8 
             9 typedef struct _ComplexType1 {
            10     int Variable1 : 8;    //1bytes(8bits)
            11     int Variable2 : 8;    //1bytes(8bits)
            12     int Variable3 : 8;    //1bytes(8bits)
            13     int Variable4 : 8;    //1bytes(8bits)
            14 } ComplexType1;
            15 
            16 typedef struct _ComplexType2 {
            17     int Variable1 : 8;    //1bytes(8bits)
            18     int Variable2 : 8;    //1bytes(8bits)
            19     int Variable3 : 8;    //1bytes(8bits)
            20     int Variable4 : 8;    //1bytes(8bits)
            21     int Variable5 : 1;    //0.125bytes(1bits) but the it also hold 32bits 
            22 } ComplexType2;
            23 
            24 int main(void){
            25     printf("sizeof SimpleType1 = %d\n"sizeof(SimpleType1));
            26     printf("sizeof ComplexType1 = %d\n"sizeof(ComplexType1));
            27     printf("sizeof ComplexType2 = %d\n"sizeof(ComplexType2));
            28 }
            結果:
            sizeof SimpleType1 = 16
            sizeof ComplexType1 = 4
            sizeof ComplexType2 = 8

            posted @ 2009-12-30 01:02 volnet 閱讀(795) | 評論 (0)編輯 收藏

            關于線程同步的一些總結(用戶模式/內核模式)

            自旋鎖同步

            1. 一般是為了內核態下各個派遣函數之間做同步作用的。
            2. 原理是(單CPU)將IRQL從軟件中斷提升到硬件中斷。PASSIVE_LEVEL->DISPATCH_LEVEL。因為在DISPATCH_LEVEL中是不會出現線程切換的(只有高級別能打斷低級別,而低級別不能打斷高級別)。
            3. 因為分頁內存將導致如果線程切換的時候會引起分頁數據交換,數據交換是通過引發頁故障來實現的,而頁故障是不允許出現在DISPATCH_LEVEL中的,否則將引起系統崩潰(PASSIVE_LEVEL則允許)。驅動程序的StartIO例程、DPC例程、中斷服務例程都運行在DISPATCH_LEVEL或者更高的IRQL。因此這些例程不能使用分頁內存,否則將導致系統崩潰。
            4. 自旋鎖在不同IRP之間同步的時候,則需要放在DeviceExtension中傳遞。

            互鎖

            1. 類似于number++; //匯編后將不止一條語句,非原子操作number--; //同上因為語句會變成多句,在線程切換的時候,兩個線程下的該例程將會交織在一起執行,導致錯誤。可以:
              先加鎖
              number++;
              解鎖
              再加鎖
              number--;
              解鎖
              來實現兩句話的同步(按指定順序執行,而不受到線程切換的影響)加鎖解鎖可以使用自旋鎖
            2. 在系統中提供了Interlocked***/ExInterlocked***實現

            信號燈同步

            1. 線程1關閉信號燈,以至于使用Wait****的時候,當前線程處于暫停狀態。
            2. 線程2的作用就是在執行結束后,點亮信號燈(增加計數器)。當線程切換回來的時候,線程1就因為計數器不是0而使信號燈處于激活狀態,從而繼續執行線程1。

            事件的同步

            (不能遞歸獲取互斥體)
            1. 主線程在輔助線程上設置了事件,如果不使用Wait**等待事件返回,則主線程可能直接執行完畢了,而導致輔助線程還在執行。
            2. 使用Wait****可以使主線程等待事件執行完成。

            互斥體同步

            (允許遞歸獲取互斥體(得到互斥體的線程還可以再次獲得這個互斥體,或者說互斥體對于已經獲得互斥體的線程不產生“互斥”關系))
            1. 創建一個互斥體對象,將互斥體對象傳遞給多個線程。
            2. 在每個線程操作的步驟中,調用Wait*****,如果互斥體處于激活(內部維護一個計數器),則繼續執行后續代碼,并在調用結束后恢復互斥體Release****,這樣當別的線程試圖使用互斥體后面的代碼的時候,因為互斥體狀態未激活,則無法繼續執行代碼。

            快速互斥體同步

            1. 與互斥體同步類似,唯一區別是不允許遞歸獲取互斥體

            posted @ 2009-12-26 05:53 volnet 閱讀(2085) | 評論 (2)編輯 收藏

            如何編譯TrueCrypt源碼

            相關配置

                 
            • Intel x86 Core 2 Duo
            •    
            • Windows 7 Ultimate x86 version
            •    
            • Windows Driver Develop Kit 7600.16385.0
            •    
            • TrueCrypt 6.3a Source.zip
            •    
            • Microsoft Visual Studio 2008 SP1 (VC++ 2008)
            •    
            • Microsoft Visual Studio VC++ 1.52
            •    
            • NASM version 2.07 compiled on Jul 19 2009
            •    
            • gzip 1.2.4 Win32 (02 Dec 97)
            •    
            • ......

            配置TrueCrypt

            1. 下載MSVC++ 1.52,安裝在C盤下:C:\MSVC
            2. 下載NASM,也安裝在C盤下:C:\NASM
              http://www.nasm.us/pub/nasm/releasebuilds/2.07/win32/
            3. 下載GZIP,也安裝在C盤下:C:\gzip
            4. 下載并安裝WINDDK,http://www.microsoft.com/whdc/DevTools/WDK/WDKpkg.mspx
              我將它們安裝在D盤,路徑:D:\WinDDK
            5. 設置系統變量((WIN7)控制面板\所有控制面板項\系統\高級系統設置\環境變量):系統變量中,新增:
              變量1:MSVC16_ROOT    值:C:\MSVC
              變量2:WINDDK_ROOT    值:D:\WinDDK\7600.16385.0
              其中7600.16385.0為WinDDK的第二級目錄名,同時也是版本號,7600是Windows7的發行版本號。
              雙擊變量:PATH,在其值的末尾補上:C:\NASM;C:\gzip
              目的是為了讓我們可以直接在命令行實用nasm以及gzip作為命令行。
            6. 下載PKCS11,三個文件,右鍵另存為即可。
              http://svn.openvpn.net/projects/openvpn/test/time/openvpn/pkcs11-headers/
              將三個文件(pkcs11.h、pkcs11f.h、pkcs11t.h)拷貝到源碼下的Common文件夾下,我的源碼放在D盤根目錄,三個源碼我就放在“D:\TrueCrypt\Common”文件夾中。
            7. 編譯,會發現有兩個錯誤。
              CKR_NEW_PIN_MODE和CKR_NEXT_OTP未定義,補充定義一下即可。
              在d:\TrueCrypt\Common\pkcs11t.h文件里(請根據您自己的路徑進行復制)
              這里將它們設置為:
              #define CKR_NEW_PIN_MODE      0x000001B0
              #define CKR_NEXT_OTP          0x000001B1
              我的方法是找到實用它的語句附近的同類語句,找到相同的定義,在其下方添加。
              比如:
                          TC_TOKEN_ERR (CKR_MUTEX_NOT_LOCKED)
                          TC_TOKEN_ERR (CKR_NEW_PIN_MODE)
                          TC_TOKEN_ERR (CKR_NEXT_OTP)
              這三句話放在一起,后兩句有問題,但第一句正常,則查找CKR_MUTEX_NOT_LOCKED的存放位置,在其下方添加如上兩句,其中定義的值參考
              http://www.cryptsoft.com/pkcs11doc/STANDARD/include/v220/otp-pkcs11.h,這里的值只不過是一種錯誤碼,只要它不重復,就可以了。
            8. 再編譯,可能會遇到一些警告:
              1. nasm.exe正在停止,而因為沒有正確執行,又導致“fatal error LNK1136: invalid or corrupt file”錯誤。
                遇到這個可能是因為你的nasm正在試圖編譯ase_amdX64.asm文件,而nasm對64位的asm編譯對你可能意義不大,起碼對我而言是這樣的,于是,我就將它轉成編譯x86體系架構的,也許是因為參數配置的問題,你可以嘗試別的方案,如果有更好的話,請告訴我。
                這里我搜索:x64、asm等關鍵字,修改d:\TrueCrypt\Crypto\Makefile.inc文件為下面這樣即可:
                行1    !if "$(TC_ARCH)" == "x86"
                行2    TC_OBJ_FORMAT = win32
                行3    !else
                行4    #TC_OBJ_FORMAT = win64
                行5    #edit by gocool, if the x64 system need the nasm.exe use the x64 format parameters for executing.
                行6    #abort the x64 system here for building.
                行7    #2009/12/23
                行8    TC_OBJ_FORMAT = win32
                行9    TC_ARCH = x86
                行10    !endif
                行11   
                行12    "$(OBJ_PATH)\$(O)\Aes_$(TC_ARCH).obj": Aes_$(TC_ARCH).asm
                行13        nasm.exe -Xvc -f $(TC_OBJ_FORMAT) -Ox -D DLL_EXPORT -o "$@" -l "$(OBJ_PATH)\$(O)\Aes_$(TC_ARCH).lst" Aes_$(TC_ARCH).asm
                其中,為了減少變化量,也利于以后恢復,第4-7行為注釋,第8、9行我將非x86的情況也定義成x86的情況,這樣無論如何下面第13行的語句都將執行以x86體系為結構的設置,而這樣的設置通常是正確的。
              2. fatal error LNK1000: Internal error during IncrBuildImage
                據說是Microsoft Visual Studio 2008的一個BUG。http://blog.csdn.net/just_one_two/archive/2009/10/05/4634391.aspx
                聽說有兩種方法,一種是方法1,需要下載補丁,我沒有嘗試。第二種通過修改配置的方法我成功了,步驟如下:
                方法:項目->屬性->鏈接器->常規   下面的“啟用增量鏈接”,將“是(/INCREMENTAL)”改為“否(/INCREMENTAL:NO)”。
                不過這又引入了另外一個警告:3>FormatCom.obj : warning LNK4075: 忽略“/EDITANDCONTINUE”(由于“/INCREMENTAL:NO”規范)
                選擇項目,屬性->配置屬性->C/C++,修改“調試信息格式”為“程序數據庫(/Zi)”即可。
              3. 警告:未找到下列環境變量
                4>項目 : warning PRJ0018 : 未找到下列環境變量:
                4>$(PKCS11_INC)
                由于項目屬性里設置有附加包含目錄“$(PKCS11_INC)”,因此編譯的時候會在系統變量里尋找PKCS11_INC項目,如果找不到,則給出警告,因此,我們需要手動補充這個項。方法同步驟5,增加一個變量為PKCS11_INC,值:D:\TrueCrypt\Common,其中,值就是之前我們拷貝三個文件(pkcs11.h、pkcs11f.h、pkcs11t.h)的目錄。
              4. 如果不出意外的話,你可能還會得到一個使用了PKEY_AppUserModel_ID未定義的聲明符的錯誤。這個是用于標識用戶態應用程序的唯一標識。你可以在Setup.h文件中定義:
                /*---region add by gc---*/
                #include "wtypes.h"
                    const PROPERTYKEY PKEY_AppUserModel_ID = {
                        {
                            (unsigned long)2009,/*unsigned long  Data1;*/
                            (unsigned short)12,/*unsigned short Data2;*/
                            (unsigned short)23,/*unsigned short Data3;*/
                            0x44,0x55,0x55,0x55,0x55,0x55,0x55,0x55
                        },/*GUID fmtid;*/
                        (DWORD)PID_FIRST_USABLE /*DWORD pid;*/
                    };
                /*---endregion---*/
                其中,這個結構體是由GUID和PID共同組成的。

            下載鏈接

          1. TrueCrypt下載:http://www.sfr-fresh.com/windows/misc/TrueCrypt-6.2a-Source.zip:a/Boot/Windows/Makefile
          2. WinDDK下載:http://www.microsoft.com/whdc/DevTools/WDK/WDKpkg.mspx
          3. PKCS11下載:http://svn.openvpn.net/projects/openvpn/test/time/openvpn/pkcs11-headers/
          4. GZip下載:http://www.gzip.org/ 或者 http://www.gzip.org/gz124src.zip
          5. Nasm下載:http://www.nasm.us/pub/nasm/releasebuilds/2.07/win32/
          6. MSVC1.52下載:http://download.csdn.net/source/620960 (15.02MB)(似乎網上很多人都在找1.52(最后一個可以編譯16bit程序的VC編譯器),但官方網站上沒有公開下載的鏈接,實在非常郁悶,我從MSDN訂閱下載(收費的噢,杯具)則有67.6MB),如果大家實在找不到下載或者15.02MB的不可用,可以聯系我。

          7. 參考鏈接

            • http://blog.csdn.net/skyremember/archive/2009/09/17/4562090.aspx
            • http://blog.sina.com.cn/s/blog_4758691d0100d8mc.html
            • http://lll332.blog.163.com/blog/static/1553692220093404635752/
            • http://msdn.microsoft.com/en-us/library/aa373931%28VS.85%29.aspx
            • http://hi.baidu.com/hhacker/blog/item/2fc5b3fb0b24132a4f4aea1d.html
            • http://blog.csdn.net/just_one_two/archive/2009/10/05/4634391.aspx
            • http://blog.csdn.net/liufei_learning/archive/2009/12/21/5047632.aspx
            • http://msdn.microsoft.com/zh-cn/library/958x11bc%28VS.80%29.aspx
            • http://bbs.xiakexing.com/cgi-bin/topic.cgi?forum=22&topic=498

            posted @ 2009-12-23 23:47 volnet 閱讀(5911) | 評論 (10)編輯 收藏

            我的Linux小記(1)

            1、如何啟動命令行?
            答:GNOME環境下,按Alt+F2,在隨后出現的運行窗口中輸入:gnome-terminal,回車。如圖所示:

            2、如何以管理員權限運行命令?
            答:Ubuntu下:
            方法1:在命令行下,輸入su,在提示下輸入密碼(不會明文顯示),回車,接下來的命令都將以管理員權限運行。
            方法2:在命令行下,需要用到管理員權限運行的語句前加sudo(僅對單條語句有效),如果是當前命令行窗口下第一次用此命令,則需要輸入密碼,按提示輸入密碼,回車,之后只需要用sudo,將不再輸入密碼。
            3、如何在Ubuntu下禁用觸摸板?
            答:在命令行中(參考1、2),輸入以下命令,禁用觸摸板:
            sudo rmmod psmouse

             

            重新啟用,則在命令行下(Alt+F2啟動后輸入gnome-terminal),輸入以下命令,啟用觸摸板:
            sudo modprobe psmouse
            如圖所示:

            4、如何用head和tail命令?
            head命令用于顯示文件的前10行,而tail命令則用于顯示文件的后10行。
            支持的參數有:
            -c N:顯示前(后)N字節的內容
            -n N:顯示前(后)N行的內容
            5、如何用shell為文件重命名呢?
            在Linux中似乎沒有rename這樣一個方法,但是可以通過mv(移動文件)來為文件重命名:
            mv ./file-name1 ./file-name2
            通過在同級目錄下移動文件,并指定文件名即可為文件重命名。

            6、fortune命令
            聽說是個傳奇的命令,聽名字就是吧?那就試試,結果Ubuntu并沒有自帶,那么輸入下面語句安裝fortune。

            sudo apt-get install fortune-mod

            posted @ 2009-12-13 19:01 volnet 閱讀(664) | 評論 (0)編輯 收藏

            QuickSort快速排序法(2009-10-28)

            在本博客,之前有一個版本的QuickSort,其實網友很早就提出了相關的BUG,但是我一直沒有時間進行修正,今天又有朋友提出了這個BUG,我剛好抽空看了一下,看來自己是相當不嚴謹以至于犯下了如此大錯。

            原文鏈接:http://www.shnenglu.com/mymsdn/archive/2009/03/06/quicksort.aspx (未修復)

            關于修復BUG后的代碼,將在本文中提供,原文中不進行修改,但會有提示指明是錯誤的,有興趣的朋友也可以直接在原文的代碼中尋找錯誤來鍛煉自己排錯的能力。

            下面就是幾段代碼:

            Algorithms.cpp

            #include "StdAfx.h"
            #include "Algorithms.h"
            Algorithms::Algorithms(void)
            {
            }
            
            Algorithms::~Algorithms(void)
            {
            }
            

            Algorithms.h

            #pragma once
            
            #include <iostream>
            
            class Algorithms
            {
            public:
                Algorithms(void);
                ~Algorithms(void);
            
            public:
                template <typename T>
                static void QuickSort(T* arr, size_t min, size_t max);
            private:
                template <typename T>
                static size_t qsort_helper_partition(T* arr, size_t min, size_t max);
                template <typename T>
                static inline void swap(T* arr, size_t x, size_t y);
                // helper
                template <typename T>
                static inline void helper_show_all(T* arr, size_t min, size_t max, char *msg);
            };
            
            template <typename T>
            void Algorithms::QuickSort(T* arr, size_t min, size_t max)
            {
                if(min >= max || max == 0 - 1) return;
                helper_show_all(arr, min, max, "before qsort_helper_partition");
                size_t p = qsort_helper_partition(arr, min, max);
                helper_show_all(arr, min, max, "after qsort_helper_partition");
            
                QuickSort(arr, min, p - 1);
                QuickSort(arr, p + 1, max);
            }
            /*
            *    @BUG:    bug200910280001
            *    @DESC:    由于在循環while(true)中,假設原代碼
                        01    while(true)
                        02    {
                        03        while(cmp < arr[i])
                        04            ++i;
                        05        while(arr[j] < cmp)
                        06            --j;
                        07        if(i >= j) break;
                        08
                        09        swap(arr, i, j);
                        10    }
                        中,前兩段(行號,行號)中的代碼均返回false,
                        則無法進入++i或者--j,那么在這個while(true)中,
                        i和j的值將無法發生變化,從而導致死循環。
                @LINK:http://www.shnenglu.com/mymsdn/archive/2009/03/06/quicksort.aspx#99606
            */
            template <typename T>
            size_t Algorithms::qsort_helper_partition(T* arr, size_t min, size_t max)
            {
                T cmp = arr[min];
                int i = min, j = max; // bug200910280001:修正i = min+1,將+1的動作放在循環內。
                while(true)
                {
                    while(cmp < arr[++i]) // bug200910280001:將原本在循環外的min+1,移進循環內,并首先+1
                        ; // bug200910280001:將++1移至while條件中。
                    while(arr[j] < cmp)
                        --j;
                    if(i >= j) break;
            
                    helper_show_all(arr, min, max, "before swap(arr, i, j)");
                    swap(arr, i, j);
                    helper_show_all(arr, min, max, "after swap(arr, i, j)");
                }
                swap(arr, min, j);
                return j;
            }
            
            template <typename T>
            void Algorithms::swap(T* arr, size_t x, size_t y)
            {
                T tmp = arr[x];
                arr[x] = arr[y];
                arr[y] = tmp;
            }
            
            template <typename T>
            void Algorithms::helper_show_all(T* arr, size_t min, size_t max, char *msg)
            {
                std::cout << "current array :\t";
                for(int i = min; i < max; ++i)
                {
                    std::cout << arr[i] << " ";
                }
                std::cout<<"\t//"<<msg;
                std::cout<<std::endl;
            }

            cpp_quickSort.cpp

            // cpp_quickSort.cpp : 定義控制臺應用程序的入口點。
            //
            
            #include "stdafx.h"
            #include "Algorithms.h"
            #include <iostream>
            #include <vector>
            #include <algorithm>
            
            int _tmain(int argc, _TCHAR* argv[])
            {
                int arr_begin = 0;
                int arr_length = 12; //The length will instead of the magic numbers 
                int arr[] = {8, 3, 7, 1, 5, 6, 2, 1, 9, 9, 1, 1};
                
                // Test for : 20091028bug0001
                // int arr[] = {1, 1, 1};
            
                std::cout << "input array :\t";
                for(size_t i = arr_begin; i != arr_length; ++i)
                {
                    std::cout<<arr[i]<<" ";
                }
                std::cout<<std::endl;
            
                Algorithms::QuickSort(arr, arr_begin, arr_length);
            
                std::cout << "result array :\t";
                for(size_t i = arr_begin; i != arr_length; ++i)
                {
                    std::cout<<arr[i]<<" ";
                }
                std::cout<<std::endl;
            
                std::cout << "--------------------" << std::endl;
                std::cout << "input array :\t";
            
                std::vector<int> vec;
                vec.push_back(3);
                vec.push_back(1);
                vec.push_back(4);
                vec.push_back(1);
                vec.push_back(7);
                vec.push_back(6);
            
                for(std::vector<int>::iterator iter = vec.begin();
                    iter != vec.end(); ++ iter)
                {
                    std::cout<<*iter<<" ";
                }
                std::cout<<std::endl;
            
                std::sort(vec.begin(), vec.end());
            
                for(std::vector<int>::iterator iter = vec.begin();
                    iter != vec.end(); ++ iter)
                {
                    std::cout<<*iter<<" ";
                }
                std::cout<<std::endl;
            
                return 0;
            }
            
            

            posted @ 2009-10-28 00:38 volnet 閱讀(1227) | 評論 (0)編輯 收藏

            僅列出標題
            共9頁: 1 2 3 4 5 6 7 8 9 
            特殊功能
             
            久久综合亚洲色HEZYO社区 | 久久久久免费精品国产| 精品无码久久久久国产动漫3d| 久久综合色之久久综合| 久久久久亚洲精品男人的天堂| 四虎国产精品免费久久久| 久久AAAA片一区二区| 精品久久久久久国产牛牛app| 国产精品永久久久久久久久久| 狠狠精品久久久无码中文字幕 | 72种姿势欧美久久久久大黄蕉| 日韩精品久久无码人妻中文字幕| 久久亚洲中文字幕精品有坂深雪 | 亚洲中文字幕无码久久精品1| 久久99久久99精品免视看动漫 | 久久久久久久97| 精品久久久久久无码专区不卡| 久久香蕉国产线看观看99| 精品人妻伦一二三区久久 | 国产精品美女久久久久AV福利| 久久99精品免费一区二区| 久久人做人爽一区二区三区| 国产情侣久久久久aⅴ免费| 99热成人精品免费久久| 久久久久久久97| 亚洲国产精品热久久| 午夜精品久久久久| 久久99中文字幕久久| 热久久视久久精品18| 久久99国产精品久久久| 欧美激情一区二区久久久| 久久青青草原精品影院| 中文字幕久久亚洲一区| 国产成人香蕉久久久久| 国产精品久久久久久五月尺| 久久综合九色综合97_久久久| 久久久久亚洲AV无码观看| 激情五月综合综合久久69| 久久99精品国产自在现线小黄鸭 | 麻豆av久久av盛宴av| 久久精品国产亚洲5555|