計算機內存中的數據可以通過變量,常量來表示和存儲,那末這些數據如何運算?
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技術干貨。