. -- () , -- 1, 2 3, workc(), workcpp() work3() . , .. .

work3() File. "" - C -- FILE*. , workc() work3(), , , .

: .

? ! ( ) 11 !!!

, .

C getc() :

#define getc(f) ((--((f)->level) >= 0) ? (unsigned char)(*(f)->curp++) : _fgetc (f))
.. . -- -. C++ , : - , - ?!

: -- ! , ?

void workc(char* fn)
{
 // ...

 if (setvbuf(fil, 0, _IOFBF, LARGE_BUFSIZ)) return;

 // ...
}

void workcpp(char* fn)
{
 // ...

 char* buf=new char[LARGE_BUFSIZ];
 fil.rdbuf()->pubsetbuf(buf, LARGE_BUFSIZ);

 // ...

 delete [] buf;
}
, ! , , ( , ).

, , . , . , .. .

, , - , C++ .


.701: 21.4.6.3. ,

- , . , - . , , , ...printf() . ? dd.mm.yyyy:
int day= 31,
    mon= 1,
    year=1974;

printf("%02d.%02d.%d\n", day, mon, year);  // 31.01.1974

cout<<setfill('0')<<setw(2)<<day<<'.'<<setw(2)<<mon<<setfill(' ')<<'.'
    <<year<<"\n";  //  31.01.1974
, .

C C++ ? C++ -- . .. C++ , , , , ...printf(). :

cout<<c_form(day,"02")<<'.'<<c_form(mon,"02")<<'.'<<year<<'\n';
:
#include <ostream>

/**     c_form,    */
namespace c_form_private {

 typedef std::ios_base::fmtflags fmtflags;
 typedef std::ostream ostream;
 typedef std::ios_base ios;

 /**
  *     .
  */
 class Formatter {
       /**    */
       fmtflags newFlags;
       /**  */
       int width;
       /**  */
       int prec;
       /** - */
       char fill;
       /**   */
       fmtflags oldFlags;

  public:
       /**
        *  ,   .
        */
       Formatter(const char* form, int arg1, int arg2);

       /**
        *      , 
        * .
        */
       void setFormatting(ostream& os);

       /**
        *   ,   
        * setFormatting().
        */
       void restoreFormatting(ostream& os);
 };

 /**
  *  .
  */
 template <class T>
 class Helper {
       /**   */
       const T& val;
       /**    */
       mutable Formatter fmtr;

  public:
       /**
        *     .
        */
       Helper(const T& val_, const char* form, int arg1, int arg2) :
         val(val_), fmtr(form, arg1, arg2) {}

       /**
        *          .
        */
       void putTo(ostream& os) const;
 };

 template <class T>
 void Helper<T>::putTo(ostream& os) const
 {
  fmtr.setFormatting(os);
  os<<val;
  fmtr.restoreFormatting(os);
 }

 /**
  *     Helper  .
  */
 template <class T>
 inline ostream& operator<<(ostream& os, const Helper<T>& h)
 {
  h.putTo(os);
  return os;
 }
}

/**
 * -,    , 
 *      ostream.  
 *      .
 * @param val   
 * @param form  : [-|0] [|*] [.(|*)] [e|f|g|o|x]
 * @param arg1  ,    .
 * @param arg2  ,  .
 * @throws std::invalid_argument    form 
 *         .
 */
template <class T>
inline c_form_private::Helper<T> c_form(const T& val, const char* form,
  int arg1=0, int arg2=0)
{
 return c_form_private::Helper<T>(val, form, arg1, arg2);
}
-:
#include "c_form.hpp"
#include <stdexcept>
#include <cctype>

namespace {

 /**
  *      .
  */
 int getval(const char*& iptr)
 {
  int ret=0;
  do ret=ret*10 + *iptr-'0';
     while (std::isdigit(*++iptr));

  return ret;
 }

}

