As the title indicates this is a collection of C idioms, roughly categorized.
if (*++argv && !strcmp(*argv, "-n")) {
++argv;
// Do something, usually set a flag.
}
if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'n') {
}
As seen in the original K&R, by convention optional arguments start with a minus sign.
while(--argc > 0 && (*++argv)[0] == '-') {
// Process optional arguments
}
while(*argv) {
// Do something
if (*++argv)
// Do something, considering there are more arguments to be processed.
}
for(int i = 1; i < argc; i++) {
// Do something using argv[i]
}
Arguments are processed using while and switch. Most of the time argc and argv are the same arguments received by main. optarg is the variable set to to the value of the option argument. optind is the variable set to the index of next non-option argument.
while ((c = getopt (argc, argv, "f: :c")) != -1) { // Process option arguments
switch (c) {
case 't':
foo(optarg) // Do something, optarg is the value of the option t.
break;
default:
}
}
argc -= optind; // update list of arguments so that regular
// arguments (non-option) can be processed as usual.
argv += optind;
In this idiom the consequent and alternative expressions of the ternary operator can be ternary expressions themselves. The conditions must be mutually exclusive and the final expression must be different for each case.
!x ? (!y ? upleft : (y == bottom ? lowleft : left)) :
(x == last ? (!y ? upright : (y == bottom ? lowright : right)) :
(!y ? upper : (y == bottom ? lower : normal)));
A goto expression is used to execute code required in multiple parts of the function. This idiom presupposes multiple exit conditions and that the label should always be placed before the end of the function. Convenient for code reuse if preventing a function call is required for performance.
int some_function(int n)
{
if ()
return 1;
if ()
goto message;
for() {
for () { // Nested for to indicate the usefulness of
// the idiom (a break statement won't do
// here).
goto message;
}
}
// Handle common exit condition. Ideally the label should be
// the name of the operation.
:message
// print something
return -1;
}
- left shift by n is equivalent to a division by 2^n.
- right shift by n is equivalent to a multiplication by 2^n.
- bitwise and by n is equivalent to a modulus operation by 2^n + 1, so the right operand must be odd.
// Multiplication
3 << 2; // multiply by 4.
3 << 4; // multiply by 16.
// Division
3 >> 2; // divide by 4.
3 >> 4; // divide by 16.
// Modulus - & 3 is equivalento to mod 3 + 1.
19 & 3; // equal to 19 % 4.
unsigned int x;
char *c;
x = 0x12345678; // set 4 byte integer
c = (char *)&x; // grab first byte
if (*c == 0x12) // check first byte
// big endian
// else little endian
// A more concise idiom
int n = 1;
if (*(char *)&n == 1)
Check if some bit is set for a particular variable.
bool checked = ((some_var & (1 << 30)) != 0);
Use & to clamp a value to be of a particular maximum number of bits.
u64 some_var = (u64)(other_var & 0x00000003);
Build a bit pattern using the | operator.
uint32 color = ((uint8) (r * 255.0f)) << 16 |
((uint8) (g* 255.0f)) << 8) |
((uint8) (b * 255.0f) << 0));