. -- () , -- 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++ .
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
. , , () .
readsome()
, ...
.. readsome()
, :
27.6.1.3 [lib.istream.unformatted]
streamsize readsome(char_type* s, streamsize n);
!good()
setstate(failbit)
, . , s
. rdbuf()->in_avail() == -1
, setstate(eofbit)
( ios_base::failure
(27.4.4.3)) ;
rdbuf()->in_avail() == 0
,
rdbuf()->in_avail() > 0
, min(rdbuf()->in_avail(),n))
, , .. . , Circle
Ellipse
, is-a: . , .
, , : a
b
. . , , .. . -- , , . , , .. , .
? , , .. . , (, , b
-- ). , , (), .. , , .
.. 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; |
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]
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
.
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); }:
get_new1
--- -, template
. , f
Allocator
, -- () (m.get_new1) < int...
get_new2
-- -, f
, template
.
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
.
p3=template get_new3<int>(m);, ,
template
C++.
? ? ? , . , :
, , -- ! ? , ; . ? .
, "" , .. . -- "". , . , , . , -- . , -- . , , ( : (!) - UPDATE STATISTICS
; , SQL- . " " ).
, . , . - . "" SQL- , , , . "" .
, .. ( , ). ""- ( , . , ) " " (, , int
, ). -- .
, . ? . , , , :
, ( : 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++, .
, ?
_VAL_
, :
#define _VAL_(var) #var "=" << var << " ", ( ) , . .
_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>"
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_
.
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++ .
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; // ..., .
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&)
.
.