🍇
type
status
date
slug
summary
tags
category
icon
password
Property
目录
K&C给出了7个与类型相关的关键字。C90标准添加了2个关键字,C99标准又添加了3个关键字
位、字节和字
- 位(bit) 来自英文 bit,音译为“比特”,表示二进制位。位是计算机内部数据储存的最小单位,11010100是一个 8 位二进制数。一个二进制位只可以表示 0 和 1 两种状态;两个二进制位可以表示 00、01、10、11 四种状态;三位二进制数可表示八种状态……。
- 字节(Byte)来自英文 Byte,音译为“拜特”,习惯上用大写的“B”表示。字节是计算机中数据处理的基本单位。计算机中以字节为单位存储和解释信息,规定一个字节由八个二进制位构成,即 1 个字节等于 8 个比特(1Byte=8bit)。八位二进制数最小为 00000000,最大为 11111111;通常 1 个字节可以存入一个 ASCII 码,2 个字节可以存放一个汉字国标码。
- 字(word) 计算机进行数据处理时,一次存取、加工和传送的数据长度称为字。一个字通常由一个或多个(一般是字节的整数位)字节构成。例如 286 微机的字由 2 个字节组成,它的字长为 16;486 微机的字由 4 个字节组成,它的字长为 32 位。计算机的字长决定了其 CPU 一次操作处理实际位数的多少,由此可见计算机的字长越大,其性能越优越。
🍇
type
status
date
slug
summary
tags
category
icon
password
Property
类型的级别从高至低依次是:long double、double、float、unsigned long long、long long、unsigned long、long、unsigned int、int。例外的情况是,当long 和 int 的大小相同时,unsigned int比long的级别高。之所以short和char类
型没有列出,是因为它们已经被升级到int或unsigned int。
自动类型转换
当类型转换出现在表达式时,无论是unsigned还是signed的char和short都会被自动转换成int,如有必要会被转换成unsigned int(如果short与int的大小相同,unsigned short就比int大。这种情况下,unsigned short会被转换成unsigned int)。在K&R那时的C中,float会被自动转换成double(目前的C不是这样)。由于都是从较小类型转换为较大类型,所以这些转换被称为升级。
涉及两种类型的运算,两个值会被分别转换成两种类型的更高级别
在赋值表达式语句中,计算的最终结果会被转换成被赋值变量的类型。这个过程可能导致类型升级或降级。所谓降级,是指把一种类型转换成更低级别的类型。
当作为函数参数传递时,char和short被转换成int,float被转换成double。
类型升级通常都不会有什么问题,但是类型降级会导致真正的麻烦。原因很简单:较低类型可能放不下整个数字。
如果待转换的值与目标类型不匹配怎么办?这取决于转换涉及的类型。待赋值的值与目标类型不匹配时,规则如下。
1.目标类型是无符号整型,且待赋的值是整数时,额外的位将被忽略。
2.如果目标类型是一个有符号整型,且待赋的值是整数,结果因实现而异。
3.如果目标类型是一个整型,且待赋的值是浮点数,该行为是未定义的。
🍈
type
status
date
slug
summary
tags
category
icon
password
Property
C库包含了多个输入函数,
scanf()
是最通用的一个,因为它可以读取不同格式的数据。当然,从键盘输入的都是文本,因为键盘只能生成文本字符:字母、数字和标点符号。如果要输入整数 2014,就要键入字符 2、0、1、4。如果要将其储存为数值而不是字符串,程序就必须把字符依次转换成数值,这就是
scanf()
要做的。scanf()
把输入的字符串转换成整数、浮点数、字符或字符串,而printf()
正好与它相反,把整数、浮点数、字符和字符串转换成显示在屏幕上的文本。
scanf()
和printf()
类似,也使用格式字符串和参数列表。scanf()
中的格式字符串表明字符输入流的目标数据类型。两个函数主要的区别在参数列表中。printf()
函数使用变量、常量和表达式,而scanf()
函数使用指向变量的指针。这里只需记住以下两条简单的规则:- 如果用
scanf()
读取基本变量类型的值,在变量名前加上一个&;
- 如果用
scanf()
把字符串读入字符数组中,不要使用&。
scanf()
函数使用空白(换行符、制表符和空格)把输入分成多个字段。在依次把转换说明和字段匹配时跳过空白。只要在每个输入项之间输入至少一个换行符、空格或制表符即可,可以在一行或多行输入。唯一例外的是%c转换说明。根据%c,scanf()会读取每个字符,包括空白。
scanf()的转换说明
scanf()
函数所用的转换说明与printf()
函数几乎相同。主要的区别是,对于float类型和double类型,printf()都使用%f、%e、%E、%g和%G转换说明。而scanf()只把它们用于float类型,对于double类型时要使用l修饰符。🍉
type
status
date
slug
summary
tags
category
icon
password
Property
表达式(expression)由运算符和运算对象组成,最简单的表达式是一个单独的运算对象,以此为基础可以建立复杂的表达式。下面是一些表达式:
运算对象可以是常量、变量或二者的组合。一些表达式由子表达式(较小的表达式)组成。
C 表达式的一个最重要的特性是,每个表达式都有一个值。要获得这个值,必须根据运算符优先级规定的顺序来执行操作。
有赋值运算符(=)的表达式的值是什么?这些表达式的值与赋值运算符左侧变量的值相同。因此,表达式
q = 5*2
作为一个整体的值是10。表达式
q > 3
的值是多少?这种关系表达式的值不是0就是1,如果条件为真,表达式的值为1;如果条件为假,表达式的值为0。语句是C程序的基本构建块。一条语句相当于一条完整的计算机指令。在C中,大部分语句都以分号结尾。因此,
legs = 4
只是一个表达式,而legs = 4;
则是一条语句。🍋
type
status
date
slug
summary
tags
category
icon
password
Property
使用了starbar标识符:函数原型告诉编译器函数
starbar()
的类型;函数调用表明在此处执行函数;函数定义明确地指定了函数要做什么。函数原型
函数和变量一样,有多种类型。任何程序在使用函数之前都要声明该函数的类型。因此,在
main()
函数定义的前面出现了下面的ANSI C风格的函数原型:圆括号表明starbar是一个函数名。第1个void是函数类型,void类型表明函数没有返回值。第2个void(在圆括号中)表明该函数不带参数。分号表明这是在声明函数,不是定义函数。
这行声明了程序将使用一个名为starbar()、没有返回值、没有参数的函数,并告诉编译器在别处查找该函数的定义。对于不识别ANSI C风格原型的编译器,只需声明函数的类型,如下所示:
🍋
type
status
date
slug
summary
tags
category
icon
password
Property
函数定义
函数定义从下面的ANSI C风格的函数头开始:
该行告知编译器
show_n_char()
使用两个参数ch和num,ch是char类型,num是int类型。这两个变量被称为形式参数,简称形参。和定义在函数中变量一样,形式参数也是局部变量,属该函数私有。这意味着在其他函数中使用同名变量不会引起名称冲突。每次调用函数,就会给这些变量赋值。虽然
show_n_char()
接受来自main()
的值,但是它没有返回值。因此show_n_char()
的类型是void。注意:ANSI C要求在每个变量前都声明其类型。也就是说,不能像普通变量声明那样使用同一类型的变量列表:
🍋
type
status
date
slug
summary
tags
category
icon
password
Property
前面介绍了如何把信息从主调函数传递给被调函数。反过来,函数的返回值可以把信息从被调函数传回主调函数。
关键字return后面的表达式的值就是函数的返回值。在该例中,该函数返回的值就是变量min的值。因为min是int类型的变量,所以
imin()
函数的类型也是int。
变量min属于
imin()
函数私有,但是return语句把min的值传回了主调函数。下面这条语句的作用是把min的值赋给lesser:imin()
中的变量是imin()
的局部变量。函数调用imin(evil1, evil2)
只是把两个变量的值拷贝了一份。返回值不仅可以赋给变量,也可以被用作表达式的一部分。例如,可以这样: