计算机内存中的数据可以通过变量,常量来表示和存储,那末这些数据如何运算?
C语言中提供了大量(34种)的运算符可以用来完成数据的算术,赋值,逻辑,关系,条件判断和自增自减运算和基于2进制的位运算,同时提供了跨平台的用于数据格式化输入输出的函数printf()和scanf(),而实际上计算机需要去完成的任务正是读取输入的数据,根据业务逻辑进行计算以后将结果输出。
在学习为了完成数据的复杂计算而生的那些运算符之前,需要先明白几个概念:
操作数:参与计算的数据,可以是之前学过的整数,浮点数和字符和以后学的。
运算符:也就是履行某项计算的符号,例如+ - * / % >等等
表达式:操作数和运算符的组合,例如 x+y;
而运算符通常是有优先级和结合性的特性:
优先级:以算术运算符为例子,通常是先乘除后加减,可使用()提高优先级
结合性:继续以算术运算符为例子,当优先级相同时(表达式中只有同级别的运算符),通常是从左到右开始履行的。
但是实际生产和生活中通常都是各种运算和后面学习的流程控制语句联合嵌套使用的,是现实生活中的业务复杂度决定的。
算术运算符主要是用来完成数学运算的,C语言支持数学上的加减乘除4则混合运算,同时还有取模运算(%),也就是求被除数/除数=商数…余数,需要指出的是只有整数才能求模。
下面程序案例演示了算术运算符使用进程中需要注意的事项:
1 整数和整数运算,结果是整数,特别是在使用除法时需要注意会舍去小数部份
2 当有多种数据类型(int double char)参与运算时,运算结果的数据类型是参与运算的最大的数据类型,这样保持数据运算的准确性。
#include <stdio.h>
/*
算术运算符 + - * -
@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));// 当参与运算的类型不1致时,如果想要指定类型的结果,可以通过强迫类型转换来实现
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;// ⑴...⑵ 结果就是⑵
printf("⑸模3=%d\n", result);
result = 5 % -3;// ⑴...2 结果就是2
printf("5模⑶=%d\n", result);
result = -5 % -3;// 1...⑵ 结果就是⑵
printf("⑸ 模⑶=%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("请输入1个反转的5位整数\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);
}
在学习变量时屡次使用到赋值运算符”=”,需要区分的是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⑴00之间的整数累加求和
/*
//复杂赋值运算符的利用场景, 1⑴00之间的整数累加求和
@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⑴00之间的偶数和
/*
偶数求和
@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);
}
自增自减运算符主要的用处是让变量自增1或自减1,不能作用于常量或表达式。自增(++)可之前置或后置,前置变量表示先自增1,再援用,而后置1表示先援用,后自增1。
当自增自减运算符和算术运算符履行混合运算时,自增自减运算符高于算术运算的优先级。
#include <stdio.h>
/*
自增自减运算符
@author Tony 18601767221@163.com
@since 20160526 11:24
*/
void auto_increment() {
//只有变量能够自增,常量与表达式不可以自增!!!
int num = 10;
num++; //让num自增1 自增运算符++可以放到整数变量num前面或后面,如果是单唯一行语句,效果是1样的
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 <stdlib.h>
/*
自增自减的典型使用处景
@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 <Windows.h>
#include <stdlib.h>
#include <stdio.h>
/*
实现命令行窗口的变色龙
@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秒钟改变1次窗口的色彩
i++;
}
}
使用自减运算符实现基于命令行的标题时间变更 倒计时的秒表
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
/*
使用自增自减实现秒表的倒计时
@author Tony 18601767221@163.com
@since 20160528 09:16
*/
void timer() {
int second = 0;
printf("请输入你要开始倒计时的秒钟数字\n");
scanf("%d",&second);
char command[32]; //声明1个字符数组保存履行的倒计时(以命令行窗口的标题时间变化)
while (second-->0) {
sprintf(command,"title %d",second);
system(command);
Sleep(1000); //利用Windows的Sleep函数实现暂停1秒钟
}
}
逻辑运算符用于计算常量,变量或表达式的逻辑值,做多个条件判断。主要有3个逻辑运算符:
逻辑与(&&):当多个表达式计算结果为非0时,逻辑与的计算结果为1,否则如果有1个表达式结果为0(逻辑与的计算结果为0),那末逻辑与将不会再履行剩余的表达式,此时短路产生!(逻辑与可以形象的理解成白富美找男朋友,要又高又富又帅,多个条件都要满足)
逻辑或(||):当多个表达式计算结果中有1个为非0时,逻辑或的计算结果为1,此时逻辑或将不再履行剩余的表达式,短路产生,否则如果所有表达式结果都为0,结果为0。(逻辑或可以形象的理解为IT男找女朋友,只要窈窕淑女1个条件便可)
逻辑非(!):对表达式运算的结果取反,即如果表达式运算结果为0,逻辑非就是非0,反之同样成立。
使用关系和逻辑运算符实现大小写字母的相互转换
/*
使用关系运算符结合逻辑运算符实现大小写字母转换
@author Tony 18601767221@163.com
@since 20160530 20:59
*/
void releation_sample() {
printf("请输入1个字母\n");
char input = getchar(); //获得输入的字母
input >= 'a'&&input <= 'z' ? putchar(input -= 0x20) : input >= 'A'&&input <= 'Z' ? putchar(input += 0x20) : putchar(input);
printf("\n");
}
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<y);//表达式成立结果为1
}
逻辑运算符使用的那些坑…
/*
逻辑运算
@author Tony 18601767221@163.com
@since 20160528 12:56
*/
void logic_operator() {
//&& 多个表达式运算结果为非0 逻辑与为1,否则为0
int age = 28;
printf("逻辑与短路特性:%d\n",3>5&&++age); //当明确计算结果时(逻辑与有1个计算结果为0)不再履行剩余的表达式(这里的++age不会再履行)
printf("age=%d\n",age);//因此age变量的值和声明初始化的结果1样
//|| 多个表达式运算结果中有1个为非0 逻辑或为1,否则(都是0的结果)为0
printf("逻辑或短路特性:%d\n",3<5||++age);//这里也不会履行++age,这个就是逻辑或的短路特性
printf("age=%d\n", age);//因此age变量的值和声明初始化的结果1样
//! 对表达式运算的结果取反,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; //9折
double eightDiscountPrice = totalPrice*0.8;//8折
//不同的商品价格实现不同的折扣
totalPrice >= 1000 ? totalPrice=nineDiscountPrice: totalPrice >= 1500 ? totalPrice=eightDiscountPrice : nineDiscountPrice;
printf("终究商品的交易价格为%.2f\n",totalPrice);
}
3元运算符的1般情势是表达式1?表达式2:表达式3,当表达式1的结果为非0时,履行表达式2,否则就履行表达式3。3目运算符可以实现if/else语句的功能。
#include <stdio.h>
#include <stdlib.h>
/*
3目运算符使用案例
@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(); //获得1个随机值
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 <stdio.h>
#include <stdlib.h>
#include <time.h> //引入时间头文件
#include <Windows.h>
/*
赌博机的原理
@author Tony 18601767221@163.com
@since 20160529 08:15
*/
void winning_rate(){
time_t ts; //声明1个时间类型的变量
int num=0;
srand((unsigned int)(time)(&ts)); //定义随机数种子,每次产生的随机数都不1样
num = rand() % 100;//产生0⑴00之间的整数
num > 80 ? printf("你赢了"),system("echo 取得80W元大奖") : printf("你输了"),system("echo 没有中奖");
}
使用3目运算符实现求4个整数中的最大值
#include <stdio.h>
/*
获得最大值
@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("4个整数中最大的值为%d\n", max);
}
从第1个C语言程序中,就使用了跨平台的库函数printf实现将1段文字输出到控制台,而实际上,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只会依照传递的参数类型解析数据,不会进行数据类型转换,传入的参数类型和个数和输出的类型和个数保持1致,不然程序运行时会出异常
使用printf打印字符串,整数和字符的案例
#include <stdio.h>
/*
使用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在打印输出整数时,不但可以依照3种不同的进制类型(8进制,10进制和106进制),同时还可以依照有符号和无符号两种方式打印整数。
和控制输出字符的宽度等等:
#include <stdio.h>
/*
输出指定格式的整数数据
如果要在网页下显示数据,还需要匹配不同的格式
@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("%⑴0d\n",num);//宽度为10,默许是依照右侧对齐, "-"表示左侧对齐
printf("%3d\n",12345); //m整数,大于实际宽度,填充0或空格,否则无效
}
/*
输出指定格式的整数(有没有符号类型和3种进制类型的)数据
如果要在网页下显示数据,还需要匹配不同的格式
@author Tony 18601767221@163.com
@since 20160530 10:11
*/
void printf_format_int_data_type() {
const int num = 10;
printf("%d\n", num);//有符号10进制
printf("%i\n",num);
printf("%u\n",num); //无符号10进制
printf("%o\n",num);//无符号8进制
printf("%x\n",num); //无符号106进制
}
/*
@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在打印输出浮点数时,整数全部输出,默许保持小数点后6位,可以依照小数和指数(天文数字使用指数存储节俭内存)计数法两种方式,同时可以控制输出的小数位数和宽度:
#include <stdio.h>
/*
输出指定格式的浮点数数据
@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()函数来输出1个字符:
#include <stdio.h>
/*
格式化输出字符
@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() {
char command[100] = { 0 };
sprintf(command, "color %c%c", '4', 'f');//将整数 实数和字符串整合到1个字符串
printf("整合的结果为%s\n", command);
system(command);
system("pause");
char com[10] = "task";
char mand[10] = "listerror";
//command = com + mand; C语言没有Java语言中的字符串以加号的方式拼接
/*
%s%s表示字符串拼接
%.4s 从左侧截取4位,只能从左侧截取(从某1地址从左向右开始截取)
-左侧对齐
*/
sprintf(command,"%s%.4s",com,mand);//
printf("%s\n",command);
system(command);
system("pause");
}
使用sprintf函数结合字符串指针实现身份证的诞生日期信息获得
/*
通过sprintf截取身份证的出身年月日
@author Tony 18601767221@163.com
@since 20160601 14:29
*/
void sprintf_id() {
char id[19] = "421023198902345678"; //字符串是以\0结尾 因此要多出1个字符长度
printf("身份证号为%s",id);
char bornDate[9] = {0}; //初始化1个字符串保存诞生日期
sprintf(bornDate,"%-.8s",id+6);//地址向后移动6位
printf("出身年月日为%s\n",bornDate);
}
printf()经常使用输出数据类型的格式总结:
格式符 | 输出效果 |
---|---|
%d | 有符号10进制整数 |
%lld | 有符号10进制整数(long long) |
%#o | 无符号8进制整数(#表明进制) |
%#x | 无符号106进制整数(#表明进制) |
%u | 无符号10进制整数 |
%llu | 无符号10进制整数(long long)用于存储身份证号 |
%c | 字符 |
%s | 字符串 |
%p | 指针地址 |
%f | 浮点数 |
%a | 106进制浮点数 |
%e | 指数情势的浮点数 |
%g | f和e相比宽度更小的浮点数 |
欢迎扫描下方的2维码,关注微信公众服务号-艺无止境,分享IT技术干货。