<二>类型、运算符与表达式

字节长度

-都知道C语言提供了几种基本数据类型:char、int、float、double。此外可以在这些基本数据类型加一些限定符。short和long两个限定符用于限定整型
short int sh;
long int cnt;
上述中int可以省略
short与 int类型至少得是16位,而long类型至少是为32位,且short类型不得低于int类型,而int类型不得长于long类型(换种说法:short、int 和 long 类型都表示整型值,存储空间的大小不同。一般, short 类型为半个机器字长,int 类型为一个机器字长,而 long 类型为一个或两个机器字长(在 32 位机器中 int 类型和 long 类型通常字长是相同的),限定符signed与 unsigned可用于限定于char类型或任何整型,若类型为n位,则unsigned 为0-2^n -1;而signed为-2^(n-1)-2^(n-1)-1;long、float、double类型可以表示高精度的浮点数,有关这些类型长度定义的符号常量以及其他与机器和编译器有关的属性可以在

常量

类似于1234的整数常量属于int型;long类型的常量以字母l或L结尾;无符号常量以字母u或U结尾,后缀ul或UL表明是unsigned long ;浮点数常量中包含一个小数点(1.2)或一个指数(1e-2),也可以两者都有,没有后缀的浮点数常量为double类型,后缀f或F表示float
一个字符常量是一个整数,字符常量一般用来与其他字符进行比较;某些字符还可以通过转义字符序列表示为字符和字符串常量。可以用’\ooo’(o为八进制数)或’\xhh’(h为十六进制数),如响铃符ASCII为7,则其可表示为’\007或’\x7’;常量表达式在编译时求值,而不是在运行时求值;字符串常量(本质是一个字符数组),注意‘x’与”x” 不是一样的,前是一个整数,后是一个字符数组;枚举常量不细说了,如enum boolean {NO,YES};

声明

所有变量必须先声明再使用,也可以声明的同时进行初始化;默认情况下,外部变量与静态变量将被初始化为0,未经初始化的自动变量的值都是未定义的

类型转换

  • 自动类型转换是指把比较窄的操作数转换为比较宽的操作数,并且不丢失信息的转换如f+i自动把整型变量i转换为浮点型;
  • 关于隐式类型转换,如二元运算符的两个操作数具有两个不同的类型,那么在进行运算之前先把“较低”的类型转换成“较高”的类型,运算结果为较高的类型。具体的转换规则挺多的。。。(好吧,你当我没说)
  • 强制类型转换格式:(类型)表达式
    下面看一个标准库rand的实现吧
unsigned long int next = 1;
/*rand函数:返回取值在0~32767之间的随机数*/
int rand(void)
{
    next = next * 1103515245 + 12345;
    return (unsigned int) (next/65536) % 32768;
}

/*srand函数:为rand函数设置种子数*/

void srand(unsigned int seed)
{
    next = seed;
}

位运算符

  • C语言提供了6个位运算符,这些只能用于整型操作数,即只能用于char、short、int 与long
  • 按位与运算符&经常用于屏蔽某些二进制位如:n = n &0x01777,该语句将n中的除7个低二进制位外的其他各位均置为0;
  • 按位或运算符|经常用于将某些某些二进制位置为1如x = x | SET_ON;
  • 按位异或^用于将两个操作数不同时将该位置为1
  • 移位运算符<<与>>用于将操作数左移或右移,移动的操作数由右操作数指定,(右操作数必须是非负值)
    • 左移:注意对unsigned类型的无符号值进行右移位时,左边空出来的部分将用 0填补,(若移动到最左边,再移一位,则循环移到最右边第一位,接着移,即循环移位)
    • 右移:对signed类型的带符号值进行右移时,某些机器将对左边空出的部分用0用符号为填补(即“算术移位”),而另一些机器则对左边空出来的部分用0填补(即“逻辑单位”) 注意没有和右移一样的“循坏移位”,如果移出去了就为0了
  • 一元运算符~用于求整数的二进制反码,如x = x & ~077 将把x的最后 6位置为0.
  • 现在看一个函数getbits(x,p,n)它将返回x中从右边数将p位开始向右数n位的字段,这里假定最右边的一位是第0位,n与p都是和合理的正值。
unsigned getbits(unsigned x, int p, int n)
{
    return (x >> (p+n-1) & ~(~0 << n));
}

思路:先讲需要的位移动到最右端(>>),然后取出来(&1)即可
注意位运算符&、| 与^的优先级比运算符==与 !=都低如:记得加括号

if ( (x&MASK) == 0)

赋值运算符与表达式

先看一个程序吧,统计x中值为1的二进制数

int bitcount(unsigned x)
{
    int b;
    for (b=0; x!= 0; x >>= 1)
        if (x & 01)
            ++b;
    return b;
}

这里讲x声明为无符号类型为了保证将x右移时,无论程序在什么机器上运行,左边空出来的位都用0(而不是符号位)填补。

条件表达式

条件表达式(三元运算符?:)?:的优先级非常低,仅仅高于赋值运算符

运算符优先级与求职次序

同大多数语言一样,C语言没有指定同一运算符中多个操作数的计算顺序(&& 、||、 ?:、 运算符除外)。如x = f() + g()的语句中,f可以在g之前计算,也可以在之后计算。
类似的,C语言也没有指定函数各参数的求值顺序。因此,下列语句在不同的编译器中会有不同的值

printf("%d %d\n",++n,power(2,n));

下面再来看一个例子:

a[i] = i++;

问题是:数组下标的i是引用旧值还是引用新值?
不同编译器解释可能不同,并因此产生不同结果
因此避免这种会产生歧义的写法
PS:这章写的好乱,有时间再来整理下吧,囧呀

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值