1. const int a; 表示a是只读的
int const a; //常整型数
const int *a; //a是一个指向常整型数的指针 表示这个指针变量可以修改,但是不能通过这个指针变量修改其所指向地址的值
int * const a; // a是一个指向整型数的常指针 表示这个指针变量不可以修改,但是可以通过这个指针变量修改其所指向地址的值
int const * a const;
注:const离谁近,且是左结合,就修饰谁。如const int *a,就是离int近,int const *a,左结合,就是个常整型的指针;int * const a,就是离*近,就是个常指针
作用是:
为给读你代码的人传达非常有用的信息,实际上,声明一个参数为常量是为了告诉了用户这个参数的应用目的;
合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。
2.用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)
#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL
表达式会使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常数是的长整型数。且这个数是正整数,所以用U表示无符号
3.宏的副作用
#define MAX(a,b) ((a) > (b) ? (a) : (b))
int a = 3,b = 2;
int c = MAX(a++,b); a = 5; c = 4
所以一般使用宏最好不要传入自增自减 。如果你一定要在宏里消除这个副作用
#define MAX(a,b,type) ({type __x = (a), __y = (b);(__x > __y) ? __x : __y;})
MAX(1,2,int); MAX(1.1,1.2,double);
4. 给定一个整型变量a,写两段代码,第一个设置a的bit 3,第二个清除a 的bit 3。
#define BIT3 (0x1 << 3)
static int a;
void set_bit3(void)
a |= BIT3;
void clear_bit3(void)
a &= ~BIT3;
5. 下面的代码输出是什么,为什么?
void foo(void) {
unsigned int a = 6; int b = -20; (a+b > 6) ? puts("> 6") : puts("<= 6"); }
整数自动转换原则,当表达式(a=b)中存在 "有符号类型" 和 "无符号类型" 时所有的操作数都自动转换为 "无符号类型" ,输出是 ">6"
6. 动态内存分配
NULL = (void *)0;
if ((ptr = (char *)malloc(0)) == NULL)
puts("Got a null pointer");
else
puts("Got a valid pointer");
malloc是在堆上分配的,即使是malloc零个内存空间,ptr也不是指向(void *)0地址,它指向堆地址
7. 一个单向链表,不知道头节点,一个指针指向其中的一个节点,问如何删除这个指针指 向的节点?
void DeleteRandomNode(node* pCurrent){
Assert(pCurrent != NULL);
node* pNext = pCurrent -> next;
if(pNext != NULL){
pCurrent -> Next = pNext -> Next; //删除当前的下一个节点
pCurrent -> Data = pNext -> Data; // 将下一个节点的值赋值给当前节点
delete pNext;
}
}