現代C語言程式設計之資料計算
現代C語言程式設計之資料計算
C語言程式設計3.1 運算子概述
計算機最核心的任務就是完成資料的計算,C語言提供了豐富(多達34種)的運算子來實現不同資料的各種運算,之前在求資料型別的大小時已經使用過的sizeof()就是一種運算子,最常用的運算子有算術,關係,邏輯以及比較和位運算子,在介紹具體的運算子之前先要明確關於運算子的一些概念。
- 運算元:就是參與運算的資料,例如2,(3+2)都是一個運算元
- 運算子:指定資料執行的運算型別,例如算術,邏輯,關係,比較,位運算等等
- 表示式:由運算元和運算子組成,通常都是完成某種業務資料計算而設計的,例如計算圓的面積等等。
- 優先順序:在各種運算子參與運算時,有不同的執行順序,由它們的優先順序決定,可以使用()來改變執行的順序。
- 結合性:執行運算的方向,例如從左到右或者從右到左。
關於運算子概念的應用案例如下所示
#include <stdio.h>
#include <stdlib.h>
/*
關於運算子的概念
*/
void main(){
//運算子:參與資料的運算方式,這裡的+就是運算子
//3+5就是表示式
//3,5就是運算元
int result = 3 + 5;
//優先順序:計算的先後順序,這裡就是先乘除,後加減 ,可以通過()提高優先順序
//結合性:計算的方向:這裡就是從左往右開始計算
int precedence = (45 + 5) / 5 * 10;
//運算子不能相鄰
// 1 + *3;
//但是在執行加減法運算時,編譯器把+3當成了正數
1 + +3;
1 + -3;
system("pause");
}
3.2 算術運算子
算術運算子就是數學意義上的加減乘除,還有取模運算(即求餘數),取模主要用於資料的擷取。
算術運算子是按照先乘除,後加減的優先順序,從左到右的結合性執行計算,應用案例如下所示
#include <stdio.h>
#include <stdlib.h>
/*
算術運算子
+ - * / % 的常規應用 以整數為例
*/
void main() {
printf("1 + 3 = %d\n", (1 + 3));
printf("8 - 2 = %d\n", (8 - 2));
//運算結果的型別是參與運算中的最大資料型別 整數和整數運算的結果是整數
printf("5 / 2 = %d\n", (5/2 ));
//整數和小數運算的結果型別是小數
printf("5 / 2.0 = %f\n", (5/2.0 ));
//3.5*2的結果是浮點數,這裡通過強制型別轉換為整數
printf("3.5 * 2 = %d \n",(int) (3.5 *2));
//求模運算子 就是求餘數
printf("5 %% 2 = %d\n", (5%2));
//需要注意的是,只有整數才能求模,如下程式碼會發生編譯錯誤
//printf(5%1.2);
//求模結果的符號型別與被除數相同
printf("5 %% -2 = %d\n", (5 % -2));
printf("-5 %% -2 = %d\n", (-5 % 2));
system("pause");
}
在執行算術運算時,會發生自動型別轉換,結算結果的資料型別是其中最大的資料型別,例如整數和浮點數參與算術運算,結果一定是浮點型別,如果想要獲得整數,則需要進行強制型別轉換,應用案例如下所
#include <stdio.h>
#include <stdlib.h>
void main() {
// 13/4=3 自動轉換為float 就是3.0
float fl = 13 / 4;
//輸出結果為3.000000
printf("%f\n",fl);
//先運算出浮點型別 13/4.0=3.25
fl = 13 / 4.0;
printf("%f", fl);
printf("5.0 /2 = %d",(int)(5.0 / 2));
system("pause");
}
取模只能是整數參與運算,運算結果的符號和被除數一致,也就意味著如果被除數是正數,那麼取模的結果就是正數,反之亦然,應用案例如下所示
#include <stdio.h>
#include <stdlib.h>
/*
取模運算要求左右兩邊必須是整數型別
*/
void main() {
//被除數/除數的餘數 就是取模
printf("3%%5=%d\n",(3%5));//3
printf("5%%3=%d\n",(5%3));//2
printf("3%%-5=%d\n",(3%-5));// 3
printf("5%%-3=%d\n",(5%-3));//2
printf("-3%%5=%d\n",(-3%5));// -3
printf("-5%%3=%d\n",(-5%3));// -2
system("pause");
}
取模的應用案例
將一個兩位數實現倒轉
#include <stdio.h>
#include <stdlib.h>
/*
取模的應用場景
資料切割
將一個二位數實現顛倒 例如輸入95 反轉結果是59
*/
void main() {
printf("請輸入一個整數\n");
int num = 0;
scanf("%d",&num);
//個位
int unit = num % 10;
//十位
int decade = num / 10;
int reversalResult = unit * 10 + decade;
printf("%d反轉之後的結果是%d\n",num,reversalResult);
system("pause");
}
將一個三位數倒轉
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
將一個三位數實現顛倒 例如輸入123 反轉結果是321
*/
void main() {
printf("請輸入一個整數\n");
int num = 0;
scanf("%d", &num);
//個位 123/10=12..3
int unit = num %10;
printf("unit= %d\n",unit);
//十位 123%10=12...3
int decade = num /10%10;
int hundreds = num / 100;
int reversalResult = unit * 100 + decade*10+ hundreds;
printf("%d反轉之後的結果是%d\n", num, reversalResult);
system("pause");
}
3.3 賦值運算子
在學習變數賦值時用到的=
實際上就是賦值運算子,它的作用就是用來將右邊的值賦值給左邊的變數,當表示式中有多個變數同時賦值時按照從右往左的結合性進行賦值,優先順序在所有運算子中僅高於逗號運算子,應用案例如下所示
#include <stdio.h>
#include <stdlib.h>
/*
賦值運算子
優先順序:
結合性: 如果有多個賦值運算,則是從右向左賦值
*/
void main() {
int num = 3;
num = 10;
printf("num = %d\n", num = 20); //num=20 賦值表示式整體的值就是num被賦值的變數
int left;
int right;
//結合性:從右向左計算
left = right = 88;
printf("left = %d \t right = %d \n",left,right);
system("pause");
}
在賦值時,賦值運算子左邊的值叫做左值,就是有記憶體實體的變數,右值就是能放在賦值號右邊,並且能夠賦值給其他變數的值,左值可以當作右值賦值給其他變數.
在賦值時會進行自動型別轉換,應用案例如下所示
#include <stdio.h>
#include <stdlib.h>
/*
賦值是在CPU內部的暫存器完成的
*/
void main() {
int num = 10;
//有記憶體實體的變數才能賦值
//右值:能放在賦值號右邊,能賦值給其他變數的值
//20 = num;
//左值:被賦值的值,必須有記憶體實體,左值一定能當作右值
int target_num = num;
//賦值號會進行自動型別轉換
int val = 10.999;
printf("val = %d\n",val);
system("pause");
}
在日常開發中,賦值運算還可以和算術運算結合在一塊使用,用於簡化表示式,但是需要注意的是它們在一起使用時不能使用空格隔開,否則會發生編譯錯誤,應用案例如下所示
#include <stdio.h>
#include <stdlib.h>
/*
賦值運算子結合算術運算子的使用
注意不能有空格 例如 + =,會造成編譯錯誤
*/
void main() {
int num = 80;
printf("num =%d\n", num);
num += 8; //等價於 num =num +8;
printf("num+8 =%d\n", num);
num -= 20;
printf("num-20 =%d\n", num);
system("pause");
}
賦值和算術運算子的複雜案例
首先定義一個列印方法,用於輸出三個整數引數的值
/*
輸出三個整數引數的結果並換三行
*/
void print_result(int a,int b,int c) {
printf(" a = %d \n b = %d \n c = %d \n", a, b, c);
}
賦值運算結合算術運算的案例如下所示
#include <stdio.h>
#include <stdlib.h>
/*
賦值運算子結合算術運算子的複雜案例
理解賦值運算子的優先順序,低於算術運算子,可以通過()提高優先順序
遇到複雜的表示式時,先拆減,後計算
*/
void main() {
int a, b, c;
a = b = c=5;
print_result(a,b,c); // 5 5 5
//改變了優先順序 先計算b=5
a = (b=5);
print_result(a, b, c); // 5 5 5
//先執行賦值,後執行加法 再把相加的結果賦值給a
a = 5 + (c = 6);//11 5 6
print_result(a, b, c);
//先執行 c=6,再執行b=4,再執行6+4 並把相加的結果賦值給a
a = (b = 4) + (c = 6); // 10 4 6
print_result(a, b, c);
//先執行c=2,再執行b=10 最周執行10/2並賦值給a
a = (b = 10) / (c = 2);// 5 10 2
print_result(a, b, c);
int num = 12;
//首先明確 賦值運算子低於算術運算子
//拆解表示式 num =num+(num=num-(num*num))
//計算步驟 num= -132+ (12-144)
num += num -= num * num;
printf(" num =%d \n ",num);
int tmp = 2;
tmp %= 4 - 1;
printf("tmp = %d",tmp); //目前tmp=2
//拆解表示式
// 0 0 0 6 6
//tmp=tmp+(tmp=(tmp*(tmp=tmp-(tmp=tmp*3))))
//tmp=
tmp += tmp *= tmp -= tmp *= 3;
printf("tmp += tmp *= tmp -= tmp *= 3 = %d",tmp);
system("pause");
}
3.4 自增運算子
自增運算子的作用就是用於變數的加1,主要用於控制迴圈的自增,由++
兩個加號組成,可以放到變數的前面或者是後面,如果是單獨一行語句,前置或者是後置結果是一樣的,應用案例如下所示
#include <stdio.h>
#include <stdlib.h>
/*
自增運算子
當自增運算子作為單獨的語句,無論前置++或者後置++結果都是一樣的
*/
void main() {
int num = 10;
num++;
printf("num = %d\n", num);
int val = 10;
++val;
printf("val = %d\n", val);
system("pause");
}
當自增運算子不是一條單獨的語句時,前置和後置會影響表示式的計算結果,應用案例如下所示
#include <stdio.h>
#include <stdlib.h>
/*
表示式中的自增運算子
*/
void main() {
int num = 10;
int result = num++;
printf("result = %d \t num = %d\n", result, num);
int tmp = 10;
int target = ++tmp;
printf("target = %d \t tmp = %d\n", target, tmp);
system("pause");
}
而如果自增運算子和算術運算子同時參與運算時,自增運算子的優先順序高於算術運算子,應用案例如下所示
#include <stdio.h>
#include <stdlib.h>
/*
自增運算子的優先順序高於算術
*/
void main() {
int num = 10;
int data = 5;
printf(" num = %d\n", ++num*5); //num先自增1 再參與乘法運算 結果是55
system("pause");
}
3.5 逗號運算子
在日常開發中,可以將多個表示式合併到一塊,表示式之間使用逗號分隔,它們就構成了逗號表示式,其優先順序是所有運算子中最低的,結合性是會按照從左到右的順序執行計算,整個表示式的值就是最後那個逗號之後的表示式的值,應用案例如下所示。
#include <stdio.h>
#include <stdlib.h>
/*
逗號表示式的運算結果是最後一個逗號的值
優先順序是所有運算子中最低的
*/
void main() <