自分自身について
私自身はC ++プログラマーです。むしろ、私は初心者であり、商業的な経験はありません。当初、私はC言語に精通し、C言語の強力な拡張機能としてC ++を発見しました。私の意見では、Cにはない必要な便利なもの(関数のオーバーロード、クラス、名前空間など)が追加されています。 、これらのものは哲学言語を完全に拡張しますが
アイデア
C 2011 "" . (Generic selection) , - ,
: () print
, . , , . C11
, . , :
. . , , :
,
" ",
:
__VA_ARGS__
__VA_OPT__
VA_ARGS
VA_OPT.
__LINE__ __FILE__
:
\
, . 20 5 ,
&
&
,<
<
-
-
, ( 700) . . -
, , . , . ! :) png
print(x)
int, float
char*
(cstring):
void print_int(int x) {printf("%d ", x); }
void print_float(float x) {printf("%.4f ", x); }
void print_string(char* x) {printf("%s ", x); }
print
:
#define print(x) _Generic((X),\
int: print_int,\
float: print_float,\
char*: print_string)\
(x)
, print("hi")
print_string("hi")
, print(5.5)
print_float(5.5)
print("hi")
_Generic(("hi"), int: print_int, float: print_float, char*: print_string)("hi"),
, _Generic(...)
. print_int
void print_int(int n, ...)
{
va_list argptr;
va_start(argptr, n);
int x;
for (int i = 0; i < n; i++)
{
x = va_arg(argptr, int);
printf("%d ", x);
}
va_end(argptr);
}
, :) n
,
PP_NARG(...),
#ifndef PP_NARG
/*
*
* The PP_NARG macro returns the number of arguments that have been
* passed to it.
*
* https://groups.google.com/g/comp.std.c/c/d-6Mj5Lko_s
*
*/
#define PP_NARG(...) \
PP_NARG_(__VA_ARGS__,PP_RSEQ_N())
#define PP_NARG_(...) \
PP_ARG_N(__VA_ARGS__)
#define PP_ARG_N( \
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
_31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
_41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
_51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
_61,_62,_63, N, ...) N
#define PP_RSEQ_N() \
63,62,61,60, \
59,58,57,56,55,54,53,52,51,50, \
49,48,47,46,45,44,43,42,41,40, \
39,38,37,36,35,34,33,32,31,30, \
29,28,27,26,25,24,23,22,21,20, \
19,18,17,16,15,14,13,12,11,10, \
9,8,7,6,5,4,3,2,1,0
#endif
#define print(...) print_int(PP_NARG(__VA_ARGS__), __VA_ARGS__)
: __VA_ARGS__
, ...
, ,
#define function(x, ...) Generic((x),\
int: function_int,\
float: function_float,\
char*: function_string)\
(PP_NARG(__VA_ARGS__) + 1, x, __VA_ARGS__)
function
, . function
, print
, . , , ,
I.
( ) hidden_print(sep, n, x1, x2, x3, ...),
xi
printf.
12. print
' .
cool
. - , , , , . c++ cool
, , . #define print cool_print
, #undef print
cool_hidden_types[12]
, cool_hidden_last
, cool_hidden_add_int
, cool_hidden_add_float
.. , . 7 : int, char*, float, double, char (?), uint, long
char (?)
- _Generic(('a'), char: fun_char)()
- " int
", int
#define
, enum
. , !
#define COOL_HIDDEN_INT 0
#define COOL_HIDDEN_STRING 1
#define COOL_HIDDEN_FLOAT 2
#define COOL_HIDDEN_DOUBLE 3
#define COOL_HIDDEN_CHAR 4
#define COOL_HIDDEN_UINT 5
#define COOL_HIDDEN_LONG 6
#define COOL_HIDDEN_VOID 7
int cool_hidden_types[12];
int cool_hidden_last = 0;
void cool_hidden_add_int()
{
cool_hidden_types[cool_hidden_last] = COOL_HIDDEN_INT;
cool_hidden_last += 1;
}
void cool_hidden_add_string()
{
cool_hidden_types[cool_hidden_last] = COOL_HIDDEN_STRING;
cool_hidden_last += 1;
}
/* */
void cool_hidden_add_void()
{
cool_hidden_types[cool_hidden_last] = COOL_HIDDEN_VOID;
cool_hidden_last += 1;
}
COOL_HIDDEN_VOID
, . 16- ,
generic cool_hidden_add(x)
, x
#define cool_hidden_add(x) \
_Generic((x), \
int: cool_hidden_add_int, \
char*: cool_hidden_add_string, \
float: cool_hidden_add_float, \
double: cool_hidden_add_double, \
char: cool_hidden_add_char, \
unsigned int: cool_hidden_add_uint, \
long: cool_hidden_add_long, \
default: cool_hidden_add_void \
)()
...
II.
, cool_print##n(x1, x2, ..., xn)
("##" n
), xi
, cool_hidden_print(sep, n, x1, x2, ...)
, n
, xi
. ( ) cool_print_sep = " "
,
. , . ( visual studio , , )
:
#define cool_print_n(x1, x2, x3, x4, ..., xn, ...)\
cool_hidden_add(x1);\
cool_hidden_add(x2);\
cool_hidden_add(x3);\
cool_hidden_add(x4);\
................... \
cool_hidden_add(xn);\
cool_hidden_print(cool_print_sep, n, x1, x2, x3, x4, ..., xn)
//hide this a big part of code
#if 1
#define cool_print_12(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, ...) \
cool_hidden_add(x1); \
cool_hidden_add(x2); \
cool_hidden_add(x3); \
cool_hidden_add(x4); \
cool_hidden_add(x5); \
cool_hidden_add(x6); \
cool_hidden_add(x7); \
cool_hidden_add(x8); \
cool_hidden_add(x9); \
cool_hidden_add(x10); \
cool_hidden_add(x11); \
cool_hidden_add(x12); \
cool_hidden_print(cool_print_sep, 12, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12)
#define cool_print_11(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, ...) \
cool_hidden_add(x1); \
cool_hidden_add(x2); \
cool_hidden_add(x3); \
cool_hidden_add(x4); \
cool_hidden_add(x5); \
cool_hidden_add(x6); \
cool_hidden_add(x7); \
cool_hidden_add(x8); \
cool_hidden_add(x9); \
cool_hidden_add(x10); \
cool_hidden_add(x11); \
cool_hidden_print(cool_print_sep, 11, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11)
#define cool_print_10(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, ...) \
cool_hidden_add(x1); \
cool_hidden_add(x2); \
cool_hidden_add(x3); \
cool_hidden_add(x4); \
cool_hidden_add(x5); \
cool_hidden_add(x6); \
cool_hidden_add(x7); \
cool_hidden_add(x8); \
cool_hidden_add(x9); \
cool_hidden_add(x10); \
cool_hidden_print(cool_print_sep, 10, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10)
#define cool_print_9(x1, x2, x3, x4, x5, x6, x7, x8, x9, ...) \
cool_hidden_add(x1); \
cool_hidden_add(x2); \
cool_hidden_add(x3); \
cool_hidden_add(x4); \
cool_hidden_add(x5); \
cool_hidden_add(x6); \
cool_hidden_add(x7); \
cool_hidden_add(x8); \
cool_hidden_add(x9); \
cool_hidden_print(cool_print_sep, 9, x1, x2, x3, x4, x5, x6, x7, x8, x9)
#define cool_print_8(x1, x2, x3, x4, x5, x6, x7, x8, ...) \
cool_hidden_add(x1); \
cool_hidden_add(x2); \
cool_hidden_add(x3); \
cool_hidden_add(x4); \
cool_hidden_add(x5); \
cool_hidden_add(x6); \
cool_hidden_add(x7); \
cool_hidden_add(x8); \
cool_hidden_print(cool_print_sep, 8, x1, x2, x3, x4, x5, x6, x7, x8)
#define cool_print_7(x1, x2, x3, x4, x5, x6, x7, ...) \
cool_hidden_add(x1); \
cool_hidden_add(x2); \
cool_hidden_add(x3); \
cool_hidden_add(x4); \
cool_hidden_add(x5); \
cool_hidden_add(x6); \
cool_hidden_add(x7); \
cool_hidden_print(cool_print_sep, 7, x1, x2, x3, x4, x5, x6, x7)
#define cool_print_6(x1, x2, x3, x4, x5, x6, ...) \
cool_hidden_add(x1); \
cool_hidden_add(x2); \
cool_hidden_add(x3); \
cool_hidden_add(x4); \
cool_hidden_add(x5); \
cool_hidden_add(x6); \
cool_hidden_print(cool_print_sep, 6, x1, x2, x3, x4, x5, x6)
#define cool_print_5(x1, x2, x3, x4, x5, ...) \
cool_hidden_add(x1); \
cool_hidden_add(x2); \
cool_hidden_add(x3); \
cool_hidden_add(x4); \
cool_hidden_add(x5); \
cool_hidden_print(cool_print_sep, 5, x1, x2, x3, x4, x5)
#define cool_print_4(x1, x2, x3, x4, ...) \
cool_hidden_add(x1); \
cool_hidden_add(x2); \
cool_hidden_add(x3); \
cool_hidden_add(x4); \
cool_hidden_print(cool_print_sep, 4, x1, x2, x3, x4)
#define cool_print_3(x1, x2, x3, ...) \
cool_hidden_add(x1); \
cool_hidden_add(x2); \
cool_hidden_add(x3); \
cool_hidden_print(cool_print_sep, 3, x1, x2, x3)
#define cool_print_2(x1, x2, ...) \
cool_hidden_add(x1); \
cool_hidden_add(x2); \
cool_hidden_print(cool_print_sep, 2, x1, x2)
#define cool_print_1(x, ...) \
cool_hidden_add(x); \
cool_hidden_print(cool_print_sep, 1, x)
#endif //hide this a big part of code
, cool_print_n
12, ...
,
PP_NARG(__VA_ARGS__
) cool_print_##PP_NARG(__VA_ARGS__)
, - cool_print_PP_NARG("x", 5, "i", 8,),
. , ,
PP_NARG(__VA_ARGS__)
#ifndef PP_NARG
/*
*
* The PP_NARG macro returns the number of arguments that have been
* passed to it.
*
* https://groups.google.com/g/comp.std.c/c/d-6Mj5Lko_s
*
*/
#define PP_NARG(...) \
PP_NARG_(__VA_ARGS__,PP_RSEQ_N())
#define PP_NARG_(...) \
PP_ARG_N(__VA_ARGS__)
#define PP_ARG_N( \
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
_31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
_41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
_51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
_61,_62,_63, N, ...) N
#define PP_RSEQ_N() \
63,62,61,60, \
59,58,57,56,55,54,53,52,51,50, \
49,48,47,46,45,44,43,42,41,40, \
39,38,37,36,35,34,33,32,31,30, \
29,28,27,26,25,24,23,22,21,20, \
19,18,17,16,15,14,13,12,11,10, \
9,8,7,6,5,4,3,2,1,0
#endif
cool_print(...) - PP_NARG,
#define cool_print(...) \
cool_print_(__VA_ARGS__ , COOL_RSEQ_N())
#define cool_print_(...) \
COOL_ARG_N(__VA_ARGS__)
#define COOL_ARG_N( \
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
_41,_42,_43,_44,_45,_46,_47,_48,_49,_50, _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
_61,_62,_63, n, ...) \
\
cool_print_##n(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11,_12)
#define COOL_RSEQ_N() \
63,62,61,60,59,58,57,56,55,54,53,52,51,50, \
49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30, \
29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10, \
9,8,7,6,5,4,3,2,1,0
:
1. cool_print("a", 4, "b")
2. cool_print_("a", 4, "b",
63,62,61,60,59,58,57,56,55,54,
53,52,51,50,49,48,47,46,45,44,43,
42,41,40,39,38,37,36,35,34,33,32,
31,30,29,28,27,26,25,24,23,22,21,
20,19,18,17,16,15,14,13,12,11,10,
9,8,7,6,5,4,3,2,1,0
3. cool_print_ COOL_ARG_N,
64 . 64- , n
- ,
VA_ARGS COOL_RSEQ_N
(63..0)
4. COOL_ARG_N
cool_print_##n .
cool_print_3
cool_print_3("a", 4, "b",
63,62,61,60,59,58,57,56,55,54,53,52,51,50,
49,48,47,46,45,44,43,42,41,40,39,38,37,36,
35,34,33,32,31,30,29,28,27,26,25,24,23,22,
21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3)
12 , .
, "..."
cool_print_##n
64 12,
III.
, cool_print("", "", 10)
cool_hidden_types
, cool_hidden_print(int sep, int n, ...)
!
C
<stdarg.h>
, . :
...
va_list argptr
-argptr
,
va_start(argptr, n)
-
va_arg(argptr, float)
-
va_end(argptr)
-
- ,
: . swich'e void' x, printf("...%s", *((type) x), sep)
, type
- , "..." - . int
printf("%d%s", *((type) x), sep)
. #define COOL_CAST(T, x) ((T) (x))
cool_hidden_print(sep, n, ...)
#define COOL_CAST(T, x) ((T) (x))
void cool_hidden_print(char* sep, int n, ...)
{
va_list argptr;
va_start(argptr, n);
void* x;
for (int i = 0; i < n; i++)
{
switch (cool_hidden_types[i])
{
case COOL_HIDDEN_INT:
x = &va_arg(argptr, int);
printf("%d%s", COOL_CAST(int, x), sep);
break;
case COOL_HIDDEN_STRING:
x = &va_arg(argptr, char*);
printf("%s%s", COOL_CAST(char*, x) , sep);
break;
case COOL_HIDDEN_FLOAT:
x = &va_arg(argptr, float);
printf("%.4f%s", COOL_CAST(float, x), sep);
break;
case COOL_HIDDEN_DOUBLE:
x = &va_arg(argptr, double);
printf("%.4f%s", COOL_CAST(double, x), sep);
break;
case COOL_HIDDEN_CHAR:
x = &va_arg(argptr, char);
printf("%c%s", COOL_CAST(char, x), sep);
break;
case COOL_HIDDEN_UINT:
x = &va_arg(argptr, unsigned int);
printf("%.4u%s", COOL_CAST(unsigned int, x), sep);
break;
case COOL_HIDDEN_VOID:
printf("unsupported type%s", sep);
break;
default:
printf("Internal COOL/C/PRINT error line: %d in %s", __LINE__, __FILE__);
break;
}
}
va_end(argptr);
cool_hidden_last = 0;
}
, , . va_arg
printf
cool_
#define print cool_print
, print
! println
,
#define cool_println(...) \
cool_print(__VA_ARGS__); printf("\n")
#define cool_printlnn() printf("\n")
, - , printlnn()
... , cool_print
#define cool_print(...) cool_print_(__VA_ARGS__ , ## COOL_RSEQ_N()
#define cool_print(...) cool_print_(__VA_ARGS__ ## , COOL_RSEQ_N()
. ,## __VA_ARGS__
, __VA_ARGS__
,
- , __VA_ARGS__
. 2
__VAR_OPT__
, , , , ,
- (,)
, visual stidio __VAR_OPT__
. __VAR_OPT__
, 63 64 ( cool_print##n
( ). -
#define cool_print(...)\
__VAR_OPT__( cool_print_(__VA_ARGS__ , COOL_RSEQ_N()) )
#define cool_print(...) \
cool_print_(__VA_ARGS__ , COOL_RSEQ_N())
- ,
#define cool_print(...)\
cool_print_("", __VA_ARGS__)
#define cool_print_(...) \
cool_print__(__VA_ARGS__ , COOL_RSEQ_N())
#define cool_print__(...) \
COOL_ARG_N(__VA_ARGS__)
,
- . , ,
- . C++ . ,
print
- . visual studio
print
println
" ", ( ) . . , variadic templates c++, ( - )
. ,
: print.h
. . , - . C++, , id ; , ( pow, powi, powf
); , , , , . -
print
C++:
print C++
#ifndef COOL_PRINT_HPP
#define COOL_PRINT_HPP
#include <string>
#include <iostream>
#include <iomanip>
namespace
{
std::ostream* out = &std::cout;
}
namespace cool
{
inline void setCyrillic()
{
setlocale(LC_ALL, "Russian");
}
void setPrintOut(std::ostream& os)
{
::out = &os;
}
std::ostream* getPrintOutPtr()
{
return ::out;
}
inline void printFlush()
{
*::out << std::flush;
}
inline void print()
{
*::out << ' ';
}
template <typename Arg>
inline void print(const Arg& arg)
{
*::out << std::fixed << std::setprecision(4) << arg << ' ';
}
template <typename Arg, typename... Args>
void print(const Arg& arg, const Args&... args)
{
print(arg);
print(args...);
}
////
inline void println()
{
*::out << '\n';
}
template <typename Arg>
inline void println(const Arg& arg)
{
*::out << std::fixed << std::setprecision(4) << arg << '\n';
}
template <typename... Args>
void println(const Args&... args)
{
print(args...);
println();
}
///
void print0() { }
template <typename Arg>
inline void print0(const Arg& arg)
{
*::out << std::fixed << std::setprecision(4) << arg;
}
template <typename Arg, typename... Args>
void print0(const Arg& arg, const Args&... args)
{
print0(arg);
print0(args...);
}
#define COOL_INFO(x) (std::string(#x) + " = " + std::to_string(x))
}
#endif
より理解しやすく、コードが約3分の1になり、実装がより完全になります。しかし同時に、標準的なものはprintf
それほどエレガントに見えませんが、高速で実用的です。各言語にはその場所があります