1.short-circuit-judging simulate if-else
2. swap a and b
3. static关键字使用
4. “#include"妙用
5. 用”{}" 隔离作用域
6. 宏
7. #if 0 … #endif 块中的内容不会被编译,因为注释不允许嵌套,我们可以把暂时不用的代码块放在这里面
8. 数组初始化的时候可以指定索引,而且可以给特定范围的数组赋值
9. scanf支持正则式,而且可以超越每次读到空白就终止的限制。
10. s[i] 是 *(s + i) 的语法糖,所以等价于 i[s]。
11. 设定printf打印的最小宽度
12. 变长数组
1.short-circuit-judging simulate if-else
for example: calculate 1+2+3+...+n#ifdef __tmain
#define debug cout
#else
#define debug 0 && cout
#endif // __tmain
class Solution {
public:
int SumRecursion(int n) {
int ans = n;
//debug <<n <<endl;
n && (ans += SumRecursion(n - 1));
return ans;
}//int SumRecursion(int n)
};//class Solution
2. swap a and b
template <typename T>
void swap(T &a, T &b) { a == b ? 0 : a ^= b ^= a ^= b; }
template <typename T>
void swap(T &a, T &b) { std::is_arithmetic<T>::value && a == b ? 0 : a ^= b ^= a ^= b; }
3. static关键字使用
static int nVal = 3;
将变量声明范围限制在文件或函数作用域内
4. "#include"妙用
static int gadDataIn[DATA_LEN] = {
#include "文件路径\文件名"
};
文件里面的数据需要用","隔开,可以是十进制也可以是十六进制数据。
5. 用"{}" 隔离作用域
{
int nVal = 3;
float fVal = 3.14;
}
将nVal和fVal声明范围限制在"{}"内
6. 宏
静态断言
#define STATIC_ASSERT(expr) (\
(void)sizeof(char[1-2*!!!(expr)]))
获取偏移量
#define offsetof(type, member) (\
(size_t)&((type*)0->menber) )
获取容器地址
/**
* container_of - cast a member of a structure out to the containing structure
* @ptr: the pointer to the member.
* @type: the type of the container struct this is embedded in.
* @member: the name of the member within the struct.
*
*/
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
数组元素数目
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) \
+sizeof(typeof(int[1-2*!!__builtin_types_compatible_p(typeof(arr),\
typeof(&arr[0]))]))*0)
头文件保护
#ifndef __XXX_H__
#define __XXX_H__
#endif
符号转字符串,符号拼接
#define _STR(x) #x
#define sys_call(n) __asm volatile("svc #"#n)
#define _str_spice(tkn1, tkn2) tkn1##tkn2
#define str_spice(tkn1, tkn2) _str_spice(tkn1, tkn2)
宏实现部分泛型功能
/*
* heap.h
*
* Author: SMS
*/
#ifndef __HEAP_H__
#define __HEAP_H__
#include <stdint.h>
#include <stdbool.h>
#define _str_spice(tkn1, tkn2) tkn1##tkn2
#define str_spice(tkn1, tkn2) _str_spice(tkn1, tkn2)
#define __template(type, tplt) str_spice(type, str_spice(_, tplt))
#ifdef __cplusplus
extern "C" {
#endif /* __CPLUSPLUS */
#ifndef heap_type
#define heap_type int
#endif
typedef bool(*compare_t)(heap_type*, heap_type*);
static inline void
__template(heap_type, heap_swap)(heap_type *a, heap_type *b)
{
heap_type t;
t = *a;
*a = *b;
*b = t;
}
static inline void
__template(heap_type, heap_build)(heap_type a[],
compare_t func,
unsigned bgn,
unsigned end)
{
heap_type t = a[bgn];
unsigned i;
for(i=(bgn<<1)+1; i<=end; bgn=i, i=(i<<1)+1)
{
if(i<end && !func(&a[i], &a[i+1]))
i++;
if(func(&t, &a[i]))
break;
a[bgn] = a[i];
a[i] = t;
}
}
static inline void
__template(heap_type, heap_adjast)(heap_type a[],
compare_t func,
unsigned bgn,
unsigned end)
{
heap_type t = a[end];
unsigned i;
for(i=(end-1)>>1; i>=bgn && end!=bgn; end=i, i=(i-1)>>1)
{
if(!func(&t, &a[i]))
break;
a[end] = a[i];
a[i] = t;
}
}
static inline void
__template(heap_type, heap_sort)(heap_type a[],
compare_t func,
unsigned len)
{
unsigned i = (len>>1)-1;
for(; i<(unsigned)-1; i--)
__template(heap_type, heap_build)(a, func, i, len-1);
for(i=len-1; i!=0; i--)
{
__template(heap_type, heap_swap)(&a[0], &a[i]);
__template(heap_type, heap_build)(a, func, 0, i-1);
}
}
static inline void
__template(heap_type, heap_push)(heap_type a[],
compare_t func,
unsigned len,
heap_type *data)
{
a[len-1] = *data;
__template(heap_type, heap_adjast)(a, func, 0, len-1);
}
static inline void
__template(heap_type, heap_pop)(heap_type a[],
compare_t func,
unsigned len,
unsigned index)
{
a[index] = a[len-1];
__template(heap_type, heap_build)(a, func, index, len-1);
}
#ifdef __cplusplus
}
#endif /* __CPLUSPLUS */
#endif /* __HEAP_H__ */
7. #if 0 ...... #endif 块中的内容不会被编译,因为注释不允许嵌套,我们可以把暂时不用的代码块放在这里面
#if 0
here will not enter into compile
we can move the code we not need now here
#endif
8. 数组初始化的时候可以指定索引,而且可以给特定范围的数组赋值
#include<stdio.h>
int main(){
int i = 0;
int arr[] = {[1]=5, [5]=10, [2]=20};
int arr2[] = {[0 ... 9] = 10, [10 ... 19] = 20, [20 ... 29] = 30};
for(i = 0; i < 6; i++)
printf("arr[%d] = %d ,", i, arr[i]);
printf("\n");
for(i = 0; i < 30; i++)
printf("arr2[%d] = %d ,", i, arr2[i]);
return 0;
}
9. scanf支持正则式,而且可以超越每次读到空白就终止的限制。
#include<stdio.h>
#define MAX 100
int main(){
int i = 0;
char s1[MAX],s2[MAX];
//scanf("%[^\n]\n",s1);
//read till meet '\n',and then trash the \n
//scanf("%[^,]",s1); //?? also will trash the coma
//scanf("%[^,],",s1); // this does not trash the coma
//this * can make us skip some input
//for example,we just care the last-name
scanf("%*s %s",s1);
printf("%s\n",s1);
return 0;
}
10. s[i] 是 *(s + i) 的语法糖,所以等价于 i[s]。
#include <stdio.h>
int main(){
char s[] = "vonzhou";
printf("%c\n", 2[s]);
return 0;
}
11. 设定printf打印的最小宽度
#include <stdio.h>
int main(){
int n = 6;
int val = 1000;
// with a minimum width of n,default right aligned
printf("%*d", n, val);
return 0;
}
12. 变长数组
struct MutableLenArray {
int count;
char p[0];
};