c_form_private::Formatter::Formatter(const char* form, int arg1, int arg2) :
  newFlags(fmtflags()), width(0), prec(0), fill(0)
{
 const char* iptr=form;  //    

 if (*iptr=='-') {  //  
    newFlags|=ios::left;
    iptr++;
 }
 else if (*iptr=='0') {  //  '0'   !left
         fill='0';
         iptr++;
      }

 if (*iptr=='*') {  //  ,  
    width=arg1;
    iptr++;

    arg1=arg2;  //   
 }
 else if (std::isdigit(*iptr)) width=getval(iptr);

 if (*iptr=='.') {  //  
    if (*++iptr=='*') {
       prec=arg1;
       iptr++;
    }
    else if (std::isdigit(*iptr)) prec=getval(iptr);
         else throw std::invalid_argument("c_form");
 }

 switch (*iptr++) {
        case   0: return;  //   
        case 'e': newFlags|=ios::scientific; break;
        case 'f': newFlags|=ios::fixed;      break;
        case 'g':                            break;
        case 'o': newFlags|=ios::oct;        break;
        case 'x': newFlags|=ios::hex;        break;
        default: throw std::invalid_argument("c_form");
 }

 if (*iptr) throw std::invalid_argument("c_form");
}

void c_form_private::Formatter::setFormatting(ostream& os)
{
 oldFlags=os.flags();
 //  floatfield    
 os.flags((oldFlags & ~ios::floatfield) | newFlags);

 if (width) os.width(width);
 if (fill)  fill=os.fill(fill);
 if (prec)  prec=os.precision(prec);
}

void c_form_private::Formatter::restoreFormatting(ostream& os)
{
 os.flags(oldFlags);

 if (fill) os.fill(fill);
 if (prec) os.precision(prec);
}
: c_form<>() c_form_private::Helper<>, ostream.

, c_form<>() , .. - c_form<>, :

cout<<c_form<int>(day,"02");
, , . . , , Formatter, Helper<>, ( ) .

, c_form . , , () .


.711: 21.6.2.

readsome() , ...

.. readsome() , :

27.6.1.3 [lib.istream.unformatted]

streamsize readsome(char_type* s, streamsize n);
  1. : !good() setstate(failbit), . , s. rdbuf()->in_avail() == -1, setstate(eofbit) ( ios_base::failure (27.4.4.3)) ;
  2. : .

.773: 23.4.3.1. 1:

, -- , , .

, , .. . , Circle Ellipse , is-a: . , .

, , : a b. . , , .. . -- , , . , , .. , .

? , , .. . , (, , b -- ). , , (), .. , , .


.879: .5.

" , ".

.. C++ , . :

T(*e)(int(3)); T* e(int(3)); , int , : .
T(f)[4]; T f[4];
T(a); T a;
T(a)=m; T a=m;
T(*b)(); .
T(x),y,z=7; T x,y,z=7;


.931: B.13.2.

:
template<class C> class Basic_ops {  //    
	friend bool operator==<>(const C&, const C&);  //  
	friend bool operator!=<>(const C&, const C&);
	// ...
};
(<>) , - ( ).

10 .

<>? operator==() , .. operator==()-. :

14.5.3. [temp.friend]

  1. - -, -, ( ) . - : :
    template<class T> class task;
    template<class T> task<T>* preempt(task<T>*);
    
    template<class T> class task {
    	//  ...
    	friend void next_time();
    	friend void process(task<T>*);
    	friend task<T>* preempt<T>(task<T>*);
    	template<class C> friend int func(C);
    
    	friend class task<int>;
    	template<class P> friend class frd;
    	//  ...
    };
    next_time - task; .. process template-arguments, - task - process -; .. preempt template-argument <T>, - task - preempt; , , - task - func. , - task - task<int>, - frd.

.935: B.13.6. template

.

- - . , - -? :

template <class T> void get_new3();  // (1)

template <class Allocator>
void f(Allocator& m)
{
 int* p1=         m.template get_new1<int>( );
 int* p2=Allocator::template get_new2<int>(m);
 int* p3=                    get_new3<int>(m);
}

struct Alloc {
       template <class T>
       T* get_new1() { return 0; }

