. -- () , -- 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&).
.