- 变量名
- 数据类型及长度
- 常量
- 声明
- 算术运算符
- 关系运算符和逻辑运算符
- 类型转换
- 自增运算符与自减运算符
- 位运算符
- 赋值运算符和表达式
- 条件表达
- 运算符优先级与求值次序
命名限制条件
- 名字是由字母和数字组成的序列,第一个字符必须为字母。 - 变量名不要以下划线“_”开头。 - 大写字母与小写字母要区分(即 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,也即null字符。 - 常量表达式是仅仅包含常量的表达式。 - 这样的表达式在编译时求值,而非运行时求值。可以出现在常量可以出现的任何位置。 - 一个字符串常量或字符串文字,是0个或多个被双引号环绕的字符的序列。 - 如: - "I am a string" - 或 - "" - 双引号不属于字符内容,仅用来界定。 - 相同的转义序列,应用于字符常量中的,也应用于字符串。 - "代表双引号字符。可以将多个字符串常量连接起来。 - "hello, " "world" - 等价于 - "hello, world" - 字符串常量是一个字符数组,由空字符' '来终止。 - 标准库函数strlen(s) 可以返回字符串参数s的长度,长度不包含末尾的‘ ’。 - 注意区分,一个字符常量和只含一个字符的字符串。 - 例: - 'x'和"x" - 前者是一个整数,用于产生字符x在机器字符集里的数值。 - 后者是一个字符数组,包含一个字符,'x',和一个' ' - 枚举常量是另外一种类型的常量。 - 枚举是常量整型值的列表。声明
- 所有变量,在使用前需要声明。 - 特定声明,可能隐含表示。 - 一个声明,指定一个变量类型,且包含一个或多个该类型变量的列表。 - 一个声明语句中的多个变量可以拆开在多个声明语句中声明。 - 一个变量也可能在声明时被初始化。 - 如果声明,跟着一个等号和一个表达式,表达式就相当于一个初始化表达式, - 如果变量不是自动变量,初始化仅能被执行一次。 - 概念上,在程序开始执行前。且初始化器必须是一个常量表达式。 - 一个显示初始化的自动变量,每次它所在的函数或程序块进入时,都将被初始化一次。 - 且初始化表达式可能是任何表达式。 - 外部变量和静态变量,默认被初始化为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) |
| << | 左移 |
| >> | 右移 |
| ~ | 按位求反(一元运算符) |
// 返回一个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;
条件表达式(使用三元运算符“?:”)提供了另外一种方法编写这段程序及类似的代码段。
expr1 ? expr2 : expr3
在上述表达式中,首先计算expr1 ,如果其值不等于0(为真),则计算expr2的值,并以该值作为条件表达式的值,否则计算expr3的值,并以该值作为条件表达式的值。
expr2与expr3中只能有一个表达式被计算。
上述语句可以改写为:
z = (a > b) ? a : b;
如果expr1与expr3的类型不同,结果的类型将由转换规则决定。
例如 :如果 f 为 float 类型,n 为 int类型,那边表达.式
(n > 0)? f : n
是 float 类型,与 n 是否为正值无关。
运算符优先级与求值次序| 运算符 | 结合性 |
|---|---|
| ( ) [ ] -> . | 从左至右 |
| ! ~ ++ – + - * & (type) sizeof | 从右至左 |
| * / % | 从左至右 |
| + - | 从左至右 |
| << >> | 从左至右 |
| < <= > >= | 从左至右 |
| == != | 从左至右 |
| & | 从左至右 |
| ^ | 从左至右 |
| | | 从左至右 |
| && | 从左至右 |
| || | 从左至右 |
| ?: | 从右至左 |
| = += -= *= /= %= &= | 从右至左 |
| ^= |= <<= >>= | 从左至右 |
| ’ | 从右至左 |
对&& / || / ?: / , 操作数的求值顺序是被指定的。 /这属于语言陷阱,要避免因此而导致的不确定的代码。 其他运算符的情形下,参与运算的各个操作数的求值顺序是没有明确要求的,取决于实现。 类似的,调用多个形参的函数时,多个实参的求值顺序也是没有明确要求的。
// 该调用,多个实参求值顺序不同时,将产生不一致的结果,是要避免的。
printf("%d %dn", ++n, power(2, n));
// 左右两边求值顺序不同时,产生不同结果。
a[i] = i++;
参考:
https://blog.csdn.net/x13262608581/article/details/108061295 C程序设计语言 第2版*新版