       template <class T>
       static T* get_new2(Alloc&) { return 0; }

       template <class T>
       friend T* get_new3(Alloc&) { return 0; }
};

int main()
{
 Alloc a;
 f(a);
}
:
  1. get_new1 --- -, template. , f Allocator , -- () (m.get_new1) < int...
  2. get_new2 -- -, f, template .
  3. get_new3 -- Alloc, . , f Alloc ( , get_new1 get_new2). f , , get_new3 f -. f, (1) get_new3 -- Alloc, ( !) - get_new3. , f --
    p3=get_new3<int>(m);
    , -. , (1) get_new3 . , ( ) get_new3, f.
, - , .. C++ , , :
p3=template get_new3<int>(m);
, , template C++.

.

? ? ? , . , :

  1. , .
  2. .
: . -- .

, , -- ! ? , ; . ? .

, "" , .. . -- "". , . , , . , -- . , -- . , , ( : (!) - UPDATE STATISTICS; , SQL- . " " ).

, . , . - . "" SQL- , , , . "" .

, .. ( , ). ""- ( , . , ) " " (, , int, ). -- .

, . ? . , , , :

, , . , , ( , ) (, ; , ; , ; -- blue death screen, system trap .., .. ).

, ( : a+a 2*a, register int i; ..), ( , " " ). .

( O(N*N), O(N*log(N)) O(N*M) ). ! , , , . , "" !

, . . , , -. , . , , sin(x), ( 360 int ). "" -- switch . , ( O(1)) ( O(log(N))) -- O(N), switch. switch .

. C++.

, , - C++ , . , " ", .. () C++, .

C++ C . .. , , , . ( _fastcall), , . :

void f1(int arg)
{
 Var+=arg;
}

void _fastcall f2(int arg)
{
 Var+=arg;
}
f1() 50% . , . .

-- . ? , -- , , 90% ! , , , . .

( ), , . , . - ? f() file1.cpp g() file2.cpp, , , file2.cpp . , , file2.cpp - g2(), g() - ; -... , , .

Paul Hsieh "Programming Optimization". , "", , , Steve Heller "Optimizing C++".


C++ ! , ? : , .

, , . , C++, .

