带你学C带你飞 | printf函数 | 变量 | 常量和宏定义 | 数据类型 | 取值范围 | 字符串 | 运算符
文章目录
- 一、printf函数
- 1.printf函数
- 2.printf函数课后作业
- 二、变量
- 1.变量
- 2.变量课后作业
- 三、常量和宏定义
- 1.常量和宏定义
- 2.常量和宏定义的课后作业
- 四、数据类型
- 1.数据类型
- 2.数据类型的课后作业
- 五、数据类型的取值范围
- 1.取值范围
- 2.取值范围的课后作业
- 六、字符和字符串
- 1.字符和字符串
- 2.字符和字符串的课后作业
- 七、运算符
- 1.算术运算符
- 2.关系运算符和逻辑运算符
- 3.运算符的课后作业
一、printf函数
1.printf函数
printf 函数用于打印格式化字符串到标准输出流。
#include <stdio.h>int main()
{printf("Hello World!\n");return 0;
}
有时候,在printf函数中会涉及到转义字符
2.printf函数课后作业
为什么下边代码不能正常编译?
#inc1ude <stdio.h>int main() {printf("Hello World!\n");return O; }
答:仔细看,是 #include 不是 #inc1ude;还有,是 return 0; 不是 return O;
你知道以下程序打印的是什么内容吗?
#include <stdio.h>int main() {printf("Hello world\b\b\b\b\bFishC\n");return 0; }
答:打印的是 Hello FishC,因为 \b 是转义字符,表示退格的意思(相当于你按下键盘上的 Backspace 键)
下边代码错在哪?
#include <stdio.h>int main() {printf(“小甲鱼说:好好学习才能天天向上!”);return 0; }
答:初学者必犯经典错误!注意噢:在绝大多数编程语言中,所用的标点符号必须是英文,所以在编程中,将你的输入法调成纯英文状态可以避免大部分此类错误。
写一个 printf 函数,要求在屏幕上打印下边内容。
#include <stdio.h>int main() {printf("FishC.com no \"fish\"\n");return 0; }
代码写成下边这样,能正常编译运行吗?
#include<stdio.h> int main(){printf("Hello World\n");return 0;}
答:可以!C 语言显示相对宽松,你可以不必强求每一行一个语句,你也像上边一样写代码。不过,正是由于 C 语言宽松的语法限制,使得程序设计自由度很大,变得非常灵活,这就对编程者本身素质有很大的要求。
自己编写代码来打印一架飞机
#include <stdio.h>int main() {printf("\n\@\n\/ \\\n\* *\n\* *\n\* *\n\* * * * * *\n\* * * * * * * *\n\ * * * * * * * * * *\n\* *\n\* *\n\* * * *\n\* * * * * *\n");return 0; }
二、变量
1.变量
变量的目的在于确定目标(命名)并提供存放的空间(数据类型)。
变量的命名规则如下:
- 变量名只能是英文字母((A-Z,a-z)和数字(0-9)或者下划线(_)组成。
- 第一个字母必须是字母或者下划线开头。
- 变量名区分大小写
习惯用小写命名变量,所有字母大写命名符号常量名 - 不能使用关键字(在C语言中有特殊含义)来命名变量
一共44个关键字
C语言的基本数据类型如下: char
:字符型,占用一个字节int
:整型,通常反映了所用机器中整数的最自然长度float
:单精度浮点型double
:双精度浮点型
声明变量的语法:数据类型 变量名
int a
char b
float c
double d
案例:
#include <stdio.h>int main()
{ int a;char b;float c;double d;a = 520;b = 'F';c = 3.14;d = 3.141592653;printf("鱼C工作室创办于2010年的%d\n",a);printf("I love %cishC.com!\n",b);printf("圆周率是:%.2f\n",c);# %11.9f总占11位,精确到小数点后9位printf("精确到小数点后9位的圆周率是:%11.9f\n",d);return 0;
}
[liujie@localhost sle4]$ gcc test.c -o test | ./test
鱼C工作室创办于2010年的520
I love FishC.com!
圆周率是:3.14
精确到小数点后9位的圆周率是:3.141592653
2.变量课后作业
程序处理的两种基本数据对象是什么?
常量和变量变量由什么组成?
答:变量名和存储单元组成。变量名用于确定目标,存储单元用于存放变量的值。下边哪些是正确的变量名?
A. FishC_123 B. FishC 123 C. FishC@123 D. 123_FishC E. _123_FishC F. FISHC G. fishc123 H. 123 I. __ J. 小美
A、E、F、G、I
C 语言经历了 ANSI C,C99,C11 三大标准的变革,那这三大标准定义的是 C 语言的什么?
答:ANSI C,C99,C11定义的是 C 语言的标准和规则,简单的说就是定义了 C 语言的语法。请通俗地解释下 C 语言的关键字是什么?
答:关键字就是 C 语言内部使用的名字,这些名字都具有特殊的含义。如果你把变量命名为这些名字,那么 C 语言君搞不懂你到底想干嘛了。将下面的描述写成代码
声明两个变量,一个叫 a,一个叫 b
将 3 赋值给变量 b
将变量 b 的值赋值给变量 a
将变量 b 乘以 2 并赋值给 b(代码这么写:b = b * 2)
打印变量 a 的值
打印变量 b 的值#include <stdio.h>int main() {int a;int b;b = 3;a = b;b = b * 2;printf("a = %d\n", a);printf("b = %d\n", b);return 0; }
将下面描述写成代码
声明一个变量 r,用来存放圆的半径
声明一个变量 c,用来存放圆的周长
声明一个变量 s,用来存放圆的面积
将 5 赋值给变量 r
计算圆的周长(公式:2 * 3.14 * r),并赋值给变量 c
计算圆的面积(公式:3.14 * r * r),并赋值给变量 s
打印圆的周长和面积(精确到小数点后两位)#include <stdio.h>int main() {int r;double c, s;r = 5;c = 2 * 3.14 * r;s = 3.14 * r * r;printf("半径为%d的圆,周长是%.2f, 面积是%.2f\n", r, c, s);return 0; }
最后一题考一下大家对 printf 函数的掌握程度,要求程序可以打印下边内容:
#include <stdio.h>int main() {printf("打印五个字符:%c %c %c %c %c\n", 70, 105, 115, 104, 67);printf("前边用 填充:%10d\n", 2015);printf("前边用0填充:%010d\n", 2015);printf("右对齐,保留2位:%10.2f\n", 3.1416);printf("左对齐,保留3位:%-10.3f\n", 3.1416);printf("右对齐,指数形式:%10e\n", 520000.0);printf("左对齐,指数形式:%-10E\n", 520000.0);return 0; }
三、常量和宏定义
1.常量和宏定义
常量的定义是在程序运行过程中,其值不能够被改变。
整型常量:520,1314,123
实型常量: 3.14,5.12,8.97
字符常量
- 普通字符:‘L’,‘o’,‘v’,‘e’
- 转义字符:‘\n’, ‘\t’, ‘\b’
字符串常量:“FishC”
符号常量:使用之前必须先定义
如何定义符号常量呢?标志符全部大写。
格式:#define 标志符 符号常量
define的功能就是把程序中所有出现的标志符替换为后面的常量(标志符的命名规范与变量的命名规范是一致的)。案例如下:
#include <stdio.h>#define URL "http://www.fishc.com"
#define NAME "鱼C工作室"
#define BOSS "小甲鱼"
#define YEAR 2010
#define MONTH 5
#define DAY 20int main()
{printf("%s成立于%d年%d月%d日\n",NAME,YEAR,MONTH,DAY);printf("%s是%s创立的\n",NAME,BOSS);printf("%s的域名是%s\n",NAME,URL);return 0;
}
[liujie@localhost sle5]$ gcc test.c -o test | ./test
鱼C工作室成立于2010年5月20日
鱼C工作室是小甲鱼创立的
鱼C工作室的域名是http://www.fishc.com
针对字符串常量,如何确定字符串的结束位置(字符串的长度)呢?在C语言中,用空字符来表示一个字符串的结束位置。当写下"Hello World"时表示一个字符串,编译器在编译时会为它在后边追加一个特殊的转移字符反斜杠0表示字符串到此为止。
2.常量和宏定义的课后作业
main 是一个合法的标识符吗?
答:是,main 是函数的标识符名称。字符串是常量吗?
答:是。在 C 语言中,转义字符 ‘\n’ 占多大空间?
答:一个字节。字符串 “FishC” 由哪些字符构成?
答:‘F’、‘i’、‘s’、‘h’、‘C’,还有一个表示结束标志的 ‘\0’。我们都知道变量就是在内存里挖个坑让你存放数据,数据类型决定坑的大小。那常量有没有数据类型呢?
答:当然有啦。在 C 语言中,只要是数据,那就有类型。如果有符号常量定义如下:
#define F(n) 2*n
那么,请问代码中 F(3+2) 的值等于多少?
答:F(3+2) == 2*3+2 == 8
,注意,宏定义是在程序编译时先进行的预处理,做法是直接将标识符替换为常量,并不会进行相关运算。因此,直接将 F(3+2) 替换为 2*3+2。修改下边代码,使用符号常量 NL,代替转义字符 ‘\n’:
#include <stdio.h>int main() {printf("Line1\n");printf("Line2\n");return 0; }
#include <stdio.h>#define NL '\n'int main() {printf("Line1%c", NL);printf("Line2%c", NL);return 0; }
定义两个宏,分别叫 S® 和 C®,通过它可以计算得到半径为 r 的圆的面积和周长
#include <stdio.h>#define PI 3.14159 #define S(r) PI * r * r #define C(R) 2 * PI * rint main() {int r = 5;printf("半径为%d的圆,面积是:%.2f,周长是:%.2f\n", r, S(r), C(r));return 0; }
大家都知道菜市的价格每天都在波动,下边我用文字描述,你写成代码:
将下边几种常见菜名的价格定义为符号常量- 今天的平均菜价(单位是元/千克,1 斤等于 0.5 千克):番茄(3.7),芥蓝(7),西芹(1.3),空心菜(8),洋葱(2.4),油菜(9),黄瓜(6.3),白萝卜(0.5)
- 计算小明买 2 斤番茄、1 斤空心菜、1 斤油菜需要支付的价格,并打印出来
- 计算小红买 3 斤西芹,半斤洋葱,5 斤黄瓜需要支付的价格,并打印出来
- 计算小甲鱼买 10 斤黄瓜和 20 斤白萝卜需要支付的价格,并打印出来
#include <stdio.h>#define FANQIE 3.7 #define JIELAN 7 #define XIQIN 1.3 #define KONGXINCAI 8 #define YANGCONG 2.4 #define YOUCAI 9 #define HUANGGUA 6.3 #define BAILUOBO 0.5int main() {float price;price = (2 * FANQIE + KONGXINCAI + YOUCAI) * 0.5; // 1斤 == 0.5公斤printf("小明需要支付%.2f元\n", price);price = (3 * XIQIN + 0.5 * YANGCONG + 5 * HUANGGUA) * 0.5;printf("小红需要支付%.2f元\n", price);price = (10 * HUANGGUA + 20 * BAILUOBO) * 0.5;printf("小甲鱼需要支付%.2f元\n", price);return 0; }
四、数据类型
1.数据类型
这些数据类型的位数为:
sizeof
运算符用于获得数据类型或表达式的长度。
- sizeof(objet);//sizeof(对象);
- sizeof(type_name);//sizeof(类型);
- sizeof object;//sizeof 对象;
其案例如下:
#include <stdio.h>int main()
{int i;char j;float k;i = 123;j = 'C';k = 3.14;printf("size of int is %d\n",sizeof(int));printf("size of i is %d\n",sizeof(i));printf("size of char is %d\n",sizeof(char));printf("size of j is %d\n",sizeof(j));printf("size of float is %d\n",sizeof(float));printf("size of k is %d\n",sizeof k);
}
[liujie@localhost sle6]$ gcc test.c -o test && ./a.out
size of int is 4
size of i is 4
size of char is 1
size of j is 1
size of float is 4
size of k is 4
signed和unsigned为类型限定符。它们用于限定char类型或者任何整型变量的取值范围。signed
表示这个变量是带符号位的,unsigned
表示这个变量是不带符号位的。带符号位表示这个变量可以存放负数。不带符号位就不能存放负数,只能存放正数和零,其将存放负数的空间腾出来,可以存放更大的值。
四种整型加上限定符就有了8种:
- [signed] short [int]
- unsigned shorts[int]
- [signed] int
- unsigned int
- [signed] long [int]
- unsigned long [int]
- [signed] long long [int]
- unsigned long long [int]
2.数据类型的课后作业
对于整型变量来说,long int 已经可以存放足够大的整数了,但若有一个更大的整数,应该尝试使用什么类型?
答:long long int,因为 C 标准规定 short <= int <= long <= long long。下图显示了不同操作系统不同模式下对整型尺寸的定义:
LLP64,即 long long(LL)和 pointers(P)都是 64 位;IL32P64,即 int(I)和 long(L)都是 32 位,pointers(P)是 64 位;其它同理……
就我们目前学到的所有数据类型中,C 标准规范存储空间最小的是?
答:_Bool,因此只要求足够容纳 0 和 1 两个数即可我们说 printf() 是一个用于格式化打印的函数,那 sizeof() 是一个函数吗?
答:不是,虽然它跟 printf() 一样后边有个小括号,并在小括号中填入“参数”,但 sizeof 其实是一个特殊的操作符。注意,它是一个运算符,一个运算符,一个运算符!C 语言定义一个字节等于多少比特位?
答:C 语言并没有具体定义一个字节等于多少比特位;一个字节被定义为连续比特位,具体大小由实现环境决定。不过通常我们约定俗成是一个字节等于八个比特位(1Byte == 8bit)。C 标准只规定一个数据类型的具体尺寸(其他数据类型都是规定相对范围),你知道是哪个数据类型如此特殊吗?
答:char 字符型,C 标准只规定 char 类型占一个字节的空间,其他数据类型均指定相对范围,具体大小依赖于实现环境。unsigned int 和 int,哪个可以表示更大的整数?
答:由于默认 int 是 signed 的,即带符号位的整数(可以表示负数),需要用一半的存储空间来存放负数;而 unsigned int 则是完全用于存放正数,因此 unsigned int 可以表示更大的整数。问题:求
1^2 + 2^3 + 3^4 + 4^5 + 5^6
的值?(1^2 表示 1 的 2 次方)#include <stdio.h> #include <math.h>int main() {int result;result = pow(1, 2) + pow(2, 3) + pow(3, 4) + pow(4, 5) + pow(5, 6);printf("结果是:%d\n", result);return 0; }
舍罕王的失算
相传国际象棋是古印度舍罕王的宰相达依尔发明的。舍罕王十分喜爱象棋,决定让宰相自己选择何种赏赐。这位聪明的宰相指着 8 * 8 共 64 格的象棋说:“陛下,请您赏给我一些麦子吧。就在棋盘的第 1 格放 1 粒,第 2 格放 2 粒,第三格放 4 粒,以后每一格都比前一格增加一倍,依此放完棋盘 64 格,我就感激不尽了。”。舍罕王听了达依尔这个“小小”的要求,想都没想就满口答应下来。结果在给达依尔麦子时舍罕惊奇地发现要给的麦子比自己想象的要多得多,于是他进行了计算,结果令他大惊失色。请问,舍罕王要兑现他的许诺共要多少粒麦子赏赐他的宰相?如果每25000粒麦子重1kg,那么舍罕王应该给予达依尔多少公斤麦子?#include <stdio.h> #include <math.h>int main() {unsigned long long sum = 0;unsigned long long temp;unsigned long long weight;int i;for (i=0; i < 64; i++){temp = pow(2, i);sum = sum + temp;}weight = sum / 25000;printf("舍罕王应该给予达依尔%llu粒麦子!\n", sum);printf("如果每25000粒麦子为1kg,那么应该给%llu公斤麦子!\n", weight);return 0; }
其实这里计算得到的麦子数(18446744073709551615 )并非正确的结果,因为 unsigned long long 能够表示最大的数字是 18446744073709551615
五、数据类型的取值范围
1.取值范围
CPU能读懂的最小单位是比特位,bit,b。内存的最小寻址单位是字节,Byte,B。
1Byte=8bit1Byte=8bit1Byte=8bit
一个字节是由8个比特位构成的。每个比特位只能存放二进制数,也就是只能存0或者1。
进制转换可查看该链接。
255是一个字节能够表示的最大值。
存放signed类型的存储单元中,左边第一位表符号位。如果该位为0,表示该整数是一个正数。如果该位为1,表示该整数是一个负数。
一个32位的整型变量,除去左边第一位符号位,剩下表示值的只有31个比特位。
#include <stdio.h> #include <math.h>int main() {unsigned int result = pow(2,32) - 1;int res = pow(2,31) - 1;printf("result = %u\n",result);printf("res =%d\n",res);return 0; }
[liujie@localhost FishC]$ gcc -lm test.c && ./a.out result = 4294967295 res =2147483647
事实上,计算机是用补码的形式来存放整数的值,不论正数还是负数
- 正数的补码就是该数的二进制形式
- 负数的补码需要通过以下几个步骤来获得:
- 先取得该数的绝对值的二进制形式
- 再将第一步的值按位取反
- 再将第二步的值加1
char数据类型的最大值和最小值为
[扩展阅读] 使用补码的好处
基本数据类型的取值范围如下:
浮点型与整型的存储形式与取值范围就不好理解了,浮点数:表示更大范围的小数(#)。
2.取值范围的课后作业
一个字节可以表示的最大带符号整数是?
答:一个字节约定等于八个比特位(事实上 C 语言没有规定一个字节等于八个比特位,这只是约定俗成),因此一个字节可以表示最大的二进制数是 1111 1111。
由于左边第一位是符号位,不能用于表示值的大小,因此一个字节可以表示的最大带符号整数是:0111 1111,转换成十进制数就是 127。假设在一个机器上,用 64 位来存放 long long 的值,请问它最大可以存放一个多少位的十进制数?
答:既然是要存放最大的那个整数,我们取 unsigned long long(符号位别浪费了~),它可以表示的最大值是 2^64 – 1,即 18446744073709551615。这是一个 20 位的十进制整数。浮点数的取值范围如下表,请问 float 类型变量可以存放的最小值是?
答:-3.40282 * 10^38请写出以下二进制数(补码)对应的十进制数
A. 0000 1100 -> 2^3 + 2^2 = 8 + 4 = 12
B. 1100 1100 –> -2^7 + 2^6 + 2^3 + 2^2 = -128 + 64 + 8 + 4 = -52
C. 1010 1010 –> -2^7 + 2^5 + 2^3 + 2 = -128 + 32 + 8 + 2 = -86
D. 1111 1111 -> -2^7 + 2^6 + 2^5 + 2^4 + 2^3 + 2^2 + 2 + 1 = -1
E. 1000 0000 –> -2^7 = -128请写出以下十进制数在内存中的二进制存放形式(8 位,补码)。
答:带符号数在内存中以补码的形式保存,正数的补码是其二进制本身,负数则通过对其绝对值的二进制取反加一计算得到
A.8 -> 0000 1000
B.27->16+8+2+1->0001 1011
C.99 -> 64+ 32+2+1 -> 0110 0011
D.-8 -> 1000 1000 ->1111 0111 ->1111 1000
E.-126 ->-128+ 2 -> 1000 0000+ 0000 0010 -> 1000 0010写出下列有符号数对应的无符号数的十进制值(8 位)
A.13->13
B.122->122
C.-1 -> -128+ 127 -> 1000 0000+ 0111 1111 = 1111 1111 ->255
D.-14 ->1000 1110 -> 1111 0001 -> 1111 0010 ->242
E.-128 ->1000 0000 -> 128填充下边代码,使得打印结果为:-1 和 255{
答:char 类型占一个字节的空间,因此 unsigned char 的取值范围是 0~255,signed char 的取值范围则是 -128~127。十进制的 255 即二进制的 11111111,signed char 第一位为符号位,因此其值转换为十进制后是 -1。
printf 函数使用 %c 打印 char 类型的字符,使用 %d 和 %u 则打印其对应的 ASCII 码(其中 %d 打印带符号数,%u 打印无符号数)。signed char 和 unsigned char 使用 hh 说明其长度。#include <stdio.h>int main() {signed char i;unsigned char j;i = 255;j = 255;printf("signed char %hhd\n", i);printf("unsigned char %hhu\n", j);return 0; }
按以下要求编写程序。
要求用户输入一个十进制整数(按下回车完成输入)
计算出该整数值的五次方
打印计算结果#include <stdio.h> #include <math.h>int main() {int i;double result;printf("请输入一个整数:");scanf("%d", &i);result = pow(i, 5);printf("%d的五次方是:%.2f\n", i, result);return 0; }
六、字符和字符串
1.字符和字符串
进行如下实验:
#include <stdio.h>int main()
{char a = 'C';printf("%c = %d\n",a,a);return 0;
}
其运算结果为:
[liujie@localhost sle8]$ gcc -lm test.c && ./a.out
C = 67
输出这样结果的原因在于ASCII字符表。声明的是字符变量,%d会打印其在ASCII字符表中对应的数值。因此,字符就是特殊的整型。
C语言并没有专门为存储字符串设计一个单独的类型。字符串就是连续的字符,只需要在内存中找一块连续的空间放一串连续的自负啊变量就可以了。声明字符串的语法为char 变量名[数量];
,可以通过索引号来获得每个字符变量的空间变量名[索引号]=字符;
。案例如下:
#include <stdio.h>int main()
{char NAME[]= {"FishC"};printf("%s\n",NAME);printf("Hello\n");return 0;
}
[liujie@localhost sle8]$ gcc test.c && ./a.out
FishC
Hello
2.字符和字符串的课后作业
C 语言中,最小的整数类型是?
答:char 类型。虽然 char 是字符类型,但它事实上是用于存放整数,因此属于整数类型。标准 ASCII 字符表用多少位二进制来表示字符?
答:标准 ASCII 字符表使用 7 位二进制数来表示所有的大写和小写字母,数字 0 到 9、标点符号,以及在美式英语中使用的特殊控制字符。观察 ASCII 字符表,请问大写字母和小写字母的 ASCII 值有什么特点?
答:大写字母对应的 ASCII 值第 6 位置 1 则变成对应的小写字母,反之亦然。例如:大写字母 A 的二进制 ASCII 值是 0100 0001,对应的小写字母 a 的二进制则是 0110 0001。此规则适用于所有大小写字母的相互转换请问字符串 “I love FishC.com!” 在内存中总共占用多少个字节?
答:18 个字节。因为字符串最后需要加上一个 ‘\0’ 字符表示结束。如有变量 char name[10] = “FishC”;,请写出变量 name 在内存中的存储形式?
答:由于 name 变量是声明了 10 个字节的字符串,而 “FishC” 只需 6 个字节的空间来存放,因此多余的空间用 ‘\0’ 进行填充。所以 name 变量在内存中的存储形式应该是:‘F’,‘i’,‘s’,‘h’,‘C’,‘\0’,‘\0’,‘\0’,‘\0’,‘\0’。如有变量 char name[5] = {‘F’, ‘i’, ‘s’, ‘h’, ‘C’};,可以通过 name[索引号] 的方式访问字符 ‘C’,请问索引号这里应该是多少?
答:通过 变量名[索引号] 的方式可以访问字符数组中的任意一个元素(当然要在范围内),索引号是从 0 开始计算,所以通过 name[4] 可以访问字符 ‘C’。在 Linux 系统上如何快速查看 ASCII 字符表?
答:输入命令 man ascii,一目了然。写一个华氏度到摄氏度的转换程序,用户输入华氏度,程序计算并输出对应的摄氏度。
#include <stdio.h>int main() {float fah, cel;printf("请输入华氏度:");scanf("%f", &fah);cel = (fah - 32) * 5 / 9;printf("转换为摄氏度是:%.2f\n", cel);return 0; }
我们都说要与时俱进,与时代接轨。这不,小甲鱼到“非死不可”投了份简历,体重和身高这一栏要求使用磅(lb)和英寸(in)为单位。大家帮忙写一个转换的小工具吧。
#include <stdio.h>int main() {char name[256];float height, weight;printf("请输入您的姓名:");scanf("%s", name);printf("请输入您的身高(cm):");scanf("%f", &height);printf("请输入您的体重(kg):");scanf("%f", &weight);printf("========== 正在为您转换 ==========\n");height = height / 2.54; // 厘米转换为英寸weight = weight / 0.453; // 公斤转换为磅printf("%s的身高是%.2f(in),体重是%.2f(lb)。\n", name, height, weight);return 0; }
七、运算符
C语言通过提供运算符来支持我们对数据进行处理。
1.算术运算符
我们把运算符作用的运算对象称为操作数。一个运算符是单目运算符还是双目运算符取决于有几个操作数。
用运算符和括号将操作数连接起来的式子,我们称之为表达式。涉及到复杂的表达式就需要讨论运算符的优先级。如果一个表达式存在多种运算符,就需要考虑运算符的优先级和结合性问题。可以参考
运算符的优先级和结合性。
当一个运算符的几个操作数类型不同的时候,编译器需要在它们运算之前将它们转化为共同的数据类型,就会涉及到类型转换。通常情况下,编译器会将占用坑位较小的那个操作数先转换为占用坑位较大的那个操作数的数据类型,然后再进行运算,以便确保计算的精度,这是一个默认的自动转换的过程。除了自动转换外,C语言还允许强制转换操作数的数据类型。做法是在操作数的前边用小括号将类型括起来。强制转换一般会损失精度,要有心理准备!
#include <stdio.h>int main()
{ printf("整型输出:%d\n",1+(int)2.0);printf("浮点型输出:%f\n",1+2.0);return 0;
}
[liujie@localhost sle9]$ gcc test.c && ./a.out
整型输出:3
浮点型输出:3.000000
2.关系运算符和逻辑运算符
使用关系运算符来比较两个数的大小关系:
- <(小于)
- <=(小于或等于)
- >(大于)
- >=(大于或等于)
- ==(等于)
- !=(不等于)
前四个的优先级比后面两个高。
用关系运算符将两边的变量、数据或表达式连接起来,称之为关系表达式。关系表达式得到的值是一个逻辑值,即真或假,在C语言的逻辑运算中,用数字1表示真,用数字0表示假。
如果需要同时对两个或者两个以上的关系表达式进行判断,就需要用到了逻辑运算符。C语言总共提供了三种逻辑运算符:
用逻辑运算符将两边的变量、数据或表达式连接起来,称之为逻辑表达式。
短路求值又称最小化求值,是一种逻辑运算符的求值策略。只有当第一个运算数的值无法确定逻辑运算的结果时,才对第二个运算数进行求值。C语言对于逻辑与和逻辑或采用短路求值的方式。
#include <stdio.h>int main(){ int a = 3,b = 3;(a = 0) && (b = 5);printf("a = %d,b = %d\n",a,b);(a = 1) || (b = 5);printf("a = %d,b = %d\n",a,b);return 0;
}
[liujie@localhost sle10]$ gcc test.c && ./a.out
a = 0,b = 3
a = 1,b = 3
3.运算符的课后作业
请问下边程序会显示什么内容?
#include <stdio.h>int main() {int a = 2, b = 1;printf("%d\n", a / 'b');return 0; }
答:0,因为字符 ‘b’ 对应的 ASCII 值为 98,a / ‘b’ == 2 / 98 == 0,
如果不上机实验,你知道下边代码会输出什么吗?
#include <stdio.h>int main() {int a;(a = 2) + 3 * 4;printf("a = %d\n", a);return 0; }
答:a = 2
如果不加小括号,那么变量 a 的值最终应该是 14 才对,因为赋值运算符的优先级要低于算术运算符,所以先计算,后赋值。但这里我们使用了优先级最高的小括号将赋值运算的过程括起来,因此先将变量 a 赋值为 2,再进行计算(计算结果不再赋值给变量 a)。请写出下边表达式的值(如果结果为浮点数,请保留六位小数)
A. 5 / 3 = 1 // 整型除以整型,结果为整型,直接舍弃小数
B. 1 / 0 出错 // 除数不能为 0
C. 1.2 + 3 = 4.200000 // 浮点型加整型,编译器会自动将“精度较小”的类型先转换为“精度较大”的类型,再进行运算,所以结果为浮点型
D. 1.2 * 0 = 0.000000 // 同上
E. 6.0 / 2 = 3.000000 // 同上
F. 10 / 6.0 = 1.666667 // 结果为无限循环小数,小数点后第六位四舍五入
G. 3 / 5 = 0 // 同 A下边代码中存在两处错误,请指出
#include <stdio.h>int main() {int a = (5 + 1.2) % 2;printf("%d\n", a); }
答:
- 求余运算符两边要求均为整型,5 + 1.2 的结果为浮点型;
- printf() 函数后边的分号写成了中文的分号(;),大部分新手经常遇到这样错把中文符号当代码的问题,请重视!
写一个等额本息的还款计算器
等额本息还款法,也称定期付息,即借款人每月按相等的金额偿还贷款本息,其中每月贷款利息按月初剩余贷款本金计算并逐月结清。
月均还款 = 贷款本金 * (月利率 * (1 + 月利率)^还款月数) / ((1 + 月利率)^还款月数 - 1)
总利息 = 还款月数 * 月均还款 - 贷款本金
贷款本金 = 房款总额 * 按揭成数程序要求用户输入房屋单价、面积、按揭成数、按揭年数以及基准利率,然后计算并显示等额本息还款法需要偿还的房款总额、首期付款、贷款总额、支付利息以及每月需要还款多少各项数据。
程序实现如下:#include <stdio.h> #include <math.h>int main() {float price, area, yir, mir; // 单价、面积、年利率、月利率float interest, loan; // 利息、贷款总额float ave_repay, down_payment; // 月均还款、首期付款float total_price, total_repay; // 房款总额、还款总额int ratio, time; // 按揭成数、按揭年数printf("请输入单价(元/平方):");scanf("%f", &price);printf("请输入面积:");scanf("%f", &area);printf("请输入按揭成数:");scanf("%d", &ratio);printf("请输入按揭年数:");scanf("%d", &time);printf("请输入当前基准年利率:");scanf("%f", &yir);mir = yir / 100 / 12; // 年利率需要除以100得到,因为用户输入是5.4(%),而不是0.054time = time * 12;total_price = price * area;loan = total_price * ratio / 10; // 这里不能写成(ratio / 10),否则结果会变成0ave_repay = loan * mir * pow((1 + mir), time) / (pow((1 + mir), time) - 1);interest = ave_repay * time - loan;total_repay = loan + interest;down_payment = total_price * (1 - (float)ratio / 10); // 强制转换ratio为浮点型printf("========== 报告结果 ==========\n");printf("房款总额:%.2f元\n", total_price);printf("首期付款:%.2f元\n", down_payment);printf("贷款总额:%.2f元\n", loan);printf("还款总额:%.2f元\n", total_repay);printf("支付利息:%.2f元\n", interest);printf("月均还款:%.2f元\n", ave_repay);return 0; }
有 10000 元,想存 5 年,分别求出以下三种方法存得的本息和:
一次性定期存 5 年;
先存 3 年定期,到期后本息再存 2 年定期;
存 1 年定期,到期后本息再存 1 年定期,连续存 5 次。
注:r 为年利率,n 为存款年数,则计算本息和的公式如下:
1 年本息和的计算公式:P = 10000 * (1 + r)
n 年本息和的计算公式:P = 10000 * (1 + r * n)
n 次 1年的本息和的计算公式:P = 10000 * (1 + r)^n#include <stdio.h> #include <math.h>int main() {float p0 = 10000, p1, p2, p3;float r1 = 0.0175, r2 = 0.0225, r3 = 0.0275, r5 = 0.0275;p1 = p0 * (1 + r5 * 5);p2 = p0 * (1 + r3 * 3) * (1 + r2 * 2);p3 = p0 * pow((1 + r1), 5);printf("第一种方案的本息和是:%.2f\n", p1);printf("第二种方案的本息和是:%.2f\n", p2);printf("第三种方案的本息和是:%.2f\n", p3);return 0; }
请问 char *name = “FishC” 和 char name[] = {‘F’, ‘i’, ‘s’, ‘h’, ‘C’} 是否等价?
答:两者并非等价。char *name = “FishC” 应该与 char name[] = {‘F’, ‘i’, ‘s’, ‘h’, ‘C’, ‘\0’} 等价。请解释为何下边变量 a 的值为何打印出来是 144(请写出分析过程)?
#include <stdio.h>int main() {unsigned char a, b, c;b = c = 200;a = b + c;printf("a = %u\n", a);return 0; }
答:200(10) == 128(10) + 64(10) + 8(10) == 1000 0000(2) + 100 0000(2) + 1000(2) == 1100 1000(2)
1100 1000(2) + 1100 1000(2) == 1 1001 0000(2)
由于 char 类型占一个字节(8 位),因此舍弃掉最前边的进位,结果为 1001 0000(2) == 144请将语句 a = b = c = 3; 拆分成 3 条独立语句。
答:务必注意结合性,赋值运算符的结合性是自右向左的。
c = 3;
b = c;
a = b;你听说过“表达式”,也听说过“语句”,那请问两者的区别是什么?
答:一个表达式会产生一个值,它可以放在任何需要一个值的地方;而语句是一段可执行代码,可以理解为一个行为,语句不一定有值。下边有一段代码,请描述表达式 a < b && c < d 的求值顺序(先求什么、再求什么、最后求什么)
#include <stdio.h>int main() {int a = 0, b = 1, c = 2, d = 3;a > b && c < d;return 0; }
答:先求关系表达式 a > b 的值,由于结果为假,根据短路求值的原则,直接得到逻辑表达式 a > b && c < d 的值为假(因为 && 需要两边同时为真,结果才为真,所以左边为假,右边则没有必要继续判断,这就是短路求值的原理)。
请说明逻辑与(&&)在下边表达式中起到的重要作用
count != 0 && sum/count
答:该表达式使用逻辑与(&&)来确保 sum/count 的除数不为 0。
因为当 count 为 0 时,并不会导致 sum/0,因为根据短路求值的原则,&& 运算符在左侧为假的情况下,并不会计算右侧的表达式。请用一个逻辑表达式来判断某一年是否为闰年。
某一年份如果符合下边 A 或 B 其中一个,我们称之为闰年:
A. 能被 4 整除,但不能被 100 整除;
B. 能被 400 整除。
答:(year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)
带你学C带你飞 | printf函数 | 变量 | 常量和宏定义 | 数据类型 | 取值范围 | 字符串 | 运算符相关推荐
- C语言学习笔记《带你学C带你飞》P21-P40
文章目录 21.指针 22.指针和数组 23.指针数组和数组指针 24.指针和二维数组 25.void指针和NULL指针 26.指向指针的指针 27.常量和指针 28.函数 29.参数和指针 30.指 ...
- 小甲鱼老师《带你学C带你飞》的后续课程补充
小甲鱼老师的<带你学C带你飞>系列之前有预告,说有机器人电子制作的续集,但是这么久了还是没有等到,博主在这里根据自己的学习经历,推荐一些学习的资料,可以为小甲鱼老师填一下坑,读者可根据自己 ...
- 【零基础】带你学C带你飞
基本特性 1. 高级语言:它是把高级语言的基本结构和语句与低级语言的实用性结合起来的工作单元. 2. 结构式语言:结构式语言的显著特点是代码及数据的分隔化,即程序的各个部分除了必要的信息交流外彼此独立 ...
- 【带你学c带你飞】第2天课后练习
@toc 上课demo练习 课后练习 你需要为程序中的变量.类型.函数和标签起一个名字,我们把这个名字称之为? 宏变量 main 是一个合法的标识符吗? 是的 字符串是常量吗? 不是 在 C 语言中, ...
- 【逗老师带你学IT】PRTG监控通过Python通过串口监控UPS运行状态,PRTG值查询功能定义
本文主要介绍,如何通过串口获取UPS主机的运行状态,并通过PRTG统计监控和告警. 不同UPS主机厂的串口通信协议不同,但是市面上有一种比较通用的协议,如果你使用的是EATON,山特等等国产UPS,大 ...
- 《带你学C带你飞》—— SE44传递结构体变量和结构体指针
使用结构体嵌套.结构体函数来写书的信息的程序 #include <stdio.h>struct Date {int year;int month;int day; };struct Boo ...
- 《带你学C带你飞》—— SE54位操作
C语言并没有规定一个字节的尺寸 . "可寻址的数据存储单位,其尺寸必须可以容纳运行环境的基本字符集的任何成员" 逻辑位运算符
- 小甲鱼最新c语言视频,带你学c带你飞系列
https://www.bilibili.com/video/av8302677/?p=7
- 【带你学c带你飞】S1E11:if语句
demo
最新文章
- vss error reading from file 解决方法
- 5G LAN — 解决方案示例
- docker环境配置
- vscode设置go-lint警告提示
- 嵌入式开发笔记(二)嵌入式系统启动过程 (S5pv210)
- __stdcall函数调用约定
- 线程的生命周期 和 线程的通讯
- Java 面试 1 小时,我看出了和月薪 3w 的差距
- html基础知识补全
- php 405,php Restler 405 Method Not Allowed 问题解决啦,restlerallowed_PHP教程
- 利用数据库管理国际化资源配置以及自定义标签实现国际化效果
- C语言提取字符对应的ASCAl,ascall码对照表(ASCII码表)
- 关于HTML图片如何设置热区
- 桥梁防撞智能预警系统方案
- ICASSP2022论文阅读记录3 - TalkingFlow
- Python深度学习13——Keras模型的可视化(神经网络结构图)
- 学习之路(三):分享一下最近的一个爬虫代码
- woff字体反爬实战,10分钟就能学会(ttf字体同理)
- IBM小型机日常维护命令
- 【LaTex】LaTex 极简使用教程(后续加附视频讲解链接)