C语言语义陷阱超详细梳理总结_第1页
C语言语义陷阱超详细梳理总结_第2页
C语言语义陷阱超详细梳理总结_第3页
C语言语义陷阱超详细梳理总结_第4页
C语言语义陷阱超详细梳理总结_第5页
已阅读5页,还剩1页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第C语言语义陷阱超详细梳理总结malloc有可能无法提供请求的内存,这种情况下malloc函数会通过返回一个空指针来作为“内存分配失败”事件的信号。

给r分配的内存在使用完毕后应该及时释放。

前面的例程在调用malloc函数时并未分配足够的内存,因为字符串还包含结束标志'\0'。

3作为参数的数组声明

1.下面列举的两种写法是等价的:

charhello[]="hello";

printf("%s\n",hello);//写法1

printf("%s\n",hello);//写法2

原因:数组名hello代表数组hello首元素的地址。

2.下面的两种写法是等价的:

intstrlen(chars[])

/*具体内容*/

intstrlen(char*s)

/*具体内容*/

}

注意下面的两种写法:

externchar*hello;

externcharhello[];

这两种写法虽然是都是正确的,但是不同的形式传递给我们的意思却是完全不一致的,我们要根据具体情况进行使用。

4空指针并非空字符串

注意:空指针不能对其进行解引用。

同时注意不能出现下述写法:

if(strcmp(p,(char*)0)==0)

···

这种写法是非法的,原因在于库函数strcmp的实现中会包括一个操作,用于查看它的指针参数所指向的内容,即对空指针进行了解引用。

也不能出现下述写法:

假设p是空指针

printf(p);

printf("%s",p);

//当然,这两种写法是等价的

这种行为是未定义的。

5边界计算与不对称边界

在我们写循环是最好这样来写:

inti=0;

for(i=0;ii++)

···

这样写能够更好的看出循环的次数,即10次。

当数组中有10个元素时,下标的取值范围为0到9,但是当我们不需要引用这个元素时只需要引用这个元素的地址时,我们可以这样写

intarr[10]={1,2,3,4,5,6,7,8,9,10};

for(inti=0;arr[i](arr[10]);i++)

···

这样可以顺利打印出数组元素从1到10的数字,

ANSIC标准明确允许这种用法:数组中实际不存在的"溢界"元素的地址位于数组之外所占内存之后,这个地址可以用于进行赋值和比较。当然,如果要引用该元素,那就是非法的了。对于实际去读取这个元素的值,这种做法的结果是未定义的,而且极少有编译器能偶检测出这个错误。当然,如果试图去修改这个元素,必然会导致程序崩溃,属于非法访问了!

6求值顺序

C语言中只有四个运算符(、||、:和,)存在规定的求值顺序。==运算符和运算符||首先对左侧操作数求值,只有在需要时才对右侧操作数求值。==运算符:有三个操作数:在ab:c中。操作数a首先被求值,根据a的值再求操作数b或c的值(此时b或c两个表达式根据前面a表达式的结果只会执行一个)。逗号运算符则首先对左侧操作数求值,然后"丢弃该值",再对右侧操作数求值。

注意:分割函数的参数并非逗号运算符。例如,x和y在函数f(x,y)中的求值顺序是未定义的,而在函数g((x,y))中却是确定的先x后y的循序。在后一个例子中,函数g只有一个参数。这个参数的值是这样求得的:先对x求值,然后“丢弃”x的值,接着求y的值。

这种求值顺序的存在使得某些“错误”的程序变为了正确,且在执行后得出正确的结果:

if(count!=0sum/countsmallaverage)

···

注意:C语言中其它所有的运算符对其操作数求值的顺序是未定义的。特别是,赋值运算符并不保证任何求值循序。

例如:下面的这中从数组x中复制前n个元素到数组y中的做法是不正确的,因为它对求值顺序做了太多的假设:

i=0;

while(in)

y[i]=x[i++];

上面的代码假设y[i]的地址将在i的自增操作指向之前被求值,但这是不一定的,这依赖于编译器的具体实现。同样,下面的这种写法也是不正确的:

i=0;

while(in)

y[i++]=x[i];

修改成下面这种写法即可正常工作:

i=0;

while(in)

y[i]=x[i];

i++;

}

当然,这种写法也可以简写为:

for(i=0;ii++)

y[i]=x[i];

7整数溢出

无符号整数不会发生溢出,这是C语言所规定的,如果结果大于所能表示的最大值M,则模(M+1),也就是发生了截断现象。

两个有符号整数进行相加时会发生溢出,而且溢出的结果是未定义的。

下面是一种错误的检查方式:

if(a+b0)

complain();

因为当a+b却是发生溢出时,所有关于结果如何假设都不再可靠。

下面是两种正确的方式:

//方法一:

if((unsigned)a+(unsigned)INT_MAX)

complain();

//方法二:

if(aINT_MAX-b)

complain()

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论