指针的各种名字,换个马甲也得认识你啊。。
char * const p; //常量指针,p的值不可以修改
char const * p;//指向常量的指针,指向的常量值不可以改
const char *p; //和char const *p
int *p[n];-----指针数组,每个元素均为指向整型数据的指针。
int (*p)[n];------p为指向一维数组的指针,这个一维数组有n个整型数据。
int *p();----------函数带回指针,指针指向返回的值。
int (*p)();------p为指向函数的指针。
memcpy和strcpy:
memcpy用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的数据长度
strcpy就只能拷贝字符串了,它遇到'\0'就结束拷贝
extern char *strcpy(char *dest,char *src)
{ ASSERT((dest!=NULL)&&(src!=NULL));
Char *address = dest;
While((*dest++=*src++)!=’\0’)
Continue;
Return dest; }
extern void *memcpy(void *dest, void *src, unsigned int count);
{ ASSERT((dest!=NULL)&&(src!=NULL));
ASSERT((dest>src+count)||(src>dest+count));//防止内存重叠,也可以用restrict修饰指针
Byte* bdest = (Byte*)dest;
Byte* bsrc = (Byte*) src;
While(count-->0)
*bdest++ = **bsrc++;
Return dest; }
ASSERT():
这个宏通常原来判断程序中是否出现了明显非法的数据,如果出现了终止程序以免导致严重后果,同时也便于查找错误。
神马时候分配神马变量,有个sense比较好:
全局变量在main函数调用后,就开始分配,
静态变量则是在main函数前就已经初始化了。
局部变量则是在用户栈中动态分配的
char s1[]=‛aaaaaaaaaaaaaaa‛;
char *s2=‛bbbbbbbbbbbbbbbbb‛;
aaaaaaaaaaa是在运行时刻赋值的; 而bbbbbbbbbbb是在编译时就确定的;
a=c[1]; //c是数组
a=p[1]; //p是指针
第一种在读取时直接就把字符串中的元素读到寄存器cl中,而第二种则要先把指针值读到edx中,在根据edx读取字符,显然慢了。
在数组作为形参的时候,只作为地址处理:
Void Func(char a[100])
=>Sizeof(a) = 4
预编译
预编译又称为预处理,是做些代码文本的替换工作。处理#开头的指令,比如拷贝#include包含的文件代码,#define宏定义的替换,条件编译等,就是为编译做的预备工作的阶段,主要处理#开始的预编译指令,预编译指令指示了在程序正式编译前就由编译器进行的操作,可以放在程序中的任何位臵。 c编译系统在对程序进行通常的编译之前,先进行预处理。
c提供的预处理功能主要有以下三种:1)宏定义 2)文件包含 3)条件编译
const VS #define
请说出const与#define 相比,有何优点?
答:Const作用:定义常量、修饰函数参数、修饰函数返回值三个作用。被Const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。 1) const 常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误。 2) 有些集成化的调试工具可以对const 常量进行调试,但是不能对宏常量进行调试。
用宏定义交换两个数:
a = a + b;
b = a - b;
a = a - b;
#define SWAP(a,b)\
(a)=(a)+(b);\
(b)=(a)-(b);\
(a)=(a)-(b);