类型、运算符和表达式

类型、运算符和表达式


变量和常量是程序处理的两种基本数据类型,声明语句说明变量的名字及类型,也可指定变量初值,运算符指定要进行的操作。

1 变量名

变量名由字母、数字及下划线 “_” 组成,且第一个字符必须为字母或下划线。

2 数据类型及长度

C 中的类型可分为以下几种:基本类型,枚举类型、void类型和派生类型。

2.1 基本类型

算术类型,包括整数类型和浮点类型。

类型大小值范围
char1字节-128~127
short2字节-32768~32767
int2字节或4字节-2147483648~2147483647
long4字节-2147483648~2147483647
float4字节6位小数
double8字节15位小数
long double16字节19位小数
2.2 枚举类型

算术类型,被用来定义在程序中只能赋予其一定的离散整数值的变量。

2.3 派生类型

包括指针类型、数组类型、结构类型、共用体类型和函数类型。

2.4 void类型

通常用于以下三种情况:

函数返回为空:函数没有返回值。

函数参数为空:函数不接受参数。

指针指向 void:类型为 void * 的指针代表对象的地址,而不是类型,可转换为任何数据类型。

3 常量

3.1 整数常量
  • 字符常量括在单引号中。

  • int类型无后缀,long类型常量后缀为l或L,无符号常量后缀为u或U。

  • 八进制整型常量前缀为0,十进制整型常量不带前缀,十六进制整型常量前缀为0x或0X。

3.2 浮点数常量

包含一个小数点或一个指数,float类型常量以字母f或F结尾,double类型常量没有后缀,long double类型常量以字母l或L结尾。

4 运算符

4.1 算术运算符

二元算术运算符包括:+、-、*、/、%(取模运算符)。整数除法会截断结果中的小数部分。取模运算符不能应用于float或double类型。

利用取模运算符可以限制数的范围,例如 a%10 的值只能在 0~9 之间,因为大于等于10的部分都会被整除

4.2 关系和逻辑运算符

关系运算符:> >= < <= == !=

关系运算符的优先级比算术运算符低。

逻辑运算符:&& || !

由 && 和 || 连接的表达式按从左到右的顺序进行求值。

逻辑非运算符 ! 的作用是将非0操作数转换为0,将操作数0转换为1if(!valid)if(valid == 0)等价,都是当valid为0是返回真。

4.3 类型转换

当一个运算符的几个操作数类型不同时,就需要通过一些规则把它们转换为某种共同的类型。一般来说,自动转换是指把”较窄“操作数转换为”较宽“操作数,并且不丢失信息的转换。

/* 将字符转换为小写形式 */
int lower(int c){
    if(c >= 'A' && c <= 'Z')
        return c + 'a' - 'A';
    else
        return c;
}

若没有unsigned类型的操作数,则遵循以下转换规则:

  • 若其中一个操作数的类型为long double,则将另一操作数转化为此类型。
  • 若其中一个操作数类型为double,则将另一操作数转换为此类型。
  • 若其中一个操作数类型为float,则将另一操作数转换为此类型。
  • 将char与short类型操作数转换为int类型。
  • 若其中一个操作数类型为long,则将另一操作数转换为此类型。

注意:表达式中的float类型操作数不会自动转换为double类型,主要为了节省存储空间和机器执行时间(双精度算术运算非常费时)。

当表达式包含unsigned类型操作数时,转换规则复杂一些,因为带符号值与无符号值间的比较运算与机器相关,取决于机器中不同整数类型的大小。

强制类型转换:使用一个一元运算符强制进行显示类型转换。可以理解为表达式首先被赋值给类型名指定的类型的某个变量,然后再用该变量替换整条语句。

(类型名) 表达式

