C语言运算符与表达式
1 概论
计算机内存中的数据可以通过变量,常量来表示和存储,那么这些数据如何运算?
c语言中提供了大量(34种)的运算符可以用来完成数据的算术,赋值,逻辑,关系,条件判断以及自增自减运算和基于二进制的位运算,同时提供了跨平台的用于数据格式化输入输出的函数printf()和scanf(),而实际上计算机需要去完成的任务正是读取输入的数据,根据业务逻辑进行计算之后将结果输出。
在学习为了完成数据的复杂计算而生的那些运算符之前,需要先明白几个概念:
操作数:参与计算的数据,可以是之前学过的整数,浮点数和字符以及以后学的。
运算符:也就是执行某项计算的符号,例如+ - * / % >等等
表达式:操作数和运算符的组合,例如 x+y;
而运算符通常是有优先级和结合性的特性:
优先级:以算术运算符为例子,通常是先乘除后加减,可以使用()提高优先级
结合性:继续以算术运算符为例子,当优先级相同时(表达式中只有同级别的运算符),通常是从左到右开始执行的。
但是实际生产和生活中通常都是各种运算和后面学习的流程控制语句联合嵌套使用的,是现实生活中的业务复杂度决定的。
2 算术运算符
算术运算符主要是用来完成数学运算的,c语言支持数学上的加减乘除四则混合运算,同时还有取模运算(%),也就是求被除数/除数=商数…余数,需要指出的是只有整数才能求模。
下面程序案例演示了算术运算符使用过程中需要注意的事项:
1 整数和整数运算,结果是整数,尤其是在使用除法时需要注意会舍去小数部分
2 当有多种数据类型(int double char)参与运算时,运算结果的数据类型是参与运算的最大的数据类型,这样保持数据运算的准确性。
#include /* 算术运算符 + - * - @author tony 18601767221@163.com @since 20160526 10:13 */ void alg_operator() { printf("%d\n", 1 + 3); printf("%d\n", -3); //加减运算符有时候会被当做正负数 printf("%d\n", 5 / 2.0);//运算的结果是2.5 但是printf在打印输出时不会做强制类型转换,因此这里解析错误,结果为0 printf("%d\n", (int)(3.5 * 2));// 当参与运算的类型不一致时,如果想要指定类型的结果,可以通过强制类型转换来实现 printf("3/2=%d", 3 / 2); //两个整数相除 小数部分被舍去 }
求模运算的结果与被除数相同,如果被除数是正数,那么取余的结果也是正数,反之也成立。
/* 算术运算符 求模的结果和被除数相关 @author tony 18601767221@163.com @since 20160526 10:13 */ void modulo_operator() { //整数能做求模运算,浮点数不能 //int result = 5.0 % 3; 编译错误 //求模运算的结果与被除数相同 int result = 5 % 3; //1...2 结果就是2 printf("5模3=%d\n", result); result = -5 % 3;// -1...-2 结果就是-2 printf("-5模3=%d\n", result); result = 5 % -3;// -1...2 结果就是2 printf("5模-3=%d\n", result); result = -5 % -3;// 1...-2 结果就是-2 printf("-5 模-3=%d\n", result); }
取模运算符可以使用乘除法实现:
/* 使用乘除法实现取模运算 @author tony 18601767221@163.com @since 20160528 20:28 */ void delivery() { int result = 5 % 3; printf("取模运算结果>>>result=%d\n",result); result = 5 - (5 / 3) * 3; //先取整相乘再相减 printf("乘除法运算结果>>>result=%d\n", result); }
取模运算符的使用场景:整数反转,例如12345反转成54321
/* 使用求模运算符实现整数反转 @author tony 18601767221@163.com @since 20160526 10:36 */ void modulo_reversal_sample() { int num = 0; printf("请输入一个反转的五位整数\n"); scanf("%d", &num); //读取键盘上输入的整数 int unit = num % 10; int decade = num / 10 % 10; int hundred = num / 100 % 100 % 10; int thousand = num / 1000 % 10; int tenthousand = num / 10000; int reseveal = tenthousand + thousand * 10 + hundred * 100 + decade * 1000 + unit * 10000; printf("反转之前的数字%d\n反转之后的数字%d\n", num, reseveal); }
3 赋值运算符
在学习变量时多次使用到赋值运算符”=”,需要区别的是c语言中的相等性判断是使用”==”两个等号来实现的。
赋值运算符的作用就是将右边的表达式或者常量值赋值给左边的变量,赋值之前会进行类型转换(将右边的值转换成左边的变量类型)。
/* 赋值运算符 @author tony 18601767221@163.com @since 20160526 10:36 */ void assignment_operator() { // c语言中的=表示赋值运算符 int value = 12; //将12赋值给变量value printf("value=%d\n", value); //赋值运算符会自动将右边的表达式计算的结果或者是常量自动转换成左边的变量类型 double db = 12 + 12; printf("db=%.2f\n", db); int one, two, three; one = two = three = value; //当同时有多个赋值运算时,从右往左执行赋值运算 //算数运算符优先级高于赋值运算符优先级 //复杂赋值运算符 int num = 10; num +=-2; num -= 4; num *= 6; num /= 8; num %= 10; // //赋值运算符是从右向左开始执行 int result = 5; result += result -= result *= result /= result; // result+=result-=result*=result=result/result printf("result=%d\n",result); }
复杂运算符的使用场景:1-100之间的整数累加求和
/* //复杂赋值运算符的应用场景, 1-100之间的整数累加求和 @author tony 18601767221@163.com @since 20160518 09:34 */ void assignement_sample() { int i = 1; int sum = 0; while (i <=100) { sum += i;//作用等同于sum =sum +i; i += 1; } printf("1到100之间的整数和为%d\n", sum); }
复杂赋值运算符的使用场景:计算1-100之间的偶数和
/* 偶数求和 @author tony 18601767221@163.com @since 20160518 09:36 */ void even_sum() { int i = 0; int sum = 0; while (i<=100) { sum += i; i += 2; } printf("1到100之间的偶数和为%d\n", sum); }
4 自增自减运算符
自增自减运算符主要的用途是让变量自增1或者自减1,不能作用于常量或者表达式。自增(++)可以前置或者后置,前置变量表示先自增1,再引用,而后置1表示先引用,后自增1。
当自增自减运算符和算术运算符执行混合运算时,自增自减运算符高于算术运算的优先级。
#include /* 自增自减运算符 @author tony 18601767221@163.com @since 20160526 11:24 */ void auto_increment() { //只有变量能够自增,常量与表达式不可以自增!!! int num = 10; num++; //让num自增1 自增运算符++可以放到整数变量num前面或者后面,如果是单独一行语句,效果是一样的 printf("num=%d\n", num); printf("前置++和后置++运算的区别\n"); printf("后置++运算\n"); int age = 28; printf("age=%d\n", age++);//先引用打印 printf("age=%d\n", age);//再自增 printf("前置++运算\n"); int year = 2016; printf("age=%d\n", ++year);//先自增 printf("age=%d\n", year);//再引用打印 //自增运算符优先级高于算数运算符优先级 int val = 10; printf("val=%d\n", ++val + 3);//val先自增1 再加3 val = 3; printf("val=%d\n", -val++);//val先自增加1再变成负3 int number = 10; int data = 5; printf("%d", ++number*data);// 55 int one = 5; int two = 10; int sum = one++ + two; printf("sum =%d\n",sum); sum = ++one + two; printf("sum =%d\n", sum); }
自增运算符常用在循环中改变循环变量的值
#include /* 自增自减的典型使用场景 @author tony 18601767221@163.com @since 20160528 08:59 */ void auto_increment_sample() { // int count = 0; while (count++<5) { system("start notepad"); //异步调用记事本 } while (count-->0) { system("calc"); } }
使用自增运算符实现基于命令行的变色龙
#include #include #include /* 实现命令行窗口的变色龙 @author tony 18601767221@163.com @since 20160528 09:00 */ void changecolor() { char command[32]; //声明字符数组保存输入的命令 int i = 0; while (i<0xf) { sprintf(command, "color %x%x", i, 15 - i);// 使用sprintf函数实现给字符串赋值 system(command); sleep(1000); //1秒钟改变一次窗口的颜色 i++; } }
使用自减运算符实现基于命令行的标题时间变更 倒计时的秒表
#include #include #include /* 使用自增自减实现秒表的倒计时 @author tony 18601767221@163.com @since 20160528 09:16 */ void timer() { int second = 0; printf("请输入你要开始倒计时的秒钟数字\n"); scanf("%d",&second); char command[32]; //声明一个字符数组保存执行的倒计时(以命令行窗口的标题时间变化) while (second-->0) { sprintf(command,"title %d",second); system(command); sleep(1000); //利用windows的sleep函数实现暂停1秒钟 } }
5 逻辑运算符
逻辑运算符用于计算常量,变量或者表达式的逻辑值,做多个条件判断。主要有三个逻辑运算符:
逻辑与(&&):当多个表达式计算结果为非0时,逻辑与的计算结果为1,否则如果有一个表达式结果为0(逻辑与的计算结果为0),那么逻辑与将不会再执行剩余的表达式,此时短路发生!(逻辑与可以形象的理解成白富美找男朋友,要又高又富又帅,多个条件都要满足)
逻辑或(||):当多个表达式计算结果中有1个为非0时,逻辑或的计算结果为1,此时逻辑或将不再执行剩余的表达式,短路发生,否则如果所有表达式结果都为0,结果为0。(逻辑或可以形象的理解为it男找女朋友,只要窈窕淑女一个条件即可)
逻辑非(!):对表达式运算的结果取反,即如果表达式运算结果为0,逻辑非就是非0,反之也成立。
使用关系和逻辑运算符实现大小写字母的相互转换
/* 使用关系运算符结合逻辑运算符实现大小写字母转换 @author tony 18601767221@163.com @since 20160530 20:59 */ void releation_sample() { printf("请输入一个字母\n"); char input = getchar(); //获取输入的字母 input >= 'a'&&input <= 'z' ? putchar(input -= 0x20) : input >= 'a'&&input <= 'z' ? putchar(input += 0x20) : putchar(input); printf("\n"); }
6 关系运算符
c语言的关系运算符和数学上的大于(>),小于(<),大于等于(>=),小于等于(<=)以及不等于(!=)相对应,只是用在c语言的表达式中产生的结果是0(假)或者1(真)。
/* 关系运算符的运算结果 @author tony 18601767221@163.com @since 20160529 08:40 */ void releation_operator() { int x = 10; int y = 20; printf("%d\n",x>y); //表达式不成立 结果为0 printf("%d\n",x
逻辑运算符使用的那些坑…
/* 逻辑运算 @author tony 18601767221@163.com @since 20160528 12:56 */ void logic_operator() { //&& 多个表达式运算结果为非0 逻辑与为1,否则为0 int age = 28; printf("逻辑与短路特性:%d\n",3>5&&++age); //当明确计算结果时(逻辑与有一个计算结果为0)不再执行剩余的表达式(这里的++age不会再执行) printf("age=%d\n",age);//因此age变量的值和声明初始化的结果一样 //|| 多个表达式运算结果中有一个为非0 逻辑或为1,否则(都是0的结果)为0 printf("逻辑或短路特性:%d\n",3<5||++age);//这里也不会执行++age,这个就是逻辑或的短路特性 printf("age=%d\n", age);//因此age变量的值和声明初始化的结果一样 //! 对表达式运算的结果取反,1变为0 0变为1 printf("3<5取反的运算结果为:%d\n",!3<5); //对结果取反 }
使用关系和逻辑运算符实现商场的购物打折程序
/* 商品打折系统 @author tony 18601767221@163.com @since 20160530 21:11 */ void discount() { double unitprice = 128.8;//商品单价 int number = 10;//购买数量 double totalprice = unitprice*number; //计算总价 double ninediscountprice = totalprice*0.9; //九折 double eightdiscountprice = totalprice*0.8;//八折 //不同的商品价格实现不同的折扣 totalprice >= 1000 ? totalprice=ninediscountprice: totalprice >= 1500 ? totalprice=eightdiscountprice : ninediscountprice; printf("最终商品的交易价格为%.2f\n",totalprice); }
7三元运算符
三元运算符的一般形式是表达式1?表达式2:表达式3,当表达式1的结果为非0时,执行表达式2,否则就执行表达式3。三目运算符可以实现if/else语句的功能。
#include #include /* 三目运算符使用案例 @author tony 18601767221@163.com @since 20160526 13:24 */ void ternary_operator() { 0 ? system("calc") : system("tasklist"),system("explorer"); //这里会执行调用notepad -1 ? system("system tasklist"),system("ipconfig"):system("calc");//执行tasklist和calc int num = rand(); //获取一个随机值 printf("产生的随机值为%d\n",num); num > 80 ? printf("你赢了") : printf("你输了"); int one = 100; int two = 200; int max = one > two ? one : two; printf("两个整数中的最大值为%d\n", max); }
结合关系运算符和以时间为随机数的种子数实现赌博机
#include #include #include //引入时间头文件 #include /* 赌博机的原理 @author tony 18601767221@163.com @since 20160529 08:15 */ void winning_rate(){ time_t ts; //声明一个时间类型的变量 int num=0; srand((unsigned int)(time)(&ts)); //定义随机数种子,每次产生的随机数都不一样 num = rand() % 100;//产生0-100之间的整数 num > 80 ? printf("你赢了"),system("echo 获得80w元大奖") : printf("你输了"),system("echo 没有中奖"); }
使用三目运算符实现求四个整数中的最大值
#include /* 获取最大值 @author tony 18601767221@163.com @since 20160529 08:20 */ void get_max_value(){ int max =0; int one = 66; int two = 77; int three = 88; int four = 99; max = one > two ? one : two; max = max > three ? max : three; max = max > four ? max : four; printf("四个整数中最大的值为%d\n", max); }
8位运算符
c语言输入输出函数">9 c语言输入输出函数
9.1 输出函数printf()
从第一个c语言程序中,就使用了跨平台的库函数printf实现将一段文字输出到控制台,而实际上,printf()不仅可以将数据按照指定的格式输出到控制台,还可以是网页或者是指定的文件中。
使用printf函数将数据按照指定的格式输出到网页的使用案例,目前我们公司的it系统还有用c语言写的后台程序(cgi)。
/* 使用printf输出数据到网页 @author tony 18601767221@163.com @since 20160530 09:04 */ void printf_html() { printf("content-type:text/html \n\n");//声明html语言 printf("hello world in html");//将生成的exe程序改成cgi就可以部署在web服务器例如apache中运行了 }
printf()函数的强大之处在于格式化显示整数,浮点数,字符以及字符串。我们可以使用这个函数来调试程序或者获取方法的返回值等等。
printf只会按照传递的参数类型解析数据,不会进行数据类型转换,传入的参数类型和个数和输出的类型和个数保持一致,不然会出异常
使用printf打印字符串,整数和字符的案例
#include /* 使用printf格式化输出数据 @author tony 18601767221@163.com @since 20160530 09:14 */ void printf_sample() { printf("hello world \n");//输出字符串常量,默认是输出到控制台 //printf显示不同数据类型的数据 printf("我的名字叫%s,我的年龄是%d我的幸运字符是%c\n","tony",28,'c'); }
printf在打印输出整数时,不仅可以按照三种不同的进制类型(八进制,十进制和十六进制),同时还可以按照有符号和无符号两种方式打印整数。
以及控制输出字符的宽度等等:
/* 输出指定格式的整数数据 如果要在网页下显示数据,还需要匹配不同的格式 @author tony 18601767221@163.com @since 20160530 09:20 */ void printf_format_int() { const int num = 10; printf("%d",num);//默认的格式是有多宽 填充多宽 printf("%d\t%ld",num,num);//32位以上的系统%d和%ld是等效的 inth和long是等效的 printf("%10d\n",num);//宽度为10,默认是右边对齐 printf("%010d\n",num);//宽度为10,如果不足则用0来补充 printf("%-10d\n",num);//宽度为10,默认是按照右边对齐, -表示左边对齐 printf("%3d\n",12345); //m整数,大于实际宽度,填充0或者空格,否则无效 } /* 输出指定格式的整数(有无符号类型以及三种进制类型的)数据 如果要在网页下显示数据,还需要匹配不同的格式 @author tony 18601767221@163.com @since 20160530 10:11 */ void printf_format_int_data_type() { const int num = 10; printf("%d\n", num); printf("%i\n",num); printf("%u\n",num); //无符号十进制 printf("%o\n",num);//无符号八进制 printf("%x\n",num); //无符号十六进制 } /* @author tony 18601767221@163.com @since 20160530 21:53 */ void printf_format_int_unsinged() { unsigned short int uvalue = 65535; short int num = 123; printf("uvalue =%hu\tnum=%hd",uvalue,num); }
printf在打印输出浮点数时,可以按照小数和指数计数法两种方式,同时可以控制输出的小数位数和宽度:
#include /* 输出指定格式的浮点数数据 @author tony 18601767221@163.com @since 20160530 10:06 */ void printf_format_double() { const double num = 3.14159265359; printf("num=%.2f\n", num);//小数点后保留两位 printf("num=%030.10f\n",num);//宽度为30,不足用0补齐 //指数表示 double depth = 1234567000000.0; printf("depth=%e\n",depth);//指数表示 double value = 1.23456789;// %g 自动选择宽度 %f.%e printf("value=%f\tvalue=%e\tvalue=%g",value,value,value); }
printf在输出字符时通过%c格式符来输出,同时提供了putchar()函数来输出一个字符:
#include /* 格式化输出字符 @author tony 186017672212163.com @since 20160530 10:15 */ void printf_char() { char ch = 'a'; printf("ch=%c\n",ch); putchar(ch); }
printf在输出字符串时,可以通过sprintf函数实现将字符串按照指定的格式拼接:
/* 输出指定格式的字符串数据 @author tony 18601767221@163.com @since 20160530 10:08 */ void printf_format_string() { char str[100] = "calc"; //输出字符串 printf("%s\n",str); } /* 使用sprintf函数实现字符串拼接 @author tony 18601767221@163.com @since 20160530 10:32 */ void sprintf_string_append() { //使用sprintf函数实现字符串拼接 char command[100] = { 0 }; sprintf(command, "color %c%c", '4', 'f');//将整数 实数和字符串整合到一个字符串 printf("整合的结果为%s\n", command); system(command); system("pause"); char com[10] = "task"; char mand[10] = "list"; //command = com + mand; c语言没有java语言中的字符串以加号的方式拼接 /* %s%s表示字符串拼接 %.5%s截取,只能从左边截取(从某一地址从左向右开始截取 -左边对齐 */ sprintf(command,"%s%s",com,mand);//字符串地址的移动实现跳过某一段 printf("%s\n",command); system(command); system("pause"); }
上一篇: HDU 2874 LCA转RMQ+并查集
下一篇: 在五子良将当中,曹操最信任的人是谁?