1、c语言的定义与声明
定义:创建对象并分配内存空间(分配内存)
声明:告诉编译器这个名字与内存的匹配情况,或者声明名称不能再重定义。(不分配内存)
比如:
int i 就是定义一个变量i,并为i开辟一块4字节的内存。
extern int i 就是声明这个变量是从外部文件引用,并不再为他开辟空间
2、auto、register关键字
auto:自动管理变量的生命周期,所有变量默认。
register:将变量放入寄存器.
注意:register变量必须是一个单个的值,并且其长度应小于或等于整形的长度。而且不能用&进行取地址
3、sizeof
注意:sizeof不是函数,而是关键字
4、一道表面很简单的题
void main()
{
char a[1000];
int i;
for(i=0; i<1000; i++)
{
a[i] = -1-i;
}
printf("%d",strlen(a));
system("pause");
}
答案为255
5、空结构体占用多少个字节?
struct student
{
}stu;
sizeof(stu)的值是多少呢?
答案为1个字节
6、柔性数组
typedef struct st_type
{
int i;
int a[];
}type_a;
这样我们就可以定义一个可变长的结构体, 用sizeof(type_a) 得到的只有4 , 就是
sizeof(i)=sizeof(int)。那个0 个元素的数组没有占用空间,而后我们可以进行变长操作了。通
过如下表达式给结构体分配内存:
type_a *p = (type_a*)malloc(sizeof(type_a)+100*sizeof(int));
7、##预算符,主要起到粘合作用
#define XNAME(n) x##n
代码执行时就会变成x8
8、来几个绝对补脑的指针变量
(1)*(int*)&p 将这个指针的地址,转换为int*指针,然后取指针对应地址的值。
void (*p)();//定义一个指向函数的指针
看下面的例子就好理解
void Function()
{
printf("Call Function!\n");
}
intmain()
{
void (*p)();
*(int*)&p=(int)Function;
(*p) ();
return 0;
}
(2)(*(void(*) ())0)();
将0地址强行转换为 指向函数的指针,这个函数格式为void(),然后取里面的值进行调用 (*p)();
第一步:void(*) (),可以明白这是一个函数指针类型。这个函数没有参数,没有返回值。
第二步:(void(*) ())0,这是将0 强制转换为函数指针类型,0 是一个地址,也就是说一
个函数存在首地址为0 的一段区域内。
第三步:(*(void(*) ())0),这是取0 地址开始的一段内存里面的内容,其内容就是保存
在首地址为0 的一段区域内的函数。
第四步:(*(void(*) ())0)(),这是函数调用。
好像还是很简单是吧,上面的例子再改写改写:
(*(char**(*) (char **,char **))0) ( char **,char **);
(3)char * (*(*pf)[3])(char * p);
函数指针数组的指针
9、memset 可以用来初始化
10、几个注意事项
使用free(p)释放后,一定要将p设置为NULL
使用malloc(0)时也是可以分配成功的,只是无法使用该地址
函数体规模尽量小,尽量控制在80行代码以内
函数的参数尽量控制在4个以内
getchar()返回值是int,用char来接收容易发生溢出
定义:创建对象并分配内存空间(分配内存)
声明:告诉编译器这个名字与内存的匹配情况,或者声明名称不能再重定义。(不分配内存)
比如:
int i 就是定义一个变量i,并为i开辟一块4字节的内存。
extern int i 就是声明这个变量是从外部文件引用,并不再为他开辟空间
2、auto、register关键字
auto:自动管理变量的生命周期,所有变量默认。
register:将变量放入寄存器.
注意:register变量必须是一个单个的值,并且其长度应小于或等于整形的长度。而且不能用&进行取地址
3、sizeof
注意:sizeof不是函数,而是关键字
4、一道表面很简单的题
void main()
{
char a[1000];
int i;
for(i=0; i<1000; i++)
{
a[i] = -1-i;
}
printf("%d",strlen(a));
system("pause");
}
答案为255
5、空结构体占用多少个字节?
struct student
{
}stu;
sizeof(stu)的值是多少呢?
答案为1个字节
6、柔性数组
typedef struct st_type
{
int i;
int a[];
}type_a;
这样我们就可以定义一个可变长的结构体, 用sizeof(type_a) 得到的只有4 , 就是
sizeof(i)=sizeof(int)。那个0 个元素的数组没有占用空间,而后我们可以进行变长操作了。通
过如下表达式给结构体分配内存:
type_a *p = (type_a*)malloc(sizeof(type_a)+100*sizeof(int));
7、##预算符,主要起到粘合作用
#define XNAME(n) x##n
代码执行时就会变成x8
8、来几个绝对补脑的指针变量
(1)*(int*)&p 将这个指针的地址,转换为int*指针,然后取指针对应地址的值。
void (*p)();//定义一个指向函数的指针
看下面的例子就好理解
void Function()
{
printf("Call Function!\n");
}
intmain()
{
void (*p)();
*(int*)&p=(int)Function;
(*p) ();
return 0;
}
(2)(*(void(*) ())0)();
将0地址强行转换为 指向函数的指针,这个函数格式为void(),然后取里面的值进行调用 (*p)();
第一步:void(*) (),可以明白这是一个函数指针类型。这个函数没有参数,没有返回值。
第二步:(void(*) ())0,这是将0 强制转换为函数指针类型,0 是一个地址,也就是说一
个函数存在首地址为0 的一段区域内。
第三步:(*(void(*) ())0),这是取0 地址开始的一段内存里面的内容,其内容就是保存
在首地址为0 的一段区域内的函数。
第四步:(*(void(*) ())0)(),这是函数调用。
好像还是很简单是吧,上面的例子再改写改写:
(*(char**(*) (char **,char **))0) ( char **,char **);
(3)char * (*(*pf)[3])(char * p);
函数指针数组的指针
9、memset 可以用来初始化
10、几个注意事项
使用free(p)释放后,一定要将p设置为NULL
使用malloc(0)时也是可以分配成功的,只是无法使用该地址
函数体规模尽量小,尽量控制在80行代码以内
函数的参数尽量控制在4个以内
getchar()返回值是int,用char来接收容易发生溢出