unsigned long int next = 1;
/* 返回取值在0~32767之间的伪随机数 */
int rand(void){
    next = next * 1103515245 + 12345;
    return (unsigned int)(next / 65536) % 32768;
}
/* 为rand函数设置种子数 */
void srand(unsigned int seed){
    next = seed;
}
rand() % 10;		//产生0~9的随机数
rand() % 51 + 13;	//产生13~63的随机数
4.4 自增、自减运算符

这两个运算符既可以用作前缀运算符,也可用作后缀运算符。表达式++n先将n的值递增1,然后再使用n的值;而表达式n++则先使用n的值,然后再将n的值递增1。对于使用变量n的值的上下文来说,++n和n++效果是不同的。自增与自减运算符只能作用于变量,表达式 (i+j)++ 是非法的。

/* 从字符串s中删除字符c */
void squeeze(char s[], char c){
    int i, j;
    for(i = j = 0; s[i] != '\0'; i++)
        if(s[i] != c)
            s[j++] = s[i];
    s[j] = '\0';
}
4.5 按位运算符

C语言提供了6个位操作运算符,这些运算符只能作用于整数:

& 按位与(AND)

| 按位或(OR)

^ 按位异或(XOR)

<< 左移

>> 右移
按位求反(一元运算符)

掩码:某些位为1,某些位为0的整数,用&和掩码可以屏蔽整数的某些位,从而达到查看某些位的效果。

/* &用于屏蔽某些二进制位(置0) */
n = n & 0177;	//0177即001111111,屏蔽n的前两位
/* |用于将某些二进制位置1 */
n = n | 0600;	//将n的两位置1
/* ^用于将某些二进制位转置(若位为1则置0,为0则置1 */
n = n ^ 0600;	//任一位与0异或都等于它本身,故将n的前2位转置
/* <<与>>用于将左操作数左移或右移,移动的位数由右操作数指定 */
n<< 2;	//将n的值左移2位,右边空出的2位用0填补,等价于n*4
/* ~用于求整数的二进制反码,即二进制位的1变为0,0变为1 */
n = n & ~0600;	//将n的前两位置0
/*
返回x中从第p位开始的n位
x >> (p+1-n)将从第p位开始的n位移到最右端
~0的所有位都为1,~0 << n将~0左移n位,最右边的n位用0填补,再用~取反
~(~0 << n)获得了最右边n位都为1的掩码
*/
unsigned getbits(unsigned x, int p, int n){
    return (x >> (p+1-n)) & ~(~0 << n);
}

注意:上述位操作中并没有指定n的机器字长,因为系统会自动补0,若n为16位则在0600左边补7个0,而不要采用0000600的形式,这样不利于移植。

4.6 赋值运算符与表达式

在赋值表达式中,若表达式左边的变量重复出现在表达式的右边,可将表达式缩写,如:

i = i + 2可缩写为i += 2,其中+=运算符称为赋值运算符

大多数二元运算符(op)都有相应的赋值运算符(op=),如 + - * / << >> & ^ | 等。

若exp1和exp2是表达式,则exp1 op= exp2等价于exp1 = (exp1) op (exp2)

/* 统计x中位为1的位数 */
int bitcount(unsigned x){
    int i;
    for(i = 0; x != 0; x >>= 1)
        if(x & 01)
            i++;
    return i;
}
4.7 条件表达式

条件表达式可以改写为使用三元运算符 ? : 的表达式。

if(exp1) exp2;
else exp3;
/* 先计算exp1,若其值为真则计算exp2的值,否则计算exp3的值 */
exp1 ? exp2 : exp3;
4.8 运算符优先级
类型运算符结合性
后缀() [] -> . ++ –从左到右
一元+ - ! ~ ++ – (type) * & sizeof从右到左
* / %从左到右
+ -
<< >>
< <= > >=
== !=
&
^
|
&&
||
三元? :从右到左
= += ~= *= /= %= &=从右到左
^= |= <<= >>=从左到右
,

: | 从右到左 |
| | = += ~= *= /= %= &= | 从右到左 |
| | ^= |= <<= >>= | 从左到右 |
| | , | |

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值