計算機內存中的數據可以通過變量,常量來表示和存儲,那麼這些數據如何運算?
C語言中提供了大量(34種)的運算符可以用來完成數據的算術,賦值,邏輯,關系,條件判斷以及自增自減運算和基於二進制的位運算,同時提供了跨平台的用於數據格式化輸入輸出的函數printf()和scanf(),而實際上計算機需要去完成的任務正是讀取輸入的數據,根據業務邏輯進行計算之後將結果輸出。
在學習為了完成數據的復雜計算而生的那些運算符之前,需要先明白幾個概念:
操作數:參與計算的數據,可以是之前學過的整數,浮點數和字符以及以後學的。
運算符:也就是執行某項計算的符號,例如+ - * / % >等等
表達式:操作數和運算符的組合,例如 x+y;
而運算符通常是有優先級和結合性的特性:
優先級:以算術運算符為例子,通常是先乘除後加減,可以使用()提高優先級
結合性:繼續以算術運算符為例子,當優先級相同時(表達式中只有同級別的運算符),通常是從左到右開始執行的。
但是實際生產和生活中通常都是各種運算和後面學習的流程控制語句聯合嵌套使用的,是現實生活中的業務復雜度決定的。
算術運算符主要是用來完成數學運算的,C語言支持數學上的加減乘除四則混合運算,同時還有取模運算(%),也就是求被除數/除數=商數…余數,需要指出的是只有整數才能求模。
下面程序案例演示了算術運算符使用過程中需要注意的事項:
1 整數和整數運算,結果是整數,尤其是在使用除法時需要注意會捨去小數部分
2 當有多種數據類型(int double char)參與運算時,運算結果的數據類型是參與運算的最大的數據類型,這樣保持數據運算的准確性。
#include
/*
算術運算符 + - * -
@author Tony [email protected]
@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 [email protected]
@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 [email protected]
@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 [email protected]
@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);
}
在學習變量時多次使用到賦值運算符”=”,需要區別的是C語言中的相等性判斷是使用”==”兩個等號來實現的。
賦值運算符的作用就是將右邊的表達式或者常量值賦值給左邊的變量,賦值之前會進行類型轉換(將右邊的值轉換成左邊的變量類型)。
/*
賦值運算符
@author Tony [email protected]
@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 [email protected]
@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 [email protected]
@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
/*
自增自減運算符
@author Tony [email protected]
@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 [email protected]
@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 [email protected]
@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 [email protected]
@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秒鐘
}
}
邏輯運算符用於計算常量,變量或者表達式的邏輯值,做多個條件判斷。主要有三個邏輯運算符:
邏輯與(&&):當多個表達式計算結果為非0時,邏輯與的計算結果為1,否則如果有一個表達式結果為0(邏輯與的計算結果為0),那麼邏輯與將不會再執行剩余的表達式,此時短路發生!(邏輯與可以形象的理解成白富美找男朋友,要又高又富又帥,多個條件都要滿足)
邏輯或(||):當多個表達式計算結果中有1個為非0時,邏輯或的計算結果為1,此時邏輯或將不再執行剩余的表達式,短路發生,否則如果所有表達式結果都為0,結果為0。(邏輯或可以形象的理解為IT男找女朋友,只要窈窕淑女一個條件即可)
邏輯非(!):對表達式運算的結果取反,即如果表達式運算結果為0,邏輯非就是非0,反之也成立。
使用關系和邏輯運算符實現大小寫字母的相互轉換
/*
使用關系運算符結合邏輯運算符實現大小寫字母轉換
@author Tony [email protected]
@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");
}
C語言的關系運算符和數學上的大於(>),小於(<),大於等於(>=),小於等於(<=)以及不等於(!=)相對應,只是用在C語言的表達式中產生的結果是0(假)或者1(真)。
/*
關系運算符的運算結果
@author Tony [email protected]
@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 [email protected]
@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 [email protected]
@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 [email protected]
@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 [email protected]
@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 [email protected]
@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位運算符
9 C語言輸入輸出函數
9.1 輸出函數printf()
從第一個C語言程序中,就使用了跨平台的庫函數printf實現將一段文字輸出到控制台,而實際上,printf()不僅可以將數據按照指定的格式輸出到控制台,還可以是網頁或者是指定的文件中。
使用printf函數將數據按照指定的格式輸出到網頁的使用案例,目前我們公司的IT系統還有用C語言寫的後台程序(cgi)。
/*
使用printf輸出數據到網頁
@author Tony [email protected]
@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 [email protected]
@since 20160530 09:14
*/
void printf_sample() {
printf("Hello World \n");//輸出字符串常量,默認是輸出到控制台
//printf顯示不同數據類型的數據
printf("我的名字叫%s,我的年齡是%d我的幸運字符是%c\n","Tony",28,'C');
}
printf在打印輸出整數時,不僅可以按照三種不同的進制類型(八進制,十進制和十六進制),同時還可以按照有符號和無符號兩種方式打印整數。
以及控制輸出字符的寬度等等:
/*
輸出指定格式的整數數據
如果要在網頁下顯示數據,還需要匹配不同的格式
@author Tony [email protected]
@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 [email protected]
@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 [email protected]
@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 [email protected]
@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 [email protected]
@since 20160530 10:08
*/
void printf_format_string() {
char str[100] = "calc"; //輸出字符串
printf("%s\n",str);
}
/*
使用sprintf函數實現字符串拼接
@author Tony [email protected]
@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");
}