# C語言基礎
2015年03月26日10:04:41
1、 語言排行榜
C——java——objective-C
2、 進制:
進制:進位機制。用普通的話講,應該為人為的定義一種度量來標識一樣東西。
計算機常用的進制有:十進制、二進制、八進制和十六進制。
➢ 十進制:0-9(十個指頭)(進制表示基數:10)
➢ 二進制:0,1(基數為2)
➢ 八進制:0-7(基數為8)
➢ 十六進制:0-9,A-F(基數為16)
可以有很多進制,比如分鐘為60進制等等。
3、 位權
為了進制之間轉換而出的一個概念。
位:一個通用的描述方式。最低位為第0位。之後依次+1。
例如:9AF(F為第0位,A為第1位,9為第2位)
權:進制是幾,權就是幾。
位權:某位上的數*權^該位
例如:231,權為:10,位是:2,位權1為10^0,位權3為10^1,位權2為10^2
4、 進制轉換
十進制轉X進制:連除倒取余數(取余數是從下往上取)
用通俗的話講:十進制的某個數轉化為其他進制時,將該數除以進制,依次將余數寫在除法每一步的旁邊,一直除完為止。則所對應的轉化後的值,從下往上按順序記錄余數,該余數即為轉化後的結果。
X進制轉十進制:按權求和
用通俗的話講:用位權的計算方法,將某進制的數,從第0位開始,把第0位上得數*進制(權)的0次方,加上第1位上得數*進制(權)的1次方….以此類推,直至該進制的數的最高位,所得到的和,即為轉化所得的十進制的結果。
進制修飾(區別什麼數是什麼進制):
➢ 十進制:什麼都不加修飾 如:111
➢ 八進制:在前加0 如:0111
➢ 十六進制:在前加0X 如:0X111
➢ 二進制:在前加0b 如:0b111
當程序員不想自己用筆來計算較大的進制轉換時,點擊右上角搜索按鈕spotlight 搜索“計算器”。command+1(簡單型計算器)2為科學型,3為編程型
2015年03月26日14:31:45
5、 基本數據類型
記憶基本數據類型的時候,這樣記——三大類:
➢ 字符:
(關鍵字)char :字符型 占字節:1 = 8位 寫得出來的都是字符’1’ ‘2’ ‘A’ 。對應十進制0~255之間任意 任意一個數都可以表示,但是>256的不能存儲。
➢ 整型:
(關鍵字)short 短整型 : 字節:2 = 16位 0~65535
(關鍵字)int 整型 : 字節:4 = 32位 0~2^33-1
(關鍵字)long 長整形 : 字節:8或4(C語言沒有給一個明確的數字,而是這樣定義的,long型的數不小於int型的數。Int型的數不小於short型的數)
➢ 浮點:
(關鍵字)float 單精度浮點型 : 字節:4
(關鍵字)double 雙精度浮點型 : 字節:8
字節:1字節 = 8位
看一個數是正數還是負數,看最高位是啥:0為正,1為負
6、 常量
不可改變的量。
如: 719,‘A’,‘a’等等。
7、 變量
變量:變量相當於一個容器或位置.
//定義一個變量
//整型
int num1 = 10;
//短整型
short s1=111;
//長整型
long l1=123456789;
//浮點型(單精度)
float f1=1.2;
//浮點型(雙精度)
double d1=2.22;
//字符型
char c1= '1';
變量命名規則
➢ 數字0~9,下劃線_,字母 a~z,A~Z 組成,不能以數字開頭
➢ 不可以用系統保留字
➢ 不能使用重復變量名
➢ 見名之意。(規范)定義一個變量,要明顯知道變量名的意思。
賦值運算符:= 可以給一個變量賦值。
//賦值運算符:=,可以給一個變量賦值。
//交換兩個變量中的值。
int number1=10;
int number2=20;
//准備另一個變量,用於臨時存放
int temp=0;
printf("前number1:%d \n",number1);
printf("前number2:%d \n",number2);
temp=number1;
number1=number2;
number2=temp;
printf("後number1:%d \n",number1);
printf("後number2:%d \n",number2);
課後思考題,交換兩個變量的值,不使用第三個變量。
提示:有兩種方式。
8、 算術運算符
算數運算符,主要是看什麼,主要是看+,-,*,/ ,++,--,這幾個運算符的用法,+,-,*就不說了,/(除法)主要是要看除數不能為0,雖然計算機不報錯(因為語句都符合C語言的標准,程序會執行。),但是在運行後,給出的結果不正確。
++和—運算比較特殊,應該這樣記:++在前則先++,++在後則後++。--和++一樣。
要明白一點就是,運算過程中,會出現自動數據類型轉換。
//+號
// //n1=30
// int n1 = 10+20;
// //n2=40;
// int n2 = n1+10;
// //n3=70
// int n3=n1+n2;
// //n4=140;
// int n4= n1+n2+n3;
// -號
// // n1=10;
// int n1 = 30-20;
// //n2=0;
// int n2 = n1-10;
// //n3=-10;
// int n3 = n2-n1;
// //n4=-20;
// int n4 = n3-n2-n1;
// *號
//除法:/
// //使用除號/,注意0不能坐除數! xcode不報錯,只提出警告,並能運行。
//// int n1 = 10 / 0;
// //除號兩邊都是整數,結果也是整數,不論除盡的小數點後面是什麼值,都捨去。
// int n2 = 3 / 2;
// //除號兩邊都是浮點型,結果也是浮點型。n3=1.5
// float n3 = 3.0/2.0;
// //參與運算的數,如果 運算符 兩邊,只要有一個是浮點型,結果都為浮點型。n4=1.5
// float n4 = 3/2.0;
//取余 %
// //n1 = 1
// int n1 = 3 % 2;
// //n2 = 0
// int n2 = 4 % 2;
//
// //取余運算符兩邊的數,必須都為整型;
//// int n3 = 5.0 % 2.0;
//
// //取余之後的結果 < 除數,一定小於除數。
//++在後
// //n1=0
// int n1 = 0;
// //n1=0
// //如果++在後面,只要這條語句沒有執行完,n1++都表示原來的值。
// //n3=0;
// int n3 = n1++;
// //n2= 1
// int n2 = n1;
//++在前
// int n1 = 0;
// //++在前,先加1,再賦值。n2=1
// int n2 = ++n1;
//符合運算符
// int n1 = 10;
// int n2 = 30;
// n2 = n2 + n1;
//// n2 += n1;與n2 = n2 + n1;等效;
9、 表達式
表達式:常量、變量與運算符的組合。
例如:3,3+1,n1+1,3+(也是表達式,但是是錯誤的表達式)
表達式都會有返回值。
語句是程序執行的最小單位,以分號結尾。
例如:1; 1+7;
不以分號結尾的,不管前面寫的再好,再標准,都不是語句。
10、 基本輸入輸出
基本輸入輸出函數 ,在C語言的第一個hello world程序裡,有printf(“hello world”);這個語句,printf是標准輸出函數,雖說打印語句都是程序裡最簡單的一個方法,但是在C語言中,printf函數輸出,不僅僅是一個函數而已,它是由先人用匯編語言把計算機內存和顯存的各種機理封裝在了printf函數中,這個函數是在stdio.h這個庫文件中的。
庫文件:即為前人寫好的代碼,放在了一起,我們可以直接用。
輸出:printf();
形式是這樣的:printf(“%d”,100)這個是輸出整型;printf(“%f”,100.0)這個是輸出浮點型;printf(“%c”,’100’)這個是輸出字符型的數據。
這個時候,輸出整形還可以分:printf(“%sd”,100)這個輸出短整型;printf(“%ld”,100)這個輸出長整型。
輸出函數printf還有一個要注意的地方:
➢ %和d中間的數字,代表預留幾個位置:從右往左算。
➢ 如果預留位置小於實際位置,按照實際位置來。
➢ 如果預留位置大於實際位置,在輸出的左邊補上空格。
➢ 如果數字前加0,則把空格變為補0;
例子:printf("%05d",12);輸出結果:00012
➢ .X表示保留小數點後X位,%4.2f表示保留小數點後2兩位。.前為代表預留幾個位置。
例如:printf("%4.2f",1.2345);//1.23
➢ 小數點也站位。
例如:printf("%4.1f",1.2345);//_1.2(下劃線代表空格)
➢ 正數表示右對齊(如果給出預留位大於實際位,左邊空格代替),負數表示左對齊(如果給出預留位大於實際位,右邊空格)。
例如:printf("%-4dabc",123);//123_abc(下劃線代表空格)
另外C語言推出一些解決輸出轉義字符的辦法
printf("123\n456");//換行。
printf("\\");//打印\
printf("%%");//打印%
輸入:scanf()
在用戶輸入一個數據時,需要在程序裡定義一個變量來接收這個輸入進來的值。
// int n1 = 0;
// printf("請輸入一個數字,按回車結束:");
// scanf("%d",&n1);
// printf("n1 = %d",n1);
值得注意的是,scanf("%d",&n1);中變量需要用&n1表示。&表示取地址。後面會介紹。
關於輸入數據類型,也需要注意,如果輸入的數據類型和程序裡定義的變量數據類型不匹配,則定義的變量拒絕接收輸入進來的數據。
在輸入函數中,與輸出函數還有一個區別就是:輸出函數的double類型占位符,用%f,但是輸入函數的double類型占位符是%lf。
// double d1 = 0;
// scanf("%lf",&d1);
輸入函數接收多個參數時,可以這樣寫:但是不推薦。
//接收多個輸入值。
// int num1 = 0;
// int num2 = 0;
// printf("請輸入兩個數字,按回車結束:");
//不推薦這麼寫
// scanf("%d%d",&num1,&num2);
// printf("num1 = %d , num2 = %d",num1,num2);
推薦的時分開接收:
//推薦分開寫
// int num1 = 0;
// int num2 = 0;
// scanf("%d",&num1);
// scanf("%d",&num2);
scanf中,不推薦寫除了占位符以外的東西,因為輸入的時候需要一一對應輸入,否則不接收輸入數據。
例如:scanf(“sum = %d”,&n1);則需要在控制台輸入:sum=100,才能匹配,n1才能接收到數據,否則拒絕接收數據。
Scanf中的占位符,不能加\n,否則在輸入數據時匹配回車將會和\n(換行)進行匹配後,無法得出結果。
——大海
2015年03月26日21:05:54 北京
2015年03月27日09:44:50
11、分支結構
在學分支結構之前,要知道一點就是C89標准中沒有BOOl這個類型,因此需要將標准升級為C99標准。
C99標准在Xcode中,在新建一個工程的時候,選擇type時,選擇doundation。
創建工程之後,會發現,與之前的main.c的後綴已經變為main.m。這是objective-C環境下的後綴。
與之前.c的頁面中,還有不同的是:
將#include<stdio.h>換成
#import <Foundation/Foundation.h>
//import是oc語法,作用和include是一樣的。都是引入一個文件。
//Foundation/Foundation.h 是系統提供的一些功能,可以直接用,比stdio.h所包含的東西多得多。
12、bool數據類型
bool數據類型,只有yes和no兩個值,非真即假。在C語言中,認為,非0即為真。
用處:用於if語句的時候和循環判斷的時候。
在編譯過程中,C語言將bool的yes值編譯成1存在內存中,將no值編譯成0,保存在內存中。
#define yes 1
#define no 0
13、關系運算符
關系運算符主要就是兩者之間的比較,> (大於),>= (大於等於),< (小於),<= (小於等於),== (等於),!=(不等於) 。比較得出的結果是bool類型的值,用bool類型變量來存儲。其他沒什麼了。
14、邏輯運算符
邏輯運算符就三個:與(&&),或(||),非(!)
參與運算的數,在符號兩邊都是bool值 。得出的結果不是真就是假。
&& 邏輯與:只要有一個為假,全都為假。
|| 邏輯或:只要有一個為真,結果都為真。
! 邏輯非:取反。
短路現象:
邏輯與運算的時候,如果系統檢測到&&前的值是no,那麼將不再去判斷&&號後面的值,此時,如果&&後的值有賦值運算,賦值運算也不執行。
邏輯或運算的時候,如果系統檢測到 || 號前的值是yes ,那麼將不再去判斷 || 號後面的值,此時,如果 || 後的值有賦值運算,賦值運算也不執行。
//短路現象
//邏輯與,如果前面判斷是假,後面的判斷不再執行。
// int num1 = -1 ;
// int num2 = -1;
// BOOL b3 = (num1 = 0) && (num2 = 2);//假
//
// printf("%d",b3);//0
// printf("num1 = %d \n",num1);// 0
// printf("num2 = %d]\n",num2); // -1
//短路現象
//邏輯或,如果前面判斷是真,後面的判斷不再執行。
// int num1 = -1 ;
// int num2 = -1;
// BOOL b3 = (num1 = 2) || (num2 = 0);//真
//
// printf("%d",b3);//1
// printf("num1 = %d \n",num1);// 2
// printf("num2 = %d)\n",num2); // -1
15、if語句
程序的三種結構:
順序結構:按順序執行程序,直到完事為止。
分支結構:if語句和switch
循環結構:循環的執行一段語句。直到循環條件結束為止。
分支結構有兩個: if語句和switch語句
if語句有三種方式:
(1)if(條件表達式){
}
//分支結構
//if的(第一種形式)
// BOOL b1 = NO;
// if (/*條件表達式:要明確的表明條件是真是假*/b1){
// printf("你個大騙子。。。");
// }
//練習
/*
從控制台輸入一個整數。
判斷這個整數是否>100。
如果大於100,輸出:“這個數大於100”
*/
// int num = 0;
// printf("請輸入一個整數,按回車結束:\n");
// scanf("%d",&num);
// if(num > 100){
// printf("你輸入的數為:%d \n",num);
// printf("這個整數大於100\n");
// }
// char c1 = 0;
// printf("輸入一個字符,按回車結束:\n");
// scanf("%c",&c1);
// BOOL b1 ='m' == c1;
// if(b1){
// printf("輸入的是男性");
// }
(2)if(條件表達式){
}else{
}
/ char c2 = 0;
// printf("請輸入字符:");
// scanf("%c",&c2);
// if ('m' == c2) {
//
// printf("正太");
// }else{
// printf("蘿莉");
// }
// int year = 0;
// printf("請輸入年份,按回車結束:");
// scanf("%d",&year);
//
// //判斷閏年的條件
// BOOL b1 = (year % 400 == 0 ) ;
// BOOL b2 =(year % 100 !=0) && (year % 4==0);
// if(b1 || b2){
//
// printf("%d\t是閏年\n",year);
//
// }else{
// printf("%d\t是平年!",year);
// }
(3)if(條件表達式){
}else if(條件表達式){
}else{
}
// char c3 = 0;
// printf("輸入一個字符:");
// scanf("%c",&c3);
//
// if('m' == c3){
// printf("男性");
// }else if ('f' == c3){
// printf("女性");
// }else{
// printf("春哥");
// }
/*
輸入一個字符,判斷
s:春天
m:夏天
a:秋天
w:冬天
其他:輸入有誤。
*/
// char c1 = 0;
//
// printf("輸入一個字符,按回車結束:");
//
// scanf("%c",&c1);
//
// if('s' == c1){
// printf("我是春天!");
// }else if('m' == c1 ){
// printf("我是夏天!");
//
// }else if('a' == c1){
// printf("我是秋天!");
//
// }else if ('w' == c1){
// printf("我是冬天!");
// }else{
// printf("輸入有誤!!");
// }
16、條件表達式
//條件表達式
// int num1 = 10;
// int num2 = 20;
//
// int num3 = num1>num2 ? num1 : num2;
//
// printf("num3 = %d",num3);
//課後練習題
/*
使用條件運算符,選擇出三個數中,哪個最大。
*/
洞房花燭夜 我 兩小無猜
字符型就是整型。
Switch 分支語句
Switch分支語句就是為了優化if(){}else if(){}過多條件。
//switch分支語句
// switch (apple) {
// case apple:
// printf("我是蘋果也!");
// //break:終止往後繼續執行
// break;
// case banana:
// printf("我是香蕉也!");
// break;
// case orange:
// printf("我是橘子也!");
// break;
// case watermelon:
// printf("我是西瓜也!");
// break;
// default:
// printf("我不是水果也!");
// }
與else if一樣的效果。
注意的是:switch ()括號中的條件必須為整型條件表達式。在每一個case下的語句代碼,最後都要加上break,用來跳出switch語句。
//練習
// int season = 0;
// printf("請輸入一個數字,按回車結束:");
// scanf("%d",&season);
//
// switch (season) {
// case 1:
// printf("春天啊我是!spring");
// break;
// case 2:
// printf("夏天啊我是!summer");
// break;
// case 3:
// printf("秋天啊我是!autumn");
// break;
// case 4:
// printf("冬天啊我是!winter");
// break;
//
// default:
// printf("啥也不是啊我!nothing");
// break;
// }
17、枚舉enum
#import <Foundation/Foundation.h>
//枚舉,建議寫在這個地方。
enum season{
//第一個元素,默認為0.後面元素依次+1.spring 自動被賦值為0,summer 為1.
//每個值都可以改變默認值,後面的數還是依次+1.初始化過的默認值,後面的數還是依次+1
spring = 100, //100
summer = 200, // 200
autumn, //201
winter //202
};
// 練習,定義一個枚舉
//定義五個水果:蘋果(10),香蕉,橘子,西瓜
enum fruits{
apple = 10,
banana,
orange,
watermelon
};
int main(){
}
——大海
2015年03月27日20:38:00 北京
18、循環
特點:在滿足特定條件的情況下,反復執行某程序段。
While循環
While循環的格式是這樣的:while(條件表達式){語句代碼},意思是滿足括號內的條件時,執行花括號內的語句代碼。或者更專業一點來說,當括號內的條件表達式返回值為真時,執行花括號內的代碼,一直到條件表達式的返回值為假時,跳出循環。
While循環很容易出現死循環這種狀況,就是因為忘記寫了“增量”這個東西。
//死循環
int count = 0 ;
// while (count < 100) {
// printf("今天我真帥...\n");
// }
上面的代碼就是少了count++,這個增量,所以,條件表達式一直滿足,就一直執行,就造成了死循環。
此時,應該這樣改進:
//循環變量 :控制循環次數
// int count = 0;
// while (/* ++ 在前,打印兩次 */count/* ++ 在後,打印三次*/ < 3 ) {
//
// printf("今天我真帥...\n");
//// count = count +1;
//
// //此處,++ 在前在後都不影響打印次數。
//
// //循環增量
// count ++;
//// ++ count;
// }
一些例子:
//練習
//打印1~100
// int num = 0;
// while (num < 100) {
// printf(" %d \n",(num + 1));
//
// num ++;
// }
//用while 打印能被7整除的1~100之間的數。
// int num = 1;
// while (num <= 100) {
//
// if(num % 7 == 0){
// printf("%d \t",num);
// }
// num ++;
// }
//用while循環打印出1~100之間各位為7的數。
// int num = 0;
//
// while (num < 100) {
//
// if(num % 10 == 7){
// printf("%d \t",(num));
// }
// num ++ ;
// }
//用while循環打印出1~100之間十位為7的數。 num / 10 == 7
// int num = 0;
// while (num < 100) {
// if(num / 10 ==7){
// printf("%d \t",num);
// }
// num ++;
// }
Do-while循環
與while不同的只有一個地方,就是先執行一遍代碼,再進行判斷。也就是說,不管你while的條件表達式成不成立,返回值為不為假,我都執行一遍循環體的代碼。
// do while
// do{
// printf("至少執行一次,不管後面的判斷條件是真還是假");
// }while (1) ;// ; 分號不能丟
隨機數arc4random()
產生隨機數的方法,arc4random()可以產生int范圍內的任意一個隨機數,包括有正數和負數,為什麼會出現負數呢?因為,在存儲的時候,生成的數的最高位的數字為1,此時,會認為這個1是符號位的負,因此會出現負數。這時,我們應該把這些情況避免掉,在輸出之前,用unsigned 來定義一個變量來接收產出的隨機數;在輸出的過程中,占位符不再用%d,而是用%u來代替。
另一個值得注意的是,隨機數產生的時候,數字會很大,而我們在代碼過程中,不需要這麼大的數,此時,想要把這個數減小,可以用取余的辦法來限制。
//隨機數 arc4random(),
//用%u來打印,表示無符號。
//由於隨機函數給的值很大,我們采用取余的方法,使值變小。 取余的隨機數的范圍就是,0~被除數-1
// printf("%u \t", arc4random() % 10);//打印 只有0~10的數
在產生一個隨機數的時候,可以讓它在固定的區間內產生,那麼就會用到這個公式:
//取某區間[a,b]的數,用公式:arc4random() % (b-a+1)+a
若是規定在負空間生成隨機數,那麼就將公式改成:
/arc4random() % (b-a+1)-a
一些例子:
//用戶輸入一個N,用while打印N個隨機數(10~30)
// int num = 0;
// int count = 0;
// printf("輸入一個數:");
// scanf("%d",&num);
// printf("產生 %d 隨機數為: \n\t",num);
// while (count < num) {
//
// //unsigned 聲明一個無符號int 類型。
// unsigned unum = (arc4random()%((30-10+1)+10));
// printf(" 第 %d 個數為:%d \t",(count+1), unum);
// count ++;
// }
//輸入一個數,用while打印n個隨機數(30~70),找出隨機數中最大值。
// int num = 0;
// printf("輸入一個數:\n");
// scanf("%d",&num);
// int count = 0;
// int max = 0;
// while (count < num ) {
// unsigned unum = (arc4random()%((70-30+1)+30));
// printf(" 第 %d 個數為:%d \n",(count+1), unum);
//
// if(max < unum ){
// max = unum;
// }
// count ++;
// }
// printf("\n ");
// printf("最大的數為:%d \n",max);
Break和continue
這兩個關鍵字在開發過程中經常遇見,他們的區別如下:
break:在某個循環的時候,用上break,意思就是停止這個循環,不再執行這個循環,我要跳出這個循環。
continue :在某個循環的時候,在過程中用上continue,意思就是,我在的這個循環還在運行,但是我不運行這一次的循環,我要跳到下一次的循環去,但是還是在這個循環裡,沒有跳出去,只是不執行這次罷了。
//循環變量
// int count = 0;
// while (count <10) {
//
// count ++;
//
// if(count == 3){
// //結束本次循環
// continue;
// /*
// 輸出結果:
//
// 第 1 天
// 第 2 天
// 第 4 天
// 第 5 天
// 第 6 天
// 第 7 天
// 第 8 天
// 第 9 天
// 第 10 天 */
// }
// if(count == 5){
// //結束循環
// break;
//
// /*
// 輸出結果:
//
// 第 1 天
// 第 2 天
// 第 4 天 */
// }
//
// printf("第 %d 天 \n",count);
//
// }
for循環
for循環和while差不多,但是是將條件和增量,循環變量都一起放在了小括號裡。
值得注意的是:while與for的比較時,for的一個好處
相比於while 循環:while 中存在浪費內存的情況,因為循環變量在while循環外邊,直到它所在的花括號結束,才釋放內存。而 for循環 的循環變量 在for循環結束後,即釋放。
for循環的執行過程是這樣的:
for(①int i= 0 ; ②i < 100;④i++){
③循環體
}
在運行到本處時,先進行①賦初值,然後判定條件,滿足則跳進循環體執行代碼③,執行循環體代碼結束後,對i進行自增④i++,然後進行②判斷,執行③,自增四。。。如此循環下去。
// for 循環
// int count = 0;
// while (count < 5) {
// printf("\n我是 while 循環。。。");
// count ++;
// }
// for(循環變量 ; 條件 ; 增量){ 循環體 }
// for (int i = 0;i < 5; i++) {
// printf("\n我是 for 循環哦。。。");
// }
//練習
//打印 0 ~100
// for (int i = 0; i <= 100; i ++) {
// printf("%d \t",i);
// }
//打印1~100
// 相比於while 循環:while 中存在浪費內存的情況,因為循環變量在while循環外邊,直到它所在的花括號結束,才釋放內存。
// 而 for循環 的循環變量 在for循環結束後,即釋放。
// for (int j = 0; j < 100; j ++) {
// printf("%d \t",(j + 1));
// }
//打印 ***
// for (int i = 0; i < 3; i ++ ) {
// printf("*");
// }
循環嵌套
當我們發現,一個循環自身又要循環多次時,用循環嵌套:循環裡有循環。
//打印
/*
***
***
***
*/
//兩層for循環
//外層for:負責控制行
// for (int j = 0; j < 3; j++) {
// //內層 for 負責每行打印多少個
// for (int i = 0; i < 3; i ++ ) {
// printf("*");
// }
// printf("\n");
// }
//打印
/*
1
1 2
1 2 3
*/
// 裡邊的個數跟行數一樣,(第一行有一個,第二行有2個。。。)那麼只要 i <= j 就可以了。
// for (int j = 1; j <= 3; j++) {
// for (int i = 1; i <= j; i ++) {
// printf("%d ",i);
// }
// printf("\n");
// }
//打印乘法口訣表
// for (int i = 0; i < 9; i ++) {
// //列
// for (int j = 0; j <= i ; j ++) {
// printf(" %d * %d = %d \t",j+1,i+1,(j+1)*(i+1));
// }
// printf("\n");
// }
//三維數組合:
// 三個for循環
//百位 1~9
for (int i = 1; i <= 9 ; i++) {
//十位 0~9
for ( int j = 0 ; j <= 9; j++) {
//個位 0~9
for (int k = 0 ; k <= 9 ; k++) {
printf("%d\n",i * 100 + j * 10 + k);
}
}
}
——大海
2015年03月30日20:14:46 北京
19、數組
數組:相同的數據類型成員組成的數據。
如:整型數組,浮點型數組。
數組的形式為:
類型修飾符 數組名[常量表達式] = { 1,2,3……..};
說明:數組在定義的時候,[ ]裡必須用常量表達式,不能用變量表達式來代替。但是數組在使用的時候,[ ]中可以用變量來代替。
數組和循環是一對好基友。
數組的幾個注意的點:
1、只有定義時,[ ]內為常量表達式。不能放變量。
// int n =3;
// int arr1[n] = {10,20,30};//報錯
2、[ ]可以放算術式。
// int arr2[1+2] = {10,20,30};
3、初始化時可以放多余空間的元素(但是這是不對的)
// int arr3[3] = {10,20,30,40};
4、定義時,可以不給出常量表達式。(數組可以通過元素個數推算空間)。給出多少個元素,會自動給你分配多少空間
// int arr4[] = {10,20,30};
5、前三個空間值分別為10,20,30,後面的7個空間全部清0,為0。
// int arr5[10] = {10,20,30};
6、數組初始化
// int arr6[3] = {0};
// //錯誤的
// int arr7[] = {0};
一些例子:
//練習
// float arr_f[3] = {3.1,5.2,7.9};
//使用數組
// int arr8[3] = {10,20,30};
// printf("%d",arr8[0]);
// printf("%d",arr8[1]);
// printf("%d",arr8[2]);
數組取值:
//使用數組可以用下標取值
//下標可以使用變量
//數組可以使用循環取出所有值
// for (int i = 0; i < 3; i ++) {
// printf("%d \n",arr8[i]);
// }
越界
1、存儲的時候越界:
//第一種,存儲的時候越界
// int arr9[3] = {10,20,30,40};//此時,40 已經被寫入內存,但是取值的時候,40所在的內存空間已經被修改,所以取值的時候,很難取到40
//
// for (int i = 0; i < 4; i ++) {//循環4次,打印10,20,30,0(不同的計算機打印出來的值不同)
//
// printf("%d\n",arr9[i]);
// }
//
2、使用的時候越界
//第二種,使用的時候越界
// int arr10[3] = {10,20,30};
//
// arr10[0] = 50;//自己定義的數組,可以隨便改。
//
// printf("%d",arr10[0]);//打印50
//
//
// arr10[3] = 50;//可以訪問之後的任意空間,本數組的第4個內存空間位置,被改動。
//
// printf("%d",arr10[3]);//打印50
C語言可以通過我們定義的數組,操作本數組之後的所有內存空間,那些空間不屬於這個數組,誰都可以去用。因此可以在上面進行讀寫。這樣就會使得程序不安全。
數組越界是一件很危險的事情,我們無法把控,因此我們在操作程序是,盡可能的避免越界產生。
數組是一個整體,不能直接參與運算,只能對各個元素進行處理。
一些代碼:
//練習
//1、定義一個具有20個元素的整型數組,30~70 間的隨機數,求和。
// //定義數組,並清零,初始化。
// int array[20] = {0};
// // 求和變量
// int sum = 0;
// printf("20個隨機數為:\n");
// //產生20 個隨機數
// for (int i = 0; i < 20; i++) {
// unsigned num = arc4random() % (70-30+1)+30;
// printf("%d\t",num);
// array[i] = num;
// //不要在這個地方求和,一個for一個功能。增加代碼的重用性。
//// sum = sum + array[i];
// }
// //求和
// for (int i = 0; i < 20 ; i ++) {
// sum += array[i];
// }
//
//
// printf("\n\n20個數的和 sum = %d",sum);
//2、復制數組。
// int array1[5] = {10,20,30,40,50};
// int array2[5] = {0};
// for (int i = 0; i < 5; i ++) {
// array2[i] = array1[i];
// printf("%d\t",array2[i]);
// }
排序
冒泡排序
從第一個數開始,用第一個數分別與後面的數進行比較,若是大於後面的數,則將該數放在後面。然後再用第二個數跟後面的數比較,若大於後面的數,則將該數放在後面,依次類推,一直到最後一個數比較完畢為止。此時,排序已經完成。
//數組排序
// //冒泡排序(只適合小范圍的數據排序)(20遍)
// int sort_arr[5] = {5,4,3,2,1};
// //外層循環,控制排序趟數,趟數為 :數組元素個數-1
// for (int i = 0; i < (5-1)/*5-1,表示數組有n個數比較,只比較n-1趟*/; i ++) {
// //內層for循環,控制比較次數
// for (int j = 0; j < 5 - (i+1)/*本來應該是5-i,但是i是從0 開始的,我們要得是從1開始,因此要5-(i+1)。此處的意思是每一趟,比較多少次。*/; j ++) {
// //判斷,並且交換。
// if (sort_arr[j] > sort_arr[j+1]) {
// //交換,不使用第三個變量交換,用亦或 ^ 的方法最好。
// sort_arr[j] = sort_arr[j] ^ sort_arr[j+1];
// sort_arr[j+1] = sort_arr[j] ^ sort_arr[j+1];
// sort_arr[j] = sort_arr[j] ^ sort_arr[j+1];
// }
// }
// }
// //打印
// printf("冒泡排序後:");
// for (int i = 0; i < 5; i ++) {
// printf("%d\t",sort_arr[i]);
// }
//練習
// //隨機產生10個[20,40]間的數,排序
//
// int array[10] = {0};
// printf("排序前的10個數為:\n");
// //取隨機數
// for (int i = 0; i < 10 ; i ++) {
// unsigned num = arc4random() % 21+20;
// array[i] = num;
// printf("%d\t",array[i]);
// }
//
// //排序開始
// //外層for循環,控制比較多少趟。
// for (int i = 0; i < 10-1; i ++) {
// //內層for循環,控制比較多少次
// for (int j = 0; j < 10 -(i+1); j ++) {
// //冒泡排序
// if (array[j] > array[j+1]) {
// //亦或,用來交換兩個變量的值。
// array[j] = array[j] ^ array[j+1];
// array[j+1] = array[j] ^ array[j+1];
// array[j] = array[j] ^ array[j+1];
// }
// }
// }
// printf("\n排序後的10 個數為:\n");
// for (int i = 0 ; i < 10 ; i ++) {
// printf("%d\t",array[i]);
// }
字符數組
第一種定義:
char array[5] = {'h','e','l','l','o'};
第二種定義:
char array1[6] = "hello";
第二種定義在定義的時候,自動添加一個'\0'。這個\0有著特定的意義,在接下來輸出這個數組時,將會用%s來作為占位符,當%s在輸出數組時,遇到了’\0’這個特定意義的“結束標識符”時,就會終止打印,停止輸出。
此時,數組的實際長度為:字符數組元素個數+1,要留出'\0'的位置。
// //%s占位符
//// for (int i = 0; i <5 ; i++) {
//// printf("%c",array[i]);
//// }
// printf("%s",array);//打印:hello
一些情況:
// //自動推算出有6個位置
// char array2[] = "hello";
//
//
// //前面補滿,後面補0
// char array3[10] = "hello";
//存儲打印中文
// char array3[20] = "藍歐