C语言自学《二》下篇---- 类型的转换、字符类型、枚举、数学函数
2014-03-16 23:16
459 查看
类型的转换
下面是一个错误的输出,不过通过注释给出了解决办法,就是通过编译器自动类型转换
<!-- lang: cpp --> int main(void){ //定义了一个float浮点型常量 const float Revenue_Per_150 = 4.5f; short JanSold = 23500; short FebSold = 19300; short MarSold = 21600; float RevQuarter = 0.0f; //错误一:总销量的值为64400,这个值超出了short类型的最大取值范围 //short最大取值范围为32767 unsigned long QuarterSold = JanSold + FebSold + MarSold; //错误!输出为负数! //输出每月分别的销量 printf("Stock sold in\nJan:%hd\nFeb:%hd\nMar:%hd\n",JanSold,FebSold,MarSold); //输出一个季度的销量 printf("Total stock sold in first quarter: %ld\n",QuarterSold); //比实际结果值少了1.50 //由于QuarterSold是一个整数,所以计算机将除以150后的结果429.333四舍五入 //所以发生了错误,丢失了精度 //解决此问题的第一个方法:改变下面的运算表达式顺序为: //RevQuarter = Revenue_Per_150 * QuarterSold / 150; 这样计算就正确了 //第二种解决办法:把150.0作为除数,如下: //RevQuarter = QuarterSold / 150.0 * Revenue_Per_150; RevQuarter = QuarterSold / 150 * Revenue_Per_150; //错误!输出为$1930.50! printf("Sales revenue this quarter is:$%.2f\n",RevQuarter); }
强制类型转换
像上面的实例,如果可以把QuarterSold的值转换为float类型,该表达式就会议浮点数的方式计算,问题就解决了要把变量从一种类型转换为另一种类型,应该把目标类型放在变量前面的括号中,这种显示的转换称为强制类型转换。
下面是表达式和普通强制转换类型的例子
<!-- lang: cpp --> //经过像下面这样修改,进行强制的类型转换 //经过修改后的表达式,在正确的地方使用正确类型的变量 //当希望保留除法结果的小数部分时,不应使用整数运算 RevQuarter = (float)QuarterSold / 150 * Revenue_Per_150; //也可以把表达式的结果从一种类型强转为另一种类型,像下面这样: double result = 0.0; int a = 5; int b = 8; result = (double)(a + b) / 2 - (a + b) / (double)(a * a + b * b);
自动类型转换
编译器在处理设计不同类型的值操作时,会按照一定规则吧其中一个操作数的类型转换为另一个操作数的类型,这称为隐式类型转换(implicit conversion)还是这个例子
<!-- lang: cpp --> //下面的二元运算就进行了隐式自动转换,可以分解成下面的样子 //QuarterSold(64400 int) / 150(int) = 429(四舍五入,舍去了小数部分) // 429(int) * Revenue_Per_150(4.5 float) = 1930.5(float) // 在上个步骤中,由于int类型的值域小于float类型,所以自动将int转为float类型 RevQuarter = QuarterSold / 150 * Revenue_Per_150;
隐式类型转换规则
基本规则是:将值较小的操作数类型转换为另一个操作数类型,但在一些情况下,两个操作数都要转换类型
以下的规则从高到低排列
如果是
long double,就把另一个操作数转换为
long double
否则,如果是
double,就把另一个操作数转换为
double
否则,如果是
float,就把另一个操作数转换为
float
否则,如果两个操作数的类型
都是带符号或无符号的整数,就把级别较低的操作数转换为另一个操作数类型
从左到右从低到高(无符号和有符号级别一样): char,short,int,long,long long
否则,如果带符号整数类型的操作数级别低于无符号整数类型的级别,就把带符号整数类型的操作数转换为无符号整数类型
否则,如果带符号整数类型的值域包含了无符号整数类型所表示的值,就把无符号整数类型转换为带符号整数类型
否则,两个操作数都转换为带符号整数类型对应的无符号整数类型
赋值语句中的隐式类型转换
下面的例子表示了赋值语句的隐式转换
<!-- lang: cpp --> int main(void){ //好吧,别看下面一大长串,其实按照上面的规则很简单就能看清是如何隐式转换的 //首先count(long)转换为double类型,ship_cost(float)也转换为double类型 //然后discount(int)转换为long类型,long类型再转换为float类型 //经过两个括号中的计算与转换,现在是下面这样的类型表达式 //long double = double * float //然后float转换为double //最后double转换为long double //因为long double包含double,所以没有丢失精度 double price = 10.0; long count = 5L; float ship_cost = 2.5F; int discount = 15; long double total_cost = (count * price + ship_cost) * ((100L - discount) / 100.0F); }
字符类型
字符的类型定义及赋值
在所有数据类型中,char类型占用的内存空间最少,它可以存储单个字符,它也只能存储一个整数,所以被看成为整数类型,也可以在算术运算中使用它,它的区间是0~255(signed)或者-128~127(unsigned)单引号内的字符代码,实际的代码值取决于计算机环境,但最常见的是美国标准信息交换吗(ASCII)
代码示例:
<!-- lang: cpp --> //下面是给char类型变量指定字符常量,用' '单引号括起来 char letter = 'A'; char digit = '9'; char exclamation = '!'; //也可以使用转义序列指定字符常量 char newline = '\n'; char tab = '\t'; char single_quote = '\'; //还可以用整数值初始化char类型变量 char character = 74; //解释为J //使用char进行算术计算 char letter = 'C'; letter += 3;
字符的输入输出
使用scanf()函数和格式说明符
%c,可以从键盘上读取单个字符
同样用
%c可以输出字符,用
%d输出字符对应的整数
代码示例:
<!-- lang: cpp --> #include <stdio.h> int main(){ char ch = 0; scanf("%c",&ch); //获取键盘输入为字符类型,存储到ch字符变量中 //下面的输出分别为一个字符和一个数值 printf("The character is %c and the code value is %d\n", ch, ch); }
如果要转换字符的大小写,可以使用标准库
<ctype.h>头文件提供的
toupper()和
tolower()函数
枚举
定义枚举类型和枚举变量
利用枚举,可以定义一个新的整数类型,该类型变量的值域是我们指定的几个可能值,下面语句定义了枚举类型代码示例:
<!-- lang: cpp --> //下面这个语句定义了一个类型,而不是变量,新类型的名称为Weekday,称为枚举的标记 //大括号中的值称为枚举常量或者叫做枚举器,枚举是一个整数类型,默认从0开始,比如Monday的值就是0,然后逐个递增 enum Weekday {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday}; //可以声明Weekday类型的一个新变量,并初始化它,如下所示: //today的值为2 enum Weekday today = Wednesday; //或者像下面这样,定义枚举类型时,声明该类型的变量 enum Weekday {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday} today, tomorrow; //当然也可以直接初始化 enum Weekday {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday} today=Monday, tomorrow=Tuesday; //由于是整数类型,所以也可以在算术表达式中使用 //要确保给定的枚举类型使用有效的枚举值 enum Weekday {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday} today=Monday, tomorrow = today + 1;
未命名的枚举类型
未命名枚举类型的主要限制是,必须在定义该类型的语句中声明它的所有变量,由于没有类型标记名,因此无法在代码的后面定义该类型的其他变量代码示例:
<!-- lang: cpp --> enum {red, orange, yellow, green, blue, indigo, violet} shirt_color; shirt_color = blue;
存储布尔值变量
_Bool类型存储布尔值,它由true或false组成,前者为1后者为0,所以_Bool类型也被看为整数类型也可以用bool作为类型名称,这看起来更简洁,但是要包含
<stdbool.h>头文件
代码示例:
<!-- lang: cpp --> #include <stdbool.h> int main(){ _Bool valid = 1; //true _Bool valid = 0; //false _Bool valid = true; _Bool valid = false; bool valid = 1; bool valid = 0; bool valid = true; bool valid = false; }
数学函数
<math.h>头文件包含各种数学函数的声明,所有的函数都返回一个double类型
不过通过在函数后面添加
l或
f,分别可以返回
long double或
float类型
这里就不详细列举数学函数了,用时再查找
相关文章推荐
- 函数返回值C语言中malloc函数返回值是否需要类型强制转换问题
- C语言-自定义函数,及其调用;函数返回值类型的自动转换,即其数量;
- C语言标准库函数--数学函数、字符(串)处理函数
- C#初级篇---类型转换、枚举、结构体、数组、函数、
- 5.单行函数,多行函数,字符函数,数字函数,日期函数,数据类型转换,数字和字符串转换,通用函数(case和decode)
- 类型转换 格式化函数 及各种数学函数
- C语言学习4: 函数返回值与传入参数,关于函数值传递和类型隐性转换,变量不同的作用域,static变量,多文件编译例如两个C文件,显示函数调用语句跳转,递归,斐波那契数列,多文件编译相同变量的问题。
- C语言标准库函数--数学函数、字符(串)处理函数
- 《C++标准函数库》中说的有三个函数可以将字符串的内容转换为字符数组和C—string (CString、char*、String三种类型互换)
- C语言itoa()函数和atoi()函数详解---整数与字符互相转换C函数
- C语言标准库函数--数学函数、字符(串)处理函数
- 【c语言】为下面的函数原型编写函数定义,这个字符串参数必须包含一个或者多个数字,函数应该把这些数字字符转换为整数并返回这个整数。
- 【C语言】为下面的函数原型编写函数定义: int ascii_to_integer(char *str); 这个字符串参数必须包含一个或者多个数字,函数应该把这些数字字符转换为整数并返回这个整数。
- leetcode_345. Reverse Vowels of a String 转换字符串中的元音字符,list类型数据转换成str类型,join()函数
- 三个C语言中字符转换的函数
- C语言—如何将字符数组转换为int类型
- 数学类型与字符类型相互转换
- C语言学习9: malloc动态内存存储,动态内存分配去空格字符增长版,动态内存分配去符号incr增长版,型参和返回值都是int型的函数的指针,main函数的地址也可以用指针指向,typedef定义函数指针,函数定义与嵌套的作用,返回函数指针类型,const作用
- 枚举类型互相转换(使用GetEnumName和TypeInfo两个函数)
- C语言技巧【枚举作为函数变量类型】【数据输入与输出】【do while循环体内scanf函数被跳过,循环结束】【用const修饰函数的参数】