《C程序设计语言》学习笔记——类型、运算符与表达式

变量名

命名限制条件

- 名字是由字母和数字组成的序列,第一个字符必须为字母。
- 变量名不要以下划线“_”开头。
- 大写字母与小写字母要区分(即 x 与 X 是两个不同的名字)。

传统C语言用法中,变量名使用小写字母,符号常量全部使用大写字母。
选择的变量名要能够尽量从字面上表达变量的用途,这样做不容易引起混淆。
局部变量一般使用较短的变量名(尤其是循环控制变量),外部变量使用较长的名字。

数据类型及长度

基本数据类型

	char    字符型,占用一个字节,可以存放本地字符集中的一个字符。
	int     整型,通常反映了所用机器中整数的最自然长度。
	float   单精度浮点型。
	double  双精度浮点型。

对基本类型可应用一些限定符,

1  short int = short
2  long int = long
3  short一般16比特。
4  int可为16或32比特。
5  long至少是32比特。
6  short类型不得长于int类型,int类型不得长于long类型。
7
8
9   unsigned/signed 修饰char及任何整型。
10  char到底是有符号还是无符号取决于机器实现,但可打印字符总是正值。
11  float/double/long double取决于具体的实现,可以表示相同的长度,也可以表示两种或三种不同的长度。

常量

- int型常量,例1234
- long型常量,例1234l或1234L
- 一个整型常量太大,越出int时,会被当成long对待,例12345678
- 无符号int常量,例1234u或1234U
- 无符号long常量,例1234ul或1234UL
- double常量(无后缀浮点数常量),例123.4或1e-2   (包含小数点或指数,表示为浮点数常量)
- float常量(后缀f或F),例123.4f或1e-2f 或 123.4F或1e-2F
- long double常量(后缀l或L),例123.4l或1e-2l 或 123.4L或1e-2L



- 整数的表达值可为,10进制、8进制或16进制。
-8进制形式:0yyy  (yyy表示整型常量)
-16进制形式:0xyyy 或 0Xyyy
-例:
-10进制:31
-8进制:037
-16进制:0x1f或0x1F
-8进制和16进制常量也可以后缀跟 L来表示long,和U来表示unsigned
-例:
-0XFUL表示unsigned long常量值为10进制下的15	




-字符常量是整数,单引号内加字符。
-字符常量值是字符在机器的字符集里面的数值。
-例:
-在ASCII字符集,字符常量'0'有值为48。
-字符常量参与数值操作,以整数方式。
-在字符串和字符常量中,特定字符可以被转义序列表达,
-如\n,
-转义字符看起来像是两个字符,但只代表一个。
-此外,任意字节大小的位模式可以被指定,
-通过'\ooo',ooo可以是1个到3个8进制数
-或通过'\xhh',hh可以说一个或多个16进制数。

转义序列集合:

转义字符描述
\a响铃符
\b回退符
\f换页符
\n换行符
\r回车符
\t横向制表符
\v纵向制表符
\\反斜杠
\?问号
\’单引号
\"双引号
\ooo八进制数
\xhh十六进制数
- 字符常量'\0'代表字符,具有值0,也即null字符。
- 常量表达式是仅仅包含常量的表达式。
- 这样的表达式在编译时求值,而非运行时求值。可以出现在常量可以出现的任何位置。


- 一个字符串常量或字符串文字,是0个或多个被双引号环绕的字符的序列。
- 如:
- "I am a string"
- 或
- "" /* 空字符串 */
- 双引号不属于字符内容,仅用来界定。
- 相同的转义序列,应用于字符常量中的,也应用于字符串。
- \"代表双引号字符。可以将多个字符串常量连接起来。
- "hello, " "world"
- 等价于
- "hello, world"


- 字符串常量是一个字符数组,由空字符'\0'来终止。
- 标准库函数strlen(s) 可以返回字符串参数s的长度,长度不包含末尾的‘\0’。
- 注意区分,一个字符常量和只含一个字符的字符串。
- 例:
- 'x'和"x"
- 前者是一个整数,用于产生字符x在机器字符集里的数值。
- 后者是一个字符数组,包含一个字符,'x',和一个'\0'


- 枚举常量是另外一种类型的常量。
- 枚举是常量整型值的列表。

声明

- 所有变量,在使用前需要声明。
- 特定声明,可能隐含表示。
- 一个声明,指定一个变量类型,且包含一个或多个该类型变量的列表。
- 一个声明语句中的多个变量可以拆开在多个声明语句中声明。

- 一个变量也可能在声明时被初始化。
- 如果声明,跟着一个等号和一个表达式,表达式就相当于一个初始化表达式,

- 如果变量不是自动变量,初始化仅能被执行一次。
- 概念上,在程序开始执行前。且初始化器必须是一个常量表达式。
- 一个显示初始化的自动变量,每次它所在的函数或程序块进入时,都将被初始化一次。
- 且初始化表达式可能是任何表达式。
- 外部变量和静态变量,默认被初始化为0。
- 自动变量,未显式初始化时值为 未定义的值(即无效值)。
- 任何变量的声明都可以使用const限定符限定。该限定符指定变量的值不能被修改。
- 对数组,const也可配合使用,它表明函数不能修改数组元素的值。
- const double e = 2.71828182845905;

算术运算符

- 二元算术运算符: +  -  *  /  %(取模运算符)
- %不能被应用于float或double
- 对于整数除法截断方向和对%结果符号,取决于机器。

关系运算符和逻辑运算符

- 关系运算符  >   >=   <   <=
- 相等性运算符 ==   !=
- 逻辑运算符  &&   ||
- 由 && 和 || 连接的表达式,按从左到右进行求值,一旦结果已知,求值停止。
- 逻辑非运算符 !,转换一个非0值变为0,一个0变为1

类型转换

-  一个表达式中存在隐士的类型转换,
-  一个表达式包含多项类型时,多个独立的项会被转换为统一的类型再进行运算,
-  常见的包含不同整型或包含整型和浮点时,
-  短整型会向可以包含它的长整型转换,整行会向浮点类型转换。
-  char可能被实现为无符号,或有符号类型。

-  可见的字符,在字符集中一般另其最高位为0,故在无符号或有符号实现下,当char转为int时,结果int都是正的。
-  但char中包含其他非可见字符时,最高为1时,在转换为int时,得到的是一个负数还是整数,依赖于char被实现为有符号还是无符号。
-  为了避免这类情形下的不确定,可以显式使用signed char,unsigned char

如果没有unsigned类型的操作数,则只要使用下面这些非正式的规则:

- 如果其中一个操作数的类型为long  double ,则将另一个操作数转换为 long double类型;
- 如果其中一个操作数的类型 double,则将另一个操作数转换为 double 类型;
- 如果其中一个操作数的类型 float,则将另一个操作数转换为 float 类型;
- 将 char 与 short 类型的操作数转换为 int 类型;
- 如果其中一个操作数的类型为 long ,则将另一个操作数页转换为 long 类型。

·

-  类型转换,先不考虑有符号和无符号。
-  首先对整型来说,每个整型有存储尺寸,而这在不同机器上是不同的。
-  假设一个运算设计n个整型操作数,
-  其中各个整型数中假设尺寸最大的为类型t。
-  则,
-  第一步,先确定所有操作数的统一类型。
-  原则为:
-  对n个类型进行排序,取出最大类型。
-  所有类型先转化为最大类型再参与运算。
-  排序规则:
-  若类型A尺寸小于类型B尺寸,则A小于B
-  类型A的有符号<类型A的无符号

-  如这样得出的类型尺寸小于int,直接将所有类型转化为int参与运算。

-  对于赋值或者强制类型转换,按指定的目标类型进行转换。
-  出现大类型转到小类型时,存在信息丢失问题。

自增运算符与自减运算符

- 自增运算符++使其操作数递增1,自减运算符--使其操作数递减1。
- 可以用作前缀运算符,也可用作后缀运算符
- 注意的是,++/-- A 或 A ++/-- 作为一个整体是一个表达式,存在一个表达式结果。
- 后++/--版本,整体表达式的值是未被改变的值。而变量值在操作后发生了自增/减1
- 前++/--版本,整体表达式的值是改变后的变量值。变量值在操作后发生了自增/减1
- 自增,自减运算符只能用于变量

位运算符

- 只能作用于整型操作数[带符号或无符号的char/short/init/long]
运算符描述
&按为与(AND)
|按位或 (OR)
^按位异或 (OR)
<<左移
>>右移
~按位求反(一元运算符)
/* getbits: get n bits from position p */
// 返回一个unsigned,低n位为x中我们感兴趣的n位。其余位为0。
unsigned getbits(unsigned x, int p, int n)
{
	// x >> (p+1-n)把x中不感兴趣的低位移除掉,同时保证此时处理后的unsigned的低n位即为我们感兴趣的
	// ~(~0 << n)构造一个unsigned类型数,低n位全部为1,其余部分全部为0
	return (x >> (p+1-n)) & ~(~0 << n);
}

赋值运算符和表达式

- 赋值运算符op=
- op可以是:+  -  *  /  %  <<  >>  &  ^  |
- expr1 op= expr2
- 等价于
- expr1 = (expr1) op (expr2)

- 例子:
x * = y + 1
含义是
x = x * (y+1)
而不是
x = x*y + 1

- 赋值表达式,作为一个整体的类型是左边操作数的类型,结果是复制后的结果。

条件表达

if ( a > b )
	z = a;
else
	z = b;
/* 用于求a 与 b 中的较大者,并将结果保存到z中  */

条件表达式(使用三元运算符“?:”)提供了另外一种方法编写这段程序及类似的代码段。

expr1 ? expr2 : expr3

在上述表达式中,首先计算expr1 ,如果其值不等于0(为真),则计算expr2的值,并以该值作为条件表达式的值,否则计算expr3的值,并以该值作为条件表达式的值。
expr2与expr3中只能有一个表达式被计算。
上述语句可以改写为:

z = (a > b) ? a : b;    /* z = max(a, b) */

如果expr1与expr3的类型不同,结果的类型将由转换规则决定。
例如 :如果 f 为 float 类型,n 为 int类型,那边表达.式

(n > 0)? f : n

是 float 类型,与 n 是否为正值无关。

运算符优先级与求值次序

运算符结合性
( ) [ ] -> .从左至右
! ~ ++ – + - * & (type) sizeof从右至左
* / %从左至右
+ -从左至右
<< >>从左至右
< <= > >=从左至右
== !=从左至右
&从左至右
^从左至右
|从左至右
&&从左至右
||从左至右
?:从右至左
= += -= *= /= %= &=从右至左
^= |= <<= >>=从左至右
从右至左
对&& / || / ?: / ,
操作数的求值顺序是被指定的。
/这属于语言陷阱,要避免因此而导致的不确定的代码。
其他运算符的情形下,参与运算的各个操作数的求值顺序是没有明确要求的,取决于实现。
类似的,调用多个形参的函数时,多个实参的求值顺序也是没有明确要求的。
// 该调用,多个实参求值顺序不同时,将产生不一致的结果,是要避免的。
	printf("%d %d\n", ++n, power(2, n));

	// 左右两边求值顺序不同时,产生不同结果。
	a[i] = i++;

参考:

https://blog.csdn.net/x13262608581/article/details/108061295

C程序设计语言  第2版*新版
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值