C开发经验2:读《C语言深度解剖>笔记

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来接收容易发生溢出
 
 
 
 
 
 
 
 
 
 
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值