C语言深度解剖 笔记2

1
int a[5];
cout<<sizeof(a)<<endl; 
cout<<sizeof(a[5])<<endl;
cout<<sizeof(&a)<<endl;
cout<<sizeof(&a[0])<<endl;
output:
20
4
4
4
当定义一个数组a时,编译器根据指定的元素个数和元素类型分配确定大小的一块内存,并把这块内存的名字命名为a,名字a一旦与这块内存匹配就不能被改变。a[0],a[1]等为a的元素,但并非元素的名字。数组的每一个元素都没有名字。
所以
sizeof(a) =  sizeof(int)*5
sizeof(a[0]) = sizeof(int)
sizeof(a[5])的值在32位系统下为4,由于sizeof是关键字不是函数,而函数求值是在运行的时候,而关键字sizeof求值是在编译的时候。虽然并不存在a[5]这个元素,但是这里也并没有去真正访问,而是根据数组元素的类型来确定其值。
sizeof(&a[0])的值在32位系统下为4,&a表示去这个变量的地址,可以理解为一个指针,指针通常分配4个字节
sizeof(&a),&a是去数组a的首地址,同样类似一个指针。


2
char a[1000];

for(i=0;i<1000;i++)
{
a[i] = -1-i;
}
printf("%d",strlen(a));
a数组中元素的值将在char一个字节的取值范围中取遍所有值,在a[255]中为0,即空'\0',所以output为255


3
无符号型的变量在作为循环变量时,要注意它永远>=0
unsigned i = 0;
for (i = 9;i >=0 ;i--)
{
printf("%u\n",i);
}


4
使用if语句的其他注意事项
先处理正常情况,再处理异常情况
把执行概率更大的代码放到前面,避免多次无谓的比较。


5
switch-case组合
最后必须使用default分支,即使程序真的不需要default处理,也应该保留语句。


6
循环嵌套控制在3层以内


7void关键字
void真正发挥的作用在于:
(1)对函数返回的限定
(2)对函数参数的限定
如果p1和p2的类型相同,那么可以直接在p1和p2间相互赋值;如果p1和p2指向不同的数据类型,则必须使用强制类型转换。
如:
float *p1;
int *p2;
p1 = (float *)p2;
而void*不同,任何类型的指针都可以直接赋值给它,无需进行强制类型转换,如:
void *p1;
int *p2;
p1 = p2;
但这并不意味着,void*也可以无需强制类型转换地赋给其它类型的指针。因为“空类型”可以包容“有类型”,而“有类型”则不能包容“空类型”。
float a,*p1;
int b,*p2;
void *p3;

a = 10.5;
b = 5;
p1 = &a;
p2= &b;
cout<<"a:"<<a<<" "<<"*p1:"<<*p1<<endl;
cout<<"b:"<<b<<" "<<"*p2:"<<*p2<<endl;


p2 = (int *)p1;
cout<<"a:"<<a<<" "<<"*p1:"<<*p1<<endl;
cout<<"b:"<<b<<" "<<"*p2:"<<*p2<<endl;//虽然p1可以强制转换成其它类型,但是在输出是结果莫名其妙


p3 = p1;
cout<<"p3"<<(*(float *)(p3))<<endl;//不能直接*p3输出,不然编译错误


8千万小心又小心使用void指针类型
(1)按照ANSI标准,不能对void指针进行算法操作,ANSI标准坚持:进行算法操作的指针必须是确定知道其指向的数据类型大小,即下列操作都不是合法的:
void *pvoid;
pvoid ++;//ANSI:错误
pvoid +=1;//ANSI:错误
但GUN则指定void*的算法操作与char*一致。因此下列语句在GUN编译器中均正确:
pvoid ++;
pvoid +=1;
在实际的程序设计中,为了符合ANSI标准,并提高程序的可移植性,可以这样编写实现同样功能的代码:
void* pvoid;
(char *)pvoid ++;//ANSI:正确;GUN:正确
(char *)pvoid +=1;//ANSI:错误;GUN:正确


9如果函数的参数可以是任意类型指针,那么应声明其参数为void*
典型的内存操作函数memcpy和memset函数原型分别为:
void* memcpy(void *dest,const void * src,size_t len);
void* memset(void *buffer,int c,size_t num);


10void不能代表一个真实的变量
因为定义变量时必须分配内存空间,定义void类型变量,编译器到底分配多大的内存呢?例如:
void a;//错误
function(void a);//错误

void体现了一种抽象,这个世界上的变量都是“有类型”的。


由于sizeof(int)*p一直没有搞懂,所以迟迟没有做完笔记2,现在还是没有弄懂作者写这个表达式的意图和涉及的知识点。












  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值