, ?

  1. . , _VAL_, :
    #define _VAL_(var) #var "=" << var << " "
    , ( ) , . .
  2. -- . _ADD_. :
    	cout<<_ADD_(" ");
    -
      <file.cpp:34>
    ,
    	cout<<" " _ADD_("") "\n";
    , _ADD_ .
    	char* _ADD_(char*);
    , . , cout , .

    _ADD_:

    #define _ADD_tmp_tmp_(str,arg) str " <" __FILE__ ":" #arg ">"
    #define _ADD_tmp_(str,arg) _ADD_tmp_tmp_(str,arg)
    #define _ADD_(str) _ADD_tmp_(str,__LINE__)
    ? , __LINE__ __FILE__ , . , , :
    #define _ADD_(str) str " <" __FILE__ ":" #__LINE__ ">"
    .. # . __LINE__ ,
    #define _ADD_tmp_(str,arg) str " <" __FILE__ ":" #arg ">"
    #define _ADD_(str) _ADD_tmp_(str,__LINE__)
    : _ADD_(" ")
    "  <file.cpp:__LINE__>"
    . , : _ADD_(" ")
    _ADD_tmp_(" ",__LINE__)
    _ADD_tmp_tmp_(" ",34)
    " " " <" "file.cpp" ":" "34" ">"
    "  <file.cpp:34>"
  3. . , "" . , SQL- DB::Query
    void DB::Query::Statement(const char *);
    , " " somefield:
    #define FieldOK 7
    // ...
    DB::Int tmp(FieldOK);
    q.Statement(" SELECT * "
                " FROM sometable "
                " WHERE somefield=? "
    );
    q.SetParam(), tmp;
    . FieldOK ? :
    #define FieldOK 7
    // ...
    #define FieldOK_CHAR "7"
    // ...
    q.Statement(" SELECT * "
                " FROM sometable "
                " WHERE somefield=" FieldOK_CHAR
    );
    .
    #define FieldOK 7
    // ...
    q.Statement(" SELECT * "
                " FROM sometable "
                " WHERE somefield=" _GETSTR_(FieldOK)
    );
    _GETSTR_ :
    #define _GETSTR_(arg) #arg
    , C++
    const int FieldOK=7;
    enum { FieldOK=7 };
    _GETSTR_ .
  4. . SQL-. , . :
    struct Table1 {  //   
           DB::Date  Field1;
           DB::Int   Field2;
           DB::Short Field3;
    };
    
    void f()
    {
     Table1 tbl;
     DB::Query q;
     q.Statement(" SELECT Field1, Field2, Field3 "
                 " FROM Table1 "
     );
     q.BindCol(), tbl.Field1, tbl.Field2, tbl.Field3;
     // ...
    }
    . , ? -- ! :
    #define TABLE1_FLD      Field1, Field2, Field3
    #define TABLE1_FLD_CHAR "Field1, Field2, Field3"
    
    struct Table1 {  //   
           DB::Date  Field1;
           DB::Int   Field2;
           DB::Short Field3;
    
           //  
           void BindCol(DB::Query& q) { q.BindCol(), TABLE1_FLD; }
    };
    
    void f()
    {
     Table1 tbl;
     DB::Query q;
     q.Statement(" SELECT " TABLE1_FLD_CHAR
                 " FROM Table1 "
     );
     tbl.BindCol(q);
     // ...
    }
    . , TABLE1_FLD_CHAR _GETSTR_(TABLE1_FLD), .. TABLE1_FLD . , C++ .
  5. . , . , , , , :
    q.Statement(" SELECT Field1, AccA_bal, AccA_cur, AccA_key, AccA_brn, "
                " AccA_per, Field2 "
                " FROM Table1 "
    );
    q.BindCol(), tbl.Field1, tbl.AccA.bal, tbl.AccA.cur, tbl.AccA.key,
                 tbl.AccA.brn, tbl.AccA.per, tbl.Field2;
    // ...
    , (tbl.AccA, tbl.AccB, tbl.KorA, tbl.KorB). :
    #define _SACC_(arg) #arg"_bal, "#arg"_cur, "#arg"_key, "#arg"_brn, " \
                        #arg"_per "
    #define _BACC_(arg) arg.bal, arg.cur, arg.key, arg.brn, arg.per
    
    // ...
    
    q.Statement(" SELECT Field1, " _SACC_(AccA) " , Field2 "
                " FROM Table1 "
    );
    q.BindCol(), tbl.Field1, _BACC_(tbl.AccA), tbl.Field2;
    // ...
    , .
  6. . :
    struct A {
           MyDate Date;
           int    Field2;
           short  Field3;
    };
    Date , .. DATE SQL. :
    struct TableA {
           DB::Date  xDate;
           DB::Int   xField2;
           DB::Short xField3;
    
           TableA& operator=(A&);
           void Clear();
    };
    -:
    TableA& TableA::operator=(A& a)
    {
     xDate=ToDB(a.Date);
     xField2=ToDB(a.Field2);
     xField3=ToDB(a.Field3);
    
     return *this;
    }
    
    void TableA::Clear()
    {
     xDate="";
     xField2="";
     xField3="";
    }
    , TableA - , , ! , ? :
    TableA& TableA::operator=(A& a)
    {
    //   : ##
    #define ASS(arg) x##arg=ToDB(a.arg);
     ASS(Date);
     ASS(Field2);
     ASS(Field3);
    #undef ASS
    
     return *this;
    }
    
    void TableA::Clear()
    {
    #define CLR(arg) x##arg=""
     CLR(Date);
     CLR(Field2);
     CLR(Field3);
    #undef CLR
    }
    TableA::Clear() TableA::operator=() , , , . : A& A::operator=(TableA&).
, - C++.
Copyright © . , 2000-2004

.