基本数据类型和数
算数类型和基本数据类型
算数类型是多种数据类型的统称,大体上可分为两种类型:整数类数据和浮点型数据。
字符型、整型和浮点型统称为基本数据类型。
基数
这里的基数指的就是十六进制、十进制、八进制、二进制数。
基数转换
基数转换指的就是进制之间的转换
整型和字符型
整型和字符型是用来表示限定范围内连续整数的数据类型。
整型分为无符号整数和有符号整数,其数据类型定义分别如下:
1 2 3 int x; signed int y; unsigned int z
数据类型汇总
头文件 limits.h
C语言编译器在 <limits.h> 文件中以宏定义的形式定义了字符型以及其他整数型所能表示的数值的最小值和最大值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 #pragma once #define _INC_LIMITS #include <vcruntime.h> #pragma warning (push) #pragma warning (disable: _VCRUNTIME_DISABLED_WARNINGS) _CRT_BEGIN_C_HEADER #define CHAR_BIT 8 #define SCHAR_MIN (-128) #define SCHAR_MAX 127 #define UCHAR_MAX 0xff #ifndef _CHAR_UNSIGNED #define CHAR_MIN SCHAR_MIN #define CHAR_MAX SCHAR_MAX #else #define CHAR_MIN 0 #define CHAR_MAX UCHAR_MAX #endif #define MB_LEN_MAX 5 #define SHRT_MIN (-32768) #define SHRT_MAX 32767 #define USHRT_MAX 0xffff #define INT_MIN (-2147483647 - 1) #define INT_MAX 2147483647 #define UINT_MAX 0xffffffff #define LONG_MIN (-2147483647L - 1) #define LONG_MAX 2147483647L #define ULONG_MAX 0xffffffffUL #define LLONG_MAX 9223372036854775807i64 #define LLONG_MIN (-9223372036854775807i64 - 1) #define ULLONG_MAX 0xffffffffffffffffui64 #define _I8_MIN (-127i8 - 1) #define _I8_MAX 127i8 #define _UI8_MAX 0xffui8 #define _I16_MIN (-32767i16 - 1) #define _I16_MAX 32767i16 #define _UI16_MAX 0xffffui16 #define _I32_MIN (-2147483647i32 - 1) #define _I32_MAX 2147483647i32 #define _UI32_MAX 0xffffffffui32 #define _I64_MIN (-9223372036854775807i64 - 1) #define _I64_MAX 9223372036854775807i64 #define _UI64_MAX 0xffffffffffffffffui64 #ifndef SIZE_MAX #ifdef _WIN64 #define SIZE_MAX 0xffffffffffffffffui64 #else #define SIZE_MAX 0xffffffffui32 #endif #endif #if __STDC_WANT_SECURE_LIB__ #ifndef RSIZE_MAX #define RSIZE_MAX (SIZE_MAX >> 1) #endif #endif _CRT_END_C_HEADER #pragma warning (pop)
通过调查这些宏的值,就可以判定自己使用的编译器中各数据类型所能表示的数值范围。
代码清单7-1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> int main (void ) { puts ("该环境下各字符型、整型数值的范围" ); printf ("char :%d~%d\n" , CHAR_MIN, CHAR_MAX); printf ("signed char :%d~%d\n" , SCHAR_MIN, SCHAR_MAX); printf ("signed char :%d~%d\n" , 0 , UCHAR_MAX); printf ("short :%d~%d\n" , SHRT_MIN, SHRT_MAX); printf ("int :%d~%d\n" , INT_MIN, INT_MAX); printf ("long :%d~%d\n" , LONG_MIN, LONG_MAX); printf ("unsigned short :%d~%d\n" , 0 , USHRT_MAX); printf ("unsigned :%d~%d\n" , 0 , UINT_MAX); printf ("unsigned long :%d~%d\n" , 0 , LONG_MAX); return 0 ; }
字符型
char 型是用来保存 “字符” 的数据类型。
对于没有声明 signed 和 unsigned 的char 型,视为有符号类型还是无符号类型,由编译器决定。
代码清单7-2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> int main (void ) { printf ("这个编译器中的char型是" ); if (CHAR_MIN) puts ("有符号的。" ); else puts ("无符号的。" ); return 0 ; }
char 类型的数据大小是 CHAR_BIT(8位) 就是一字节。
sizeof 运算符
sizeof 运算符可以判断出所有数据类型的长度,该运算符以字节为单位。
代码清单7-3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> int main (void ) { printf ("sizeof (char) = %u\n" , (unsigned )sizeof (char )); printf ("sizeof (short) = %u\n" , (unsigned )sizeof (short )); printf ("sizeof (int) = %u\n" , (unsigned )sizeof (int )); printf ("sizeof (long) = %u\n" , (unsigned )sizeof (long )); return 0 ; }
sizeof运算符功能是由编译器实现,并未产生相应的汇编代码。
size_t型和typedef 声明
由 sizeof 运算符生成的值的数据类型在 <stddef.h> 头文件中定义的 size_t 型。在许多编译器中用 typedef 声明来定义 size_t 型。
size_t 是无符号字符(unsigned)的别称,该类型主要是为了让代码易读。
整型的灵活运用
通常,int 型是程序运行环境中最容易处理并且可以高速运算的数据类型。在有些 sizeof(long) 大于 sizeof(int) 的编译器中,long型的运算比 int 型更耗时。因此只要不处理特别大的数值,还是尽量使用 int 型比较好。
这主要是因为在32位系统中,寄存器的大小和int型都是32位的数据,数据处理起来方便。如果数据类型超过32位或小于32位处理起来就比较麻烦,程序所耗费的时间也就越长。
代码清单7-4
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> int main (void ) { int na, nb; double dx, dy; printf ("sizeof(int) = %u\n" , (unsigned )sizeof (int )); printf ("sizeof(double) = %u\n" , (unsigned )sizeof (double )); printf ("sizeof(na) = %u\n" , (unsigned )sizeof (na)); printf ("sizeof(dx) = %u\n" , (unsigned )sizeof (dx)); printf ("sizeof(na+nb) = %u\n" , (unsigned )sizeof (na+nb)); printf ("sizeof(na+dy) = %u\n" , (unsigned )sizeof (na+dy)); printf ("sizeof(dx+dy) = %u\n" , (unsigned )sizeof (dx+dy)); return 0 ; }
将 sizeof 运算符应用于数组,就可以得到数组整体的大小。
代码清单7-5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> int main (void ) { int vi[10 ]; double vd[25 ]; printf ("数组vi的元素个数 = %u\n" , (unsigned )(sizeof (vi) / sizeof (vi[0 ]))); printf ("数组vd的元素个数 = %u\n" , (unsigned )(sizeof (vi) / sizeof (vd[0 ]))); return 0 ; }
按位操作运算符
位运算符
功能
&
逻辑与
|
逻辑或
^
逻辑异或
~
反码
注意:这里要把 “逻辑运算符”(&&、||、!) 和 “按位逻辑运算符” (&、|、~)区分开。
代码清单7-6
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> int count_bits (unsigned x) { int bits = 0 ; while (x) { if (x & 1U ) bits++; x >>= 1 ; } return bits; } int int_bits (void ) { return count_bits(~0U ); } void print_bits (unsigned x) { int i; for (i = int_bits() - 1 ; i >= 0 ; i--) putchar (((x>> i) & 1U ) ? '1' : '0' ); } int main (void ) { unsigned a, b; printf ("请输入两个非负整数。\n" ); printf ("a:" ); scanf ("%u" , &a); printf ("b:" ); scanf ("%u" , &b); printf ("\na = " ); print_bits(a); printf ("\nb = " ); print_bits(b); printf ("\na & b = " ); print_bits(a&b); printf ("\na | b = " ); print_bits(a|b); printf ("\na ^ b = " ); print_bits(a^b); printf ("\n~a = " ); print_bits(a); printf ("\n~b = " ); print_bits(~b); putchar ('\n' ); return 0 ; }
位移运算符
代码清单7-7
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> int count_bits (unsigned x) { int bits = 0 ; while (x) { if (x & 1U ) bits++; x >>= 1 ; } return bits; } int int_bits (void ) { return count_bits(~0U ); } void print_bits (unsigned x) { int i; for (i = int_bits() - 1 ; i >= 0 ; i--) putchar (((x>> i) & 1U ) ? '1' : '0' ); } int main (void ) { unsigned a, b; printf ("请输入非负整数。\n" ); printf ("a:" ); scanf ("%u" , &a); printf ("位移位数:" ); scanf ("%u" , &b); printf ("\n整数 = " ); print_bits(a); printf ("\na左移后的值 = " ); print_bits(a<<b); printf ("\na右移后的值 = " ); print_bits(a>>b); putchar ('\n' ); return 0 ; }
整数常量
十进制常量:10、57等等
八进制常量:010、057
十六进制常量:0x10、0x57
整型常量的数据类型
在 limits.h 文件中,整型常量附带 U 和 L 等符号,这些符号称为整型后缀。
u/U 表示该整型常量为无符号类型(unsigned)
l/L 表示该整型常量为 long 型(long)
u/U和l/L 表示整数常量无符号 long 型(unsigned long)
整数的显示
pritnf函数:“%d” 输出十进制数,“%o” 输出八进制数,“%x” 输出十六进制数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> int count_bits (unsigned x) { int bits = 0 ; while (x) { if (x & 1U ) bits++; x >>= 1 ; } return bits; } int int_bits (void ) { return count_bits(~0U ); } void print_bits (unsigned x,unsigned n) { int i=int_bits(); i=(n<i)?n-1 :i-1 ; for (; i >= 0 ; i--) putchar (((x>> i) & 1U ) ? '1' : '0' ); } int main (void ) { unsigned i; for (i = 0 ; i <= 65535U ; i++) { printf ("%5u" , i); print_bits(i, 16 ); printf ("%06o %04x\n" , i, i); } return 0 ; }
数据溢出和异常
溢出
有符号数运算的溢出
无符号数运算的溢出
异常
在算数运算中常见的除法异常。
算数运算中的溢出和异常汇编中都学过,就不再去重复写代码验证了。
浮点型
浮点型数据类型
浮点型用来表示带有小数部分的实数。浮点型有以下3中类型。
float:单精度浮点型。
double:双精度浮点型。
long double:长双精度浮点型。
代码清单7-9
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 int main (void ) { float x=123456789012345678901234567890.0 ; double y=123456789012345678901234567890.0 ; long double z=123456789012345678901234567890.0 ; printf ("x = %f\n" , x); printf ("y = %lf\n" , y); printf ("z = %llf\n" , z); printf ("单精度浮点型宽度:%d\n双精度浮点型宽度:%d\n长双精度浮点型宽度:%d" , sizeof (float ), sizeof (double ), sizeof (long double )); return 0 ; }
long double 类型不是原始的C标准类型。C99中才添加了这种类型。而在C99及后续规范中,该类型的规定也不详细,只是要求long double 类型在精度上需要不少于double的精度。于是出现了有的编译器不支持long double,而支持的编译器在实现上也有区别,目前常见的long double有占8字节,10字节,12字节和16字节四种,单输出格式都是相同的 %llf。
浮点数转换为二进制原理
浮点数转换为二进制数据分为如下几步:
将十进制的浮点数转换为二进制浮点数
浮点数的二进制值由三个部分组成:符号位(1位) 指数位(8位) 尾数位(23位)
根据浮点数的正负值确定符号位
移动小数点的位置确定指数部分
将小数点后的位放在尾数部分
1、将十进制浮点数以二进制浮点数表示
将十进制浮点数的整数部分循环除以2,取余数并倒序排序作为整数部分二进制值。
将小数部分乘以2,取整数作为小数部分的二进制值。
案例:十进制小数 3.1 转换为二进制形式
整数部分:
小数部分:
1 2 3 4 5 6 7 8 9 10 11 12 13 0.1*2=0.2...0 0.2*2=0.4...0 0.4*2=0.8...0 0.8*2=1.6...1 0.6*2=1.2...1 0.2*2=0.4...0 0.4*2=0.8...0 0.8*2=1.6...1 0.6*2=1.2...1 0.2*2=0.4...0 0.4*2=0.8...0 0.8*2=1.6...1 0.6*2=1.2...1
最终结果:11.0001100010001100011000
因为小数部分的计算丢弃了小数点后面的值因此这也就导致了小数的计算结果并不准确,而计算机存储的二进制又有限,这就导致计算机在运算浮点数的结果都是近似值。
2、将二进制浮点数转换成二进制数据
符号位:如果是正数值为0,负数为1
指数位:左移或右移小数点,浮点数的二进制表示形式的整数位只有1位,且值必须是1。指数位默认值是127,如果是左移 “指数位=【127+左移位数】”,如果是右移“指数位=【127-右移位数】”
尾数位:将二进制表示形式的小数点后面的值作为尾数。
根据以上规则得出结果小数3.1存储的二进制值如下:
符号位:0
指数位:11.0001100010001100011000 = 1.10001100010001100011000*2^1;127+1=128=1000 0000
尾数位:10001100010001100011000
最终结果:0 10000000 1000110011001100110010 = 0x4046 6666
单精度浮点数尾数是23位,双精度浮点数尾数位是52位。
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> void WriteBin (int x,const int n) { char * str = "%c" ; int * addr = &x; __asm { xor ebx,ebx mov ecx, n mov esi, addr add esi, n WriteBin1: push ecx dec esi mov bl, byte ptr[esi] mov ecx,8 ByteToBits1: push ecx shl bl,1 jnc ByteToBits2 mov eax, '1' jmp ByteToBits3 ByteToBits2: mov eax, '0' ByteToBits3: push eax push str call printf add esp,8 pop ecx loop ByteToBits1 pop ecx loop WriteBin1 } } void floatB (float x) { int a = abs (x); int b = 127 ; char mantissa[26 ] = { 0 }; int index = 0 ; float c = 0 ; int * Ufloat = &x; int i, n; puts ("浮点数转换为二进制表示形式:" ); for (int k = 0 ; a != 0 ; k++) { mantissa[k] = a % 2 ; a /= 2 ; index = k; } for (int k = index; k >= 0 ; k--) { printf ("%d" , mantissa[k]); } printf ("." ); a = abs (x); if (x > 0 ) { c = x - a; } else { c = -(x + a); } for (int k = index + 1 ; k < 24 ; k++) { c *= 2 ; printf ("%d" , (int )c); mantissa[k] = c; if (c >= 1 ) { c -= 1 ; } } puts ("\n\n内存中存储的值:" ); puts ("符号位---指数位---尾数位" ); if (x > 0 ) { printf (" 0 " ); } else { printf (" 1 " ); } a = abs (x); if (a == 0 ) { index -= 1 ; for (int j = 1 ; mantissa[j] == 0 ; j++) { index -= 1 ; } } WriteBin(127 + index, 1 ); printf (" " ); if (index < 0 ) { for (int k = 0 ; k < 24 ; k++) { printf ("%d" , mantissa[k]); } } else { for (int k = 1 ; k < 24 ; k++) { printf ("%d" , mantissa[k]); } } printf ("\n\n浮点表示法:%.16f" , x - 0.00000000000000001 ); printf ("\n\n浮点数的十六进制值:%x" , Ufloat[0 ]); } int main (void ) { float x = 3.1 ; floatB(x); return 0 ; }
<math.h> 头文件
C语言提供了基本的数学函数来支持科学计算。<math.h>文件中包含了这些函数的声明。
代码清单7-10
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> #include <math.h> double dist (double x1,double y1,double x2,double y2) { return sqrt (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1); } int main (void ) { double x1, y1; double x2, y2; printf ("求两点间的距离。\n" ); printf ("点1...X坐标" ); scanf ("%lf" , &x1); printf (" Y坐标" ); scanf ("%lf" , &y1); printf ("点2...X坐标" ); scanf ("%lf" , &x2); printf (" Y坐标" ); scanf ("%lf" , &y2); printf ("两点之间的距离为%f。\n" , dist(x1, y1, x2, y2)); return 0 ; }
循环的控制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> int main (void ) { float x; for (x = 0.0 ; x <= 1.0 ; x += 0.01 ) { printf ("x=%f\n" , x); } return 0 ; }
这里因为浮点运算只能取近似值的关系,导致最终结果为0.999999,并不能达到0.1
代码清单7-12
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> int main (void ) { int i; float x; for (i = 0 ; i <= 100 ; i++) { x = i / 100.0 ; printf ("x=%f\n" , x); } return 0 ; }
这里不以浮点数作为循环变量,而是以运算方式(整数/浮点数)来取得运算结果。
运算和运算符
运算符优先级不需要考虑,要优先运算哪个就在那里加个小括号。
数据类型转换
总结
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> int main (void ) { int i, no; float value; float sum = 0.0f ; puts ("对浮点数进行多次加法运算。" ); printf ("值" ); scanf ("%f" , &value); printf ("次数:" ); scanf ("%d" , &no); for (i = 0 ; i < no; i++) sum += value; printf ("加法运算的结果是%f。\n" , sum); return 0 ; }
练习
练习7-1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> int main (void ) { int n; printf ("%d\n" , sizeof 1 ); printf ("%d\n" , sizeof +1 ); printf ("%d\n" , sizeof -1 ); printf ("%d\n" , sizeof (unsigned )-1 ); printf ("%d\n" , sizeof (double )-1 ); printf ("%d\n" , sizeof ((double )-1 )); printf ("%d\n" , sizeof n+2 ); printf ("%d\n" , sizeof (n + 2 )); printf ("%d\n" , sizeof (n + 2.0 )); return 0 ; }
练习7-2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> int main (void ) { unsigned int n = 4 ; printf ("n左移2位的值:%d,n乘以2的2次幂的值:%d\n" , n << 2 , n * 4 ); printf ("n右移2位的值:%d,n除以2的2次幂的值:%d\n" , n >> 2 , n / 4 ); return 0 ; }
练习7-3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> unsigned rrotate (unsigned x,int n) { return x >> n; } unsigned lrotate (unsigned x, int n) { return x << n; } int main (void ) { unsigned int x = 4 ; int n = 2 ; printf ("%d左移%d位的值:%d\n" , x,n,lrotate(x, n)); printf ("%d右移%d位的值:%d\n" , x,n,rrotate(x, n)); return 0 ; }
练习7-4
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> unsigned set (unsigned x,int pos) { int pos1 = (1 << (pos - 1 )); int n = x & pos1; if (n != pos1) { return x | pos1; } return x; } unsigned reset (unsigned x, int pos) { int pos1 = (1 << (pos - 1 )); int n = x & pos1; if (n == pos1) { return x ^ pos1; } return x; } unsigned inverse (unsigned x, int pos) { int pos1 = (1 << (pos - 1 )); return x ^ pos1; } int main (void ) { printf ("%d" ,set (13 , 1 )); return 0 ; }
练习7-5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> unsigned set_n (unsigned x,int pos,int n) { int a = 0 ; int pos1 = 0 ; int buffer = x; for (int i = 1 ;i<=n; i++) { pos1 = (1 << (pos - i)); a = x & pos1; if (a != pos1) { buffer |= pos1; } } return buffer; } unsigned reset_n (unsigned x, int pos,int n) { int a = 0 ; int pos1 = 0 ; int buffer = x; for (int i = 1 ; i <= n; i++) { pos1 = (1 << (pos - i)); a = buffer & pos1; if (a == pos1) { buffer ^= pos1; } } return buffer; } unsigned inverse_n (unsigned x, int pos,int n) { int a = 0 ; int pos1 = 0 ; int buffer = x; for (int i = 1 ; i <= n; i++) { int pos1 = (1 << (pos - i)); buffer ^= pos1; } return buffer; } int main (void ) { printf ("%d" , inverse_n(128 ,4 ,4 )); return 0 ; }
练习7-6
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> void flow (unsigned x, unsigned y) { unsigned sum = x + y; if (sum < x|sum < y) { printf ("CF=1" ); } else { printf ("CF=0" ); } } int main (void ) { flow(4294967295 , 10 ); return 0 ; }
练习7-7
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> int main (void ) { float a; double b; long double c; printf ("请输入float类型的变量:" ); scanf ("%f" , &a); printf ("请输入double类型的变量:" ); scanf ("%lf" , &b); printf ("请输入long double类型的变量:" ); scanf ("%lf" , &c); printf ("%f \n%.15f \n%.15f" , a, b, c); return 0 ; }
练习7-8
1 2 3 4 5 6 7 8 9 10 11 12 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> int main (void ) { printf ("%d \n%d \n%d" , sizeof (float ), sizeof (double ), sizeof (long double )); return 0 ; }
练习7-9
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> #include <math.h> int main (void ) { float a = 0 ; printf ("请输入正方形面积(实数):" ); scanf ("%f" , &a); printf ("正方形的边长是%f" , sqrt (a)); return 0 ; }
练习7-10
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> int main (void ) { int i; float x; for (i=0 ,x = 0.0 ; x <= 1.0 &&i<=100 ; x += 0.01 ,i++) { printf ("x=%f " , x); x = i / 100.0 ; printf ("x=%f\n" , x); } return 0 ; }
练习7-11
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> int main (void ) { float x,y=0.0 ; for (x = 0.0 ; x <= 1.0 ; x += 0.01 ) { y += x; printf ("x=%f\n" , x); } printf ("x递增后所有值的累计:%f\n" , y); return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> int main (void ) { int i; float x,y=0.0 ; for (i = 0 ; i <= 100 ; i++) { x = i / 100.0 ; y += x; printf ("x=%f\n" , x); } printf ("x递增后所有值的累计:%f\n" , y); return 0 ; }