C语言笔记7

三个典型题:

1.

#include <stdio.h>
int main()
{
    int i = 1;
    int ret = (++i)+(++i)+(++i);
    printf("ret = %d\n", ret);
	return 0;
}

这个代码的运行结果取决于编译器,不同的编译器会有不同的结果,在我们写代码的过程中最好不要写出上似的代码。表达式(++i)+(++i)+(++i),只有操作符的优先级和结合性,没法确定唯一计算路径:

(1)若在gcc编译器下就是这样的规则,按照先1后2相加之后再3的话就是:3+3+4=10,,可能有人会问为啥不是2+3+4=9呢?

进行调试观察汇编代码你会发现(++i)+(++i)+(++i), 中存在多个对同一个变量 i 的自增操作,会对当前状态下的++i进行操作完成后分别赋值给1和2之后,1和2就变了3,进行求和之后对最后一个++i进行和运算,第三个++i就变成了4,所以说在gcc编译器下是10。

(2)若在VS环境下测试,是先对三次++i进行操作完毕之后,分别赋值给1,2,3也就是4+4+4=12。

2.

#include <stdio.h>
int i;
int main()
{
    i--;
    if (i > sizeof(i))
    {
        printf(">\n");
    }
    else
    {
        printf("<\n");
    }
    return 0; 
}

观察这个代码:

在C语言中,全局变量如果没有显式初始化,其初始值为0。因此,对于全局变量int i,其初始值为0。经过i--之后为-1,而 if (i > sizeof(i))判别就要注意了,sizeof(i)的返回值是无符号的整形(unsigned int),对于一个整形内存为4个字节,故此处sizeof(i)的返回值为4,那么通常可能是这样比较 (i > sizeof(i))也就是-1>4不成立,最后程序输出“<”。

但是,需要注意的是,i是有符号的变量i--之后值为-1,当有符号的i与 sizeof()进行运算的时候,会把有符号的i提升为无符号。那么-1提升为无符号,那么-1的补码是11111111111111111111111111111111,是一个很大的数比4肯定大, 比较是用补码进行比较,所以此程序运行结果为“>”。

3.

#include <stdio.h>
int main()
{
  int arr[] = {1,2,3,4,5};
  short *p = (short*)arr;
  int i = 0;
  for(i=0; i<4; i++)
  {
    *(p+i) = 0;
  }
   
  for(i=0; i<5; i++)
  {
    printf("%d ", arr[i]);
  }
  return 0;
}

观察这个代码:

这个代码short *p = (short*)arr; int类型的arr指针变量被强制转化为short类型的指针变量,于是这个地址p把arr指向short类型的数据。它的1个整形就占两个字节。对于*(p+i) = 0;如i=0,*p= 0,会对当前的两个字节复制为0,并且指针变量解引用的时候每加1就会跳过两个字节。所以最后的输出值为00345

  • 11
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值