1 一、四個月的課程體系 2 1、語言基礎 3 1、c語言10day 4 2、oc語言(真正開發語言)6day 5 3、foudation(庫) 6 2、iOS 核心編程 7 1、視圖層(如何做QQ的樣子,手勢、動畫) 8 3、iOS 高級編程 9 1、系統服務 10 2、網絡編程 11 4、游戲開發 12 1、學習C ++(主要用來開發游戲)可以跨平台 13 2、cocos2d-x 14 3、swift語言以及iOS8開發 15 二、什麼是ios開發 16 1.移動便攜式開發:android 和 iOS 17 2.iOS開發(iOS程序員、iOS軟件工程師) 18 3.android 和 iOS區別 19 a. iOS基於unix,安全穩定。android基於linux的虛擬機,安全性低 20 b. iOS強大的sdk、開發工具,不開源,apple公司,App Store(08年上線),高端用戶使用 21 android開源,google公司,googleplay應用商店,各種用戶人群, 22 三、ios開發環境 23 1.mac操作系統 24 1)操作系統os:管理硬件資源和軟件資源 25 2)macos:apple公司,自我封閉 26 3)iOS:設備:iPhone(2007年1月9日),iPod,touch,iPad, apple tv 27 2. 布局:菜單欄、桌面、dock(快捷鍵) 28 3.格式化u盤:磁盤工具——ms-dos(fat) 29 4.軟件安裝 30 1、*.dmg(setup.exe虛擬光驅) 31 2、*.app(綠色軟件)直接安裝 32 3、直接從app store 33 5.pwd、cd、is命令 34 1、操作計算機的兩種方式 35 a.圖形化操作方式(操作直觀) 36 b.命令行的操作方式(操作便捷,節約資源) 37 2、操作命令(終端快捷操作) 38 a.ls命令(查看當前文件夾下的文件或者子目錄) 39 b.pwd(查看當前操作目錄) 40 c.cd+空格+子目錄名稱(切換子目錄) 41 d.cd+空格+..(退回上一級目錄) 42 e.clear清除屏幕信息 43 f.mkdir+空格+文件夾(創建一個目錄) 44 g.rm+空格-f空格 刪除 45 3.相對路徑和絕對路徑(路徑兩種表達方式) 46 1./代表硬盤根目錄(/uses/tarena/doc) 47 2.相對路徑:相當於當前操作狀態下的文件(或目錄)的位置 48 3.絕對路徑:根據硬盤根目錄開始,文件(或目錄)的位置 49 4.文件夾的創建與查看 50 51 12.31 52 c語言(1973年貝爾實驗室) 53 1.四大部分:中央處理器(控制器、運算器)、存儲器、輸入設 備、輸出設備 (1946年,馮諾依曼) 54 2.計算機語言分類 55 機器語言、匯編語言、高級語言 56 3.編程:自己有個想法,通過計算機語言使計算機理解,並幫我 們實現。 57 一、c語言執行步驟: 58 一.編輯程序 59 1.編寫c語言的代碼,保存在擴展名.c的文件中,源文件。 60 2.編寫代碼有三種方式: 61 a.vi命令方式系統自帶 62 b.ultraedit網絡下載 63 c.xcode網絡下載 64 二.編譯(gcc 文件名.c) 65 將c語言轉換成計算機識別的代碼 66 三.運行(./a.out) 67 經過編輯、連接之後,源程序文件就可以生成可執行文件 68 * vi的使用-補充(c語言快捷鍵):shift+“:”進入編輯功能 69 wq退出 70 “i”insert進入編輯模式 71 四.xcode簡單的使用 72 1.創建項目 73 2.創建一個osx—command line Tool 74 3.main.c進行編程 75 4. 菜單欄product編譯-run執行 76 5.改字體(蘋果-第二個prefer..偏好設置-第五個改字體) 77 五.#include指令 78 1.在編譯之前做的事情 79 2.相當於復制操作 80 3.加載系統提供的標准函數庫 81 *“”是加載系統自定義功能 82 《》是加載系統功能 83 六.變量 84 1.數據類型:字符型char、整數型int、浮點型float/double、指 針、結構、聯合等類型。 85 2.語法格式:變量類型 變量名=初始化值 86 3.保存運算中臨時的值,number1=10賦值,可以多次賦值,但只會保留最後一次的值(右—左) 87 4.變量命名:a.必須以字母或下劃線開頭 88 b.包含字母、下劃線或數字(不要出現空格) 89 c.不能與關鍵字沖突 90 d.大小寫敏感的 91 e.長度一般不會限制,但會被編輯器截斷 92 93 *變量放在等號左邊就是存值操作,變量放在等式右邊就是取值操作 i=10(存),j=i(取).把右面的賦值給左邊的,從右向左 94 95 1.4 96 數據類型和變量賦值 97 1.整數類型 98 (char、int)小數類型(float、double) 99 a.有符號類型(整數、負數、0)范圍 ( -128~127) 100 *所占存儲空間的第一位為符號位。 101 *二進制符號位,最左邊0+,1代表負數 102 b.無符號整型(整數、0)(0~255)256 103 c.有符號的整型(int,4個字節 )(-2^31~2^31-1) 104 *Byte、KB、MB、GB、TB、PB(1024) 105 如:1KB=1024B 106 超出最大值從最小值開始運算 107 超出最小值從最大值開始運算 108 d.有符號的短整型(short int,2字節) 109 e.有符號的長整型(long int,8字節) 110 f.有符號的長長整型(long long int) 111 g.無符號的整型(unsigned int,4字節) 112 h.無符號短整型(unsigned short int,2字節) 113 i.無符號長整型(unsigned long int,8字節) 114 j.無符號長長整型(unsigned long long int,8字節) 115 2.進制 116 a.十進制%d(0-9)逢十進一 117 b.八進制%o(0-7)逢八進一 118 c.十六進制%x(0-9ABCDEF)逢十六進一 119 d.二進制(0、1)逢二進一 120 int i=11 //十進制 121 int i=011 //八進制 122 int i=0x11 //十六進制 123 *c語言不能使用二進制 124 1.十進制轉換二進制(除二取余,將余數從下向上讀出) 125 舉例: 126 32/2=17……0 127 17/2=8……1 128 8/2=4……0 129 4/2=2……0 130 2/2=1……0 131 1/2=0……1 132 將余數從下向上讀出:100010 133 134 2.二進制數轉化成十進制數(按權相加) 135 0 1 0 1 1 1 0 1位(從右向左)93 136 128 64 32 16 8 4 2 1權 137 舉例: 138 1001110 139 0*2^0=0 140 1*2^1=2 141 1*2^2=4 142 1*2^3=8 143 0*2^4=0 144 0*2^5=0 145 1*2^6=64 146 得出的值相加=0+2+4+8+0+0+64=78 147 3.十進制數轉換成八進制數、十六進制數 148 方法:輾轉相除,從下向上取余 149 34/8=16……6 150 16/8=2……0 151 2/8=0……2 152 從下向上對應的八進制數:206 153 4.八進制數、十六進制數轉換成十進制數 154 方法:按權相加法 155 6*8^0=6 156 0*8^1=0 157 2*8^2=128 158 按權相加:=134 159 5.二進制數轉換成八進制數 160 方法:從最後一位開始,每三位二進制數,相當於一個八進制數。前面不足3為補0 161 舉例:100 010=42 162 6.二進制轉換成十六進制數 163 方法:每四位,不足補0 164 舉例:0010 0010->22 165 3.字符(%c) 166 1.通過數值直接賦值 2.通過字符直接賦值 167 *.2f保留兩位有效數字 168 4.變量:臨時保存數據,數據的容器 169 常量:不可改變的值(具體的數值) 170 字面值:不可改變的值,就是數值(字符、數值) 171 *變量=字面值(常量)數據 172 173 練習題: 174 C語言中整數-8在內存中存儲形式是: 原碼->反碼->補碼(只有負數存的是補碼)(2個字節=16位) 175 A)1111,1111,1111,1000 B)1000,0000,0000,1000 176 C)0000,0000,0000,1000 D)1111,1111,1111,0111 177 178 一、知識點 179 一.scanf(“%d”,&i);&取地址 180 181 例題: 182 1.輸入兩個數,並輸出兩個數 183 #include <stdio.h> 184 185 int main(int argc, const char * argv[]) 186 { 187 int i=0,j=0; 188 189 printf("pelease input a number:"); 190 scanf("%d",&i); 191 printf("pelease input nest number:"); 192 scanf("%d",&j); 193 printf("i=%d\nj=%d",i,j); 194 return 0; 195 196 } 197 198 2.輸入兩個數,求其面積、周長、和 199 int main(int argc, const char * argv[]) 200 { 201 int i=0,j=0,sum=0,mj=0,zc=0; 202 printf("pelease input a number:"); 203 scanf("%d",&i); 204 printf("pelease input nest number:"); 205 scanf("%d",&j); 206 mj=i*j; 207 zc=(i+j)*2; 208 sum=i+j; 209 printf("面積=%d\n周長=%d\n和=%d\n",mj,zc,sum); 210 return 0; 211 } 212 213 3.輸入兩個數求和、差、積、商 214 int i = 0 , j = 0; 215 //輸入函數 要依賴於變量 要臨時保存在鍵盤上輸入的數據 216 //程序會發生阻塞狀態 217 //友好性差 配合輸出語句結合使用 218 printf("please input first Number:\n"); 219 scanf("%d",&i);//&得到變量在內存中的地址,將鍵盤上輸入的數據保存在變量中 220 printf("please input second Number:\n"); 221 scanf("%d",&j); 222 //輸出函數 223 printf("i:%d\n",i); 224 printf("j:%d\n",j); 225 226 int sum = 0;//求和 227 int sub = 0;//求差 228 int mul = 0;//求積 229 int div = 0;//求商 230 sum = i+j; 231 sub = i-j; 232 mul = i*j; 233 div = i/j;//整數相除取整數部分 234 printf("sum:%d\n",sum); 235 printf("sub:%d\n",sub); 236 printf("mul:%d\n",mul); 237 printf("div:%d\n",div); 238 return 0; 239 結果: 240 please input first Number: 241 45 242 please input second Number: 243 2 244 i:45 245 j:2 246 sum:47 247 sub:43 248 mul:90 249 div:22 250 251 252 4.數據類型省略寫法 253 int main(int argc, const char * argv[]) 254 { 255 signed int i=0;//有符號整型 可以省略signed 256 unsigned int i2=0;//無符號整型 257 short i3=0;//有符號短整型 可以省略 int 關鍵字 258 unsigned short i4=0;// 259 long i5=0;//有符號長整型 可以省略int 260 unsigned long i6=0; 261 long long i7=0;//長長整型 可以省略signed 和int 關鍵字 262 unsigned long long i8=0;// 263 264 return 0; 265 } 266 知識點 267 二、進制轉換 268 269 5.輸入一個數,分別以十進制、八進制、十六進制輸出變量 270 int main(int argc, const char * argv[]) 271 { 272 int i,j,k; 273 printf("輸入:"); 274 scanf("%d%d%d",&i,&j,&k); 275 printf("i=%d j=%o k=%x\n",i,j,k);//分別以十進制%d、八進制%o、十六進制%x輸出變量 276 return 0; 277 } 278 6.十進制、八進制、十六進制之間的轉換 279 int i=11,j=011,k=0x11; 280 printf("i=%d j=%o k=%x\n",i,i,i);//分別以十進制、八進制、十六進制輸出變量 281 printf("i=%d j=%o k=%x\n",j,j,j); 282 printf("i=%d j=%o k=%x\n",k,k,k); 283 return 0; 284 結果:i=11 j=13 k=b 285 i=9 j=11 k=9 286 i=17 j=21 k=11 287 288 7.制表符(\t) 空3個字符,一個漢字 289 printf("1234567890123456\n"); 290 printf("helloword!\n"); 291 printf("hello\tword!\n"); 292 293 return 0; 294 結果 295 1234567890123456 296 helloword! 297 hello word! 298 299 8.整型數據溢出 300 //數據溢出 301 int i = 2147483647;//999 + 1 302 int j = i + 1;//超出最大值從最小值開始運算 303 int k = -2147483648; 304 int l = k - 1;//超出最小值從最大值開始運算 305 printf("j:%d\n",j); 306 printf("l:%d\n",l); 307 return 0; 308 結果: 309 j:-2147483648 310 l:2147483647 311 312 9.浮點型(float:%f double: %lf) 313 float f = 3.1415926;//100 314 double d = 3.1415926;//200 315 float f2 = d;//100 = 200 316 //%.2f保留兩位有效數字 317 printf("float:%.2f\n",f); 318 printf("double:%lf\n",d); 319 return 0; 320 結果: 321 float:3.14 322 double:3.141593 323 324 知識點 325 三、sizeof:計算存儲空間的大小,單位:字節 326 sizeof()對應的數據類型是 long unsigned int ->%ld 327 328 10.sizeof所占空間大小 329 int i = 10; 330 long l = 20l; 331 long long ll = 30ll; 332 char c = 10; 333 334 float f = 10.1f; 335 double d = 10.1; 336 long double ld = 10.1l; 337 //求出某種類型或變量或字面值(常量)或表達式所占內存空間大小 338 //一定注意 變量的空間一定要大於字面值的空間,否則“可能”出現數據問題。 339 unsigned long int length = sizeof(d=20.1); //sizeof()不負責計算表達式的值 340 printf("d:%lf\n",d); 341 printf("length:%lu\n",length); 342 結果: 343 d:10.100000 344 length:8 345 知識點 346 四、運算符 347 348 11.優先級與結合性 349 int i = 3+4*5; 350 printf("i:%d\n",i); 351 int i2 = 3/2;//整數相除 結果還是整數 352 double d = 3.0/2;//如果相除時,有小數,則結果為小數 353 printf("i2:%d\n",i2); 354 printf("d:%lf\n",d); 355 356 //取余運算符% 357 int i3 = -5%2; 358 printf("i3:%d\n",i3); 359 360 //向0取整 361 int i4 = -5/2; 362 printf("i4:%d\n",i4); 363 364 //符號問題 365 int i5 = -5/-2;//與數學中的符號相同 366 printf("i5:%d\n",i5); 367 int i6 = 5%-2;//與前面的數字的符號相同 368 printf("i6:%d\n",i6); 369 結果: 370 i:23 371 i2:1 372 d:1.500000 373 i3:-1 374 i4:-2 375 i5:2 376 i6:1 377 378 12.例題:輸入一個秒數 求時分秒 379 int inputSecond = 0; 380 printf("請輸入一個秒數:\n"); 381 scanf("%d",&inputSecond); 382 383 int hour=0,minute=0,second=0; 384 385 //hour = inputSecond/3600; 386 //minute = (inputSecond-hour*3600)/60; 387 //second = inputSecond -hour*3600 - minute*60; 388 389 hour = inputSecond/3600; 390 minute = inputSecond%3600/60; 391 second = inputSecond%60; 392 393 printf("input的秒數=%d時%d分%d秒\n",hour,minute,second); 394 395 結果: 396 請輸入一個秒數: 397 3666 398 input的秒數=1時1分6秒 399 400 13.自增自減運算符 401 int i = 10; 402 //i++;//自增1 i = i + 1; 403 i--;//自減1 i = i - 1; 404 printf("i:%d\n",i); 405 406 int j = 10; 407 //int k = ++j;//前綴表達式 先自增 再運算(賦值) 408 int k = j++;//後綴表達式 先運算 後自增 409 printf("k:%d\n",k); 410 411 i = 10; 412 k=++i+(++i)+i++; 413 printf("k:%d\n",k); 414 return 0; 415 結果: 416 i:9 417 k:10 418 k:35 419 14.關系運算符 420 int i = 10; 421 int j = 20; 422 //>、<、>=、<=、==、!= 關系 423 printf("i>j:%d\n",i>j);//0 不成立 424 printf("i<j:%d\n",i<j);//1 成立 425 printf("i==j:%d\n",i==j);//0 426 printf("10>20:%d\n",10>20); 427 printf("10.1>20.1:%d\n",10.1>20.1); 428 printf("10.1>20:%d\n",10.1>20); 429 printf("'A'>'B':%d\n",'A'>'B');//ASC碼 430 printf("'A'<'B':%d\n",'A'<'B'); 431 結果: 432 i>j:0 433 i<j:1 434 i==j:0 435 10>20:0 436 10.1>20.1:0 437 10.1>20:0 438 'A'>'B':0 439 'A'<'B':1 440 15.練習題: 441 用戶從控制台輸入一個年齡,由程序判斷該年齡是否大於18歲,結果輸出1為真,0為否 442 int age = 0; 443 printf("請輸入一個年齡:\n"); 444 scanf("%d",&age); 445 printf("age>18:%d\n",age>18); 446 結果: 447 請輸入一個年齡: 448 45 449 age>18:1 450 16. 布爾類型(bool) 451 C99 版本新添加的數據類型 邏輯值類型bool類型 452 #include <stdbool.h> 頭文件 453 bool flag = false;//true 1 false 0 454 printf("flag:%d\n",flag); 455 結果:0 456 知識點 457 五、if語句條件分支語句 if…else if…else if 458 459 //條件 關系表達式 460 //邏輯值 真 (1 true 或 非0) 假(0 false) 461 1.if 語句書寫有三種形式 462 //普通語句(大括號可以省略)只會執行一條語句 463 if(true) printf("congratulation!"); 464 區別 465 1. //普通語句(大括號可以省略)沒有括號,只會執行一條語句 466 if(true) 467 printf("congratulation!"); 468 469 printf("congratulation!"); 470 471 472 2.//復合語句 要麼多執行 要麼都不執行 把多條語句變成一個整體 473 if(true){ 474 printf("congratulation!"); 475 476 printf("congratulation!"); 477 } 478 479 3.//空語句 480 if(age>18); 481 482 2.if…else 483 int age = 18; 484 485 if (age>=18) { 486 printf("你已經成年了!\n"); 487 }else{ 488 printf("你還未成年!\n"); 489 } 490 結果:你已經成年了! 491 492 3. if…else if…else 493 if(表達式1)語句1; 494 else if(表達式2) 語句2; 495 else if(表達式3) 語句3; 496 …… 497 else 語句5; 498 執行方式從頭開始判斷真假 499 500 17.練習 輸入小寫字母 得到相應的大寫字母 501 char ch; 502 printf("shuru"); 503 scanf("%c",&ch); 504 if(ch>=97){ 505 ch=ch-32;得到大寫字母 506 printf("=%c",ch); 507 508 }else{ 509 ch=ch+32;得到小寫字母 510 printf("=%c",ch); 511 } 512 return 0; 513 18.輸入一個分數,判斷這個分數是否及格? 514 int score = 0; 515 printf("請輸入一個分數:\n"); 516 scanf("%d",&score); 517 518 if (score>=90) { 519 printf("您的分數是優秀\n"); 520 } 521 else if(score>=60){ 522 printf("您的分數是及格\n"); 523 } 524 else{ 525 printf("您的分數是不及格\n"); 526 } 527 結果: 528 請輸入一個分數: 529 95 530 您的分數是優秀 531 19.輸入一個分數,得到相應的級別 532 int score=0; 533 printf("input:"); 534 scanf("%d",&score); 535 if(score>100) printf("GO OUT !!!"); 536 else if(score>=90) printf("A"); 537 else if(score>=80) printf("B"); 538 else if(score>=60) printf("C"); 539 else printf("D"); 540 return 0; 541 20.else if和if 比較 542 else if 相當於過一個十字路口:一次判斷,多種選擇 543 但是if 相當於過多個十字路口:多次判斷 544 1.一次判斷 多種選擇 只會選擇其一執行(滿足條件) 545 int score = 0; 546 printf("請輸入一個分數:\n"); 547 scanf("%d",&score); 548 if (score>=60) { 549 printf("60\n"); 550 }else if (score>=70){ 551 printf("70\n"); 552 }else{ 553 printf("else\n"); 554 } 555 結果: 556 請輸入一個分數: 557 90 558 60 559 2.多次判斷 多次執行(滿足條件) 560 int score = 0; 561 printf("請輸入一個分數:\n"); 562 scanf("%d",&score); 563 if (score>=60) { 564 printf("if 60\n"); 565 } 566 if (score>=70) { 567 printf("if 70\n"); 568 } 569 結果: 570 請輸入一個分數: 571 80 572 if 60 573 if 70 574 3.if在大括號裡如果滿足條件依次執行 575 int score = 0; 576 printf("請輸入一個分數:\n"); 577 scanf("%d",&score); 578 if (score>=60) { 579 printf("if 60\n"); 580 printf("if 70\n");} 581 582 結果: 583 請輸入一個分數: 584 80 585 if 60 586 if 70 587 21.邏輯運算符(&&、||) 588 int i=0,j=10;//邏輯與短路(短路與) 589 if((1!=1)&&(i=10))//若第一個表達式的值為假,後面的表達式不再計算 590 printf("i=%d",i); 591 //短路或 若第一個表達式值為真,後面的表達式不再計算 592 if((1==1)||(j=20)) 593 { 594 printf("j=%d",j); 595 } 596 return 0; 597 結果: 598 i:0 599 j:1 600 22.取地址&與尋址運算符* 601 int i = 30; 602 603 int* p = &i;//得到變量在內存中位置 604 printf("p:%p\n",p); 605 606 //通過尋址運算符 根據地址直接操作內存 607 //取 608 printf("內存中的數據:%d\n",*p); 609 //存 610 *p = 40; 611 printf("i:%d\n",i); 612 613 614 結果: 615 p:0x7fff5fbff70c 616 內存中的數據:30 617 i:40 618 619 作業 620 621 1.輸入一個年份,求該年一共有多少天。 622 int year; 623 printf("請輸入年份:\n"); 624 scanf("%d",&year); 625 if(year%400==0||((year%4==0)&&(year%100!=0))) 626 {printf("366天\n");} 627 else{printf("365天\n");} 628 結果: 629 請輸入年份: 630 2005 631 365天 632 老師的程序: int days=365+(year%400==0||((year%4==0)&&(year%100!=0))) 633 634 2.輸入一個年份,輸入一個月份,求該月有多少天? 635 //1.輸入年份 636 int year = 0; 637 printf("請輸入年份:\n"); 638 scanf("%d",&year); 639 //2.輸入月份 640 int month = 0; 641 printf("請輸入月份:\n"); 642 scanf("%d",&month); 643 //3.判斷不同的月份 天數是不一樣的 644 //1 3 5 7 8 10 12 31天 645 //4 6 9 11 30天 646 //2 閏年 29天 平年28天 647 int days = 0;//用來保存所求天數 648 if (month==4||month==6||month==9||month==11) { 649 days = 30; 650 }else if (month==2){ 651 days = 28 + ((year%400==0)||(year%4==0 && year%100!=0)); 652 }else{ 653 days = 31; 654 } 655 //4.輸出天數 656 printf("year:%d month:%d days:%d\n",year,month,days); 657 結果: 658 請輸入年份: 659 2005 660 請輸入月份: 661 12 662 year:2005 month:12 days:31 663 3.准備回家過年了,交通工具,通過輸入工資, 664 小於1300(最低工資),程序要報錯,工資大於10000 665 坐飛機回家,如果大於5000,就坐火車回家,如果大於 666 3000,就坐汽車回家。大於1500,就騎自行車回家,都 667 不滿足,步行。 668 int i=0; 669 printf("請輸入工資:"); 670 scanf("%d",&i); 671 if(i>=10000) 672 printf("飛機\n"); 673 else if(i>=5000) 674 printf("火車\n"); 675 else if(i>=3000) 676 printf("汽車\n"); 677 else if(i>=1500) 678 printf("自行車\n"); 679 else if(i<1300) 680 printf("程序報錯\n"); 681 else 682 printf("步行\n"); 683 684 4.通過鍵盤輸入4個值,求4個值中的最大值,最小值,和。 685 //1.輸入4個值 686 int num1=0,num2=0,num3=0,num4=0; 687 int sum = 0; 688 printf("請輸入第一個數:\n"); 689 scanf("%d",&num1); 690 sum+=num1; 691 printf("請輸入第二個數:\n"); 692 scanf("%d",&num2); 693 sum+=num2; 694 printf("請輸入第三個數:\n"); 695 scanf("%d",&num3); 696 sum = sum + num3; 697 printf("請輸入第四個數:\n"); 698 scanf("%d",&num4); 699 sum = sum + num4; 700 //2.求最大值 算法(邏輯) 701 int max = num1;//標尺 702 if (num2>max) {max = num2;} 703 if (num3>max) {max = num3;} 704 if (num4>max) {max = num4;} 705 printf("max:%d\n",max); 706 //求最小值 707 int min = num1;//標尺 708 if (num2<min) {min = num2;} 709 if (num3<min) {min = num3;} 710 if (num4<min) {min = num4;} 711 printf("min:%d\n",min); 712 713 //3.求最小值 714 //4.求和 715 //sum = sum + num3; 累加 716 //sum += num3;累加 但效率更高 (編譯原理) 717 //sum = num1+num2+num3+num4; 718 printf("sum:%d\n",sum); 719 結果: 720 請輸入第一個數: 721 8 722 請輸入第二個數: 723 6 724 請輸入第三個數: 725 5 726 請輸入第四個數: 727 9 728 max:9 729 min:5 730 sum:28 731 732 知識點 733 六、運算符 734 735 23.賦值運算符 736 int i = 20; 737 int j = 10; 738 int k = 15; 739 int l = 0; 740 l = (i = (j = (k = 5)));//從右向左運算的 右結合 741 printf("i:%d j:%d k:%d l:%d\n",i,j,k,l); 742 結果:i:5 j:5 k:5 l:5 743 744 1.按位異或操作 745 printf("5&3:%d\n",5&3); //0000 0101 746 int i = 5; //0000 0011 747 printf("~5:%d\n",~i); 748 int j = 3; 749 printf("5^3:%d\n",i^j);//按位異或操作 750 結果: 751 5&3:1 752 ~5:-6 753 5^3:6 754 755 2.調換兩個值(^) 756 int l = 5; 757 int r = 4; 758 printf("調換前: l:%d r:%d\n",l,r); 759 l^=r;//l=l^r; 760 r^=l;//r=r^l; 761 l^=r;//l=l^r; 762 /* 763 int temp = 0;//中間臨時變量 桌 764 temp = l; 765 l = r; 766 r = temp; 767 */ 768 printf("調換後: l:%d r:%d\n",l,r); 769 770 結果: 771 調換前: l:5 r:4 772 調換後: l:4 r:5 773 774 3.按位左移 按位右移 標識一些有規律的數據 775 int i2 = 1; 776 //數據(二進制數)<<(左移)移動位數 777 //0000 0001 <<1 0000 0010 778 printf("i2<<1:%d\n",i2<<1); 779 //0000 0001 <<2 0000 0100 780 printf("i2<<2:%d\n",i2<<2); 781 結果: 782 i2<<1:2 783 i2<<2:4 784 785 4.多目運算符 786 int i = 10; 787 int j = 20; 788 char c ; 789 c = i<j?'a':'b'; 790 printf("c:%c\n",c); 791 結果:c:a 792 793 24.重構利用多目運算符,輸入字符 如果大寫 轉換小寫 如果小寫 轉換大寫 794 char ch; 795 char ch2; 796 printf("請輸入一個字符:\n"); 797 scanf("%c",&ch); 798 //2.判斷 大->小 小->大 799 //ch2 = (ch>='A' && ch<='Z')?ch+('a'-'A'):ch-('a'-'A'); 800 //多目運算符的嵌套 801 /* 802 條件表達式?表達式1:表達式2; 803 條件表達式?(條件表達式?表達式1:表達式2):表達式2; 804 */ 805 ch2 = (ch>='A' && ch<='Z')?ch+('a'-'A'):(ch>='a'&&ch<='z')?ch- ('a'-'A'):'?'; 806 printf("ch:%c->ch2:%c\n",ch,ch2); 807 結果: 808 請輸入一個字符:ch:a->ch2:A 809 810 知識點 811 七、swich語句 812 25.輸入一個小寫的數字 輸出相應的大寫數字 1->一 813 //1.輸入一個小寫數字 814 int number = 0; 815 printf("請輸入一個小寫的數字:\n"); 816 scanf("%d",&number); 817 //2.根據不同的值進行不同的處理(條件分支) 818 819 switch (number) { 820 case 1: 821 printf("一\n"); 822 break;//終止switch語句繼續執行 823 //case 'a':printf("A\n"); 824 case 2: 825 printf("二\n"); 826 break; 827 case 3: 828 printf("三\n"); 829 break; 830 default:printf("您輸入的數據有誤!\n"); 831 break; 832 } 833 結果: 834 請輸入一個小寫的數字: 835 2 836 二 837 838 26.重構成績等級制輸入分數求級別 839 int score = 0; 840 printf("請輸入一個分數:\n"); 841 scanf("%d",&score); 842 //2.求相應的級別 843 //100/10 10 95/10 9 90/10 9 844 switch (score/10) { 845 case 10: 846 case 9:printf("A\n");break; 847 case 8: 848 case 7:printf("B\n");break; 849 case 6:printf("C\n");break; 850 default:printf("D\n"); 851 break; 852 結果: 853 請輸入一個分數: 854 90 855 A 856 27.重構等級制度輸入一個分數級別 857 //二、輸入一個分數級別 858 //求分數的范圍 A "您的分數范圍是90~100" 859 //1.輸入一個級別 860 char level; 861 printf("請輸入一個分數的級別:\n"); 862 scanf("%c",&level); 863 //2.根據級別求分數范圍 864 /* if分支語句 865 if (level=='A'||level=='a') { 866 printf("分數的范圍是90~100\n"); 867 }else if (level=='B'||level=='b'){ 868 printf("分數的范圍是70~90\n"); 869 }else if (level=='C'||level=='c'){ 870 printf("分數的范圍是60~70\n"); 871 }else{//E 872 printf("分數的范圍是0~60\n"); 873 }*/ 874 875 //switch語句 876 switch (level) { 877 default: 878 printf("0~60\n"); 879 break; 880 case 'B': 881 case 'b':printf("70~90\n");break; 882 case 'C': 883 case 'c':printf("60~70\n");break; 884 case 'A': 885 case 'a':printf("90~100\n");break; 886 結果: 887 請輸入一個分數的級別: 888 a 889 90~100 890 28.switch練習 891 //1.輸入數字 892 int number = 0; 893 printf("==================\n"); 894 printf("1.顯示全部記錄\n"); 895 printf("2.查詢登錄記錄\n"); 896 printf("3.退出\n"); 897 printf("==================\n"); 898 printf("請輸入你需要的功能:\n"); 899 scanf("%d",&number); 900 //2.根據不同數字 進行不同處理 901 switch (number) { 902 case 1: 903 printf("執行顯示全部記錄\n"); 904 break; 905 case 2: 906 printf("執行查詢登錄記錄\n"); 907 break; 908 case 3: 909 printf("退出系統\n");break; 910 default: 911 printf("您輸入的數據有請誤!\n"); 912 break; 913 } 914 結果: 915 ================== 916 1.顯示全部記錄 917 2.查詢登錄記錄 918 3.退出 919 ================== 920 請輸入你需要的功能: 921 2 922 執行查詢登錄記錄 923 924 知識點 925 八、for 循環 926 927 1.for循環 928 //0 1 2 3 4 5 6 7 8 9 929 //循環語句 重復的執行一段代碼 930 for (int i = 0; i<10; i++) { 931 //循環體 932 printf("跑了第%d圈\n",i); 933 } 934 935 //可以省略表達式1 可以放到其它位置 可能會出現問題 936 //可以省略表達式2 默認值是1 不可以放到其它位置 937 //可以省略表達式3 可以放到其它位置 但必須放在循環體的最後一條件語句 938 //三個表達式都可以省略 939 /* 940 for (int i=0;i<10;i++) { 941 printf("Hello\n"); 942 } 943 */ 944 結果: 945 跑了第0圈 946 跑了第1圈 947 跑了第2圈 948 跑了第3圈 949 跑了第4圈 950 跑了第5圈 951 跑了第6圈 952 跑了第7圈 953 跑了第8圈 954 跑了第9圈 955 956 957 958 29.循環作業 959 960 1.重構字母轉換(if語句)(邏輯運算符) 961 大寫—>小寫,小寫—>大寫,不是字母—>您輸入的數據有誤 962 963 2.求1-100的和1+2+3+5.....=5050 964 //求(輸出)1到100的和。 965 //1.拿1~100數 966 //表達式1 循環標識 967 //表達式2 循環條件 968 //表達式3 969 970 int sum = 0; 971 for (int i = 1; i<=100; i++) { 972 //printf("i:%d\n",i);//循環體 973 sum=sum+i;//累加求和 974 } 975 //2.求和 976 printf("sum:%d\n",sum); 977 結果:sum:5050 978 979 3.輸出1到100直間的奇數(不能被2整除的是奇數) 980 4.輸出1到100之間的偶數(能被2整除的是偶數) 981 for (int i = 1; i<=100; i++) { 982 //2.根據條件取得的數 983 if(i%2==0){ 984 printf(“偶數:%d\n”,i); 985 } 986 } 987 988 /*也可以用這樣的辦法求 989 for (int i = 1; i<=100; i=i+2) { 990 printf("i:%d\n",i); 991 } 992 */ 993 994 5.重構求10個數的最大值、最小值、和 995 int num = 0; 996 int sum = 0; 997 998 printf("請輸入第1個數:\n"); 999 scanf("%d",&num); 1000 int max = num;//標尺 1001 int min=num; 1002 sum = sum + num;//求和 1003 for (int i = 1; i<4 ; i++) { 1004 printf("請輸入第%d個數:\n",i+1); 1005 scanf("%d",&num); 1006 sum = sum + num;//求和 求累"積"? 1007 //求最大值 求最小值? 1008 if (num>max) { 1009 max = num; 1010 } 1011 if (num<min) { 1012 min = num; 1013 } 1014 } 1015 printf("sum:%d\n",sum); 1016 printf("max:%d\n",max); 1017 printf("max:%d\n",min); 1018 結果: 1019 請輸入第1個數: 1020 50 1021 請輸入第2個數: 1022 60 1023 請輸入第3個數: 1024 40 1025 請輸入第4個數: 1026 10 1027 sum:160 1028 max:60 1029 max:10 1030 6.在鍵盤上輸入一個數(任意正整數),求該數的長度 1031 123—3 4567—4 1032 int i=0,c; 1033 printf("請輸入:\n"); 1034 scanf("%d",&c); 1035 while(c) 1036 { c=c/10; 1037 i++;} 1038 printf("長度為:%d\n",i); 1039 結果: 1040 請輸入: 1041 123456 1042 長度為:6 1043 1044 7.打印水仙花數,水仙花數是一個3位數100—999,每個位的數值的立方剛好是這個數的本身。 1045 153=1*1*1+5*5*5+3*3*3,求水仙花數有哪些 1046 int i; 1047 int a,b,c; 1048 1049 for(i=100;i<1000;i++){ 1050 a=i/100; 1051 b=i%100/10; 1052 c=i%10; 1053 {if(i==a*a*a+b*b*b+c*c*c) 1054 1055 printf("%d\n",i);}} 1056 結果: 1057 153 1058 370 1059 371 1060 407 1061 知識點 1062 九、while循環 1063 /* 標准的while循環 1064 //int i = 0;//表達式1 循環標識 1065 //在while循環中 表達式2是不可以省略的 1066 while (i<10) {//表達式2 循環條件 1067 printf("Hello\n"); 1068 //i++;//表達式3 循環規律 1069 } 1070 */ 1071 //通過while循環的使用 只關注條件 1072 /* 1073 while (1<10) { //表達式2 循環條件 1074 printf("hello\n"); 1075 }*/ 1076 1077 //while循環的使用 1078 int num = 1;//保存用戶輸入的數據 1079 int count1 = 0;//統計正數有多少個 1080 int count2 = 0;//統計負數有多少個 1081 while (num!=0) { 遇到0就停止循環 1082 printf("執行循環體\n"); 1083 printf("請輸入一個數:\n"); 1084 scanf("%d",&num); 1085 printf("您輸入的數為:%d\n",num); 1086 //判斷是正數還是負數 1087 if (num>=0) {//正數 1088 count1++; 1089 } 1090 if (num<0) {//負數 1091 count2++; 1092 } 1093 } 1094 printf("正數有:%d個\n",count1++); 1095 printf("負數有:%d個\n",count2++); 1096 1097 printf("程序結束!\n"); 1098 //多次輸入一個數,只要不為0,就一直輸入,統計 1099 //輸入的數,有多少個是正數,有多少個是負數。 1100 結果: 1101 執行循環體 1102 請輸入一個數: 1103 60 1104 您輸入的數為:60 1105 執行循環體 1106 請輸入一個數: 1107 -60 1108 您輸入的數為:-60 1109 執行循環體 1110 請輸入一個數: 1111 0 1112 您輸入的數為:0 1113 正數有:2個 1114 負數有:1個 1115 程序結束! 1116 1117 知識點 1118 十、隨機數 1119 #include <stdio.h> 1120 //1.導入頭文件 1121 #include <time.h> 1122 #include <stdlib.h> 1123 #include <stdbool.h> 1124 int main(int argc, const char * argv[]) 1125 { 1126 /* 1127 int i = 200; 1128 char c; 1129 //類型轉換 int->char 1130 c = (char)i;//告訴其它程序員 類型轉換 有風險 1131 */ 1132 //2.使用函數 (unsigned)將有符號->符號 1133 srand((unsigned)time(0));//種子 1134 //0~21億 1135 //0~9 %10 1136 //0~99 %100 1137 //1~100 %100+1 1138 int num = rand()%100+1;//隨機數 1139 //printf("num:%d\n",num); 1140 bool isFlag = false;//標識是否猜正確 1141 int inputNum = 0;//輸入一個數 1142 int count = 0;//統計猜數次數 1143 while (!isFlag) { 1144 printf("請輸入您猜的數:\n"); 1145 scanf("%d",&inputNum); 1146 count++; 1147 //判斷 1148 if (inputNum==num) { 1149 printf("您猜對了!\n"); 1150 isFlag = true; 1151 printf("您一共猜了%d次!\n",count); 1152 }else{ 1153 printf("請繼續猜!\n"); 1154 if (inputNum>num) { 1155 printf("您上次輸入的數大了\n"); 1156 }else{ 1157 printf("您上次輸入的數小了\n"); 1158 } 1159 } 1160 } 1161 結果: 1162 請輸入您猜的數: 1163 60 1164 請繼續猜! 1165 您上次輸入的數小了 1166 請輸入您猜的數: 1167 80 1168 請繼續猜! 1169 您上次輸入的數大了 1170 請輸入您猜的數: 1171 70 1172 請繼續猜! 1173 您上次輸入的數大了 1174 請輸入您猜的數: 1175 65 1176 請繼續猜! 1177 您上次輸入的數小了 1178 請輸入您猜的數: 1179 69 1180 您猜對了! 1181 您一共猜了5次! 1182 1183 知識點 1184 十一、do…while循環 1185 //表達式1 循環標識 就算條件不成立 至少執行一次 1186 int i = 20; 1187 do { 1188 printf("HelloWorld\n");//循環體 1189 i++;//表達式3 1190 } while (i<10);//表達式2 循環條件 1191 /* 第一次循環不會進行判斷 1192 do{ 1193 }while(表達式2) 1194 */ 1195 /* 三個循環的區別 1196 for循環可以直接確定循環的次數 1197 while循環關注循環的條件 1198 do...while循環 第一次循環不會進行判斷,每次判斷的是下一次循環是否執行 1199 */ 1200 //重構猜數練習 1201 結果:HelloWorld (先執行do循環體的結果) 1202 1203 2.練習 1204 模擬輸入用戶名密碼(數字),設置一個數據庫(模擬數據寫死)中用戶名密碼(123,456),匹配則顯示登錄成功(則循環停止),否則登錄失敗,重新登錄。 1205 1206 #include <stdio.h> 1207 int main(int argc, const char * argv[]) 1208 { 1209 //1.模擬輸入用戶名密碼(數字) 1210 int username = 0;//用戶名 1211 int password = 0;//密碼 1212 //2.設置一個數據庫(模擬數據寫死)中用戶名密碼(123,456) 1213 int d_username = 123; 1214 int d_password = 456; 1215 //3.匹配則顯示登錄成功(則循環停止),否則登錄失敗,重新登錄。 1216 //a.輸入數據 1217 do{ 1218 printf("輸入用戶名:\n"); 1219 scanf("%d",&username); 1220 printf("請輸入密碼:\n"); 1221 scanf("%d",&password); 1222 }while ( !(username==d_username && password==d_password) ); 1223 printf("登錄成功!\n"); 1224 //用戶名和密碼 都相同 登錄成功 1225 //(username==d_username && password==d_password) 1226 或(同時使用break和continue) 1227 1228 //1.模擬輸入用戶名密碼(數字) 1229 int username = 0;//用戶名 1230 int password = 0;//密碼 1231 //2.設置一個數據庫(模擬數據寫死)中用戶名密碼(123,456) 1232 int d_username = 123; 1233 int d_password = 456; 1234 //3.匹配則顯示登錄成功(則循環停止),否則登錄失敗,重新登錄。 1235 //a.輸入數據 1236 do{ 1237 printf("輸入用戶名:\n"); 1238 scanf("%d",&username); 1239 printf("請輸入密碼:\n"); 1240 scanf("%d",&password); 1241 if (username==d_username && password==d_password) { 1242 printf("登錄成功!\n"); 1243 break; 1244 }else{ 1245 printf("登錄失敗,請重新登錄!\n"); 1246 continue; 1247 } 1248 }while (1); 1249 //用戶名和密碼 都相同 登錄成功 1250 //(username==d_username && password==d_password) 1251 1252 三個循環的特點: 1253 for:循環可以直接確定循環次數 1254 while :關注循環的條件 1255 do…while 循環:第一次循環不會進行判斷,每次判斷的是下一次循環是否執行! 1256 1257 知識點 1258 十二、break,continue 1259 1.循環中使用break; 1260 break;不但可以終止switch,也可以終止for循環語句 1261 舉例: 1262 int main() 1263 { 1264 int i=0; 1265 for (; i<10; i++) { 1266 if (i==3) { 1267 break;//終止循環的繼續執行 1268 } 1269 printf("hello:%d\n",i); 1270 } 1271 } 1272 練習: 1273 編寫一個求和程序。用戶從控制台輸入的整數的個數 不受限制,直到輸入整數0為止。將輸入的整數逐個相加後, 把結果輸出。 1274 int sum = 0; 1275 while (1) { 1276 //1.輸入一個整數 1277 int num = 0; 1278 printf("請輸入一個數:\n"); 1279 scanf("%d",&num); 1280 //2.循環輸入 直接輸入0時結束 break 1281 if (num==0) { 1282 break; 1283 } 1284 //3.求輸入整數之和並輸出 1285 sum+=num; 1286 printf("sum:%d\n",sum); 1287 } 1288 結果: 1289 請輸入一個數: 1290 45 1291 sum:45 1292 請輸入一個數: 1293 64 1294 sum:109 1295 請輸入一個數: 1296 0 1297 2.continue可以終止當次循環,繼續下一次循環 1298 相當於跳過當次,接著執行下面的 1299 int main() 1300 { 1301 for (int i=0; i<10; i++) { 1302 if (i==3) { 1303 continue; 1304 } 1305 printf("hello word:%d\n",i); 1306 } 1307 return 0; 1308 } 1309 結果: 1310 hello word:0 1311 hello word:1 1312 hello word:2 1313 hello word:4 1314 hello word:5 1315 hello word:6 1316 hello word:7 1317 hello word:8 1318 hello word:9 1319 1320 3.清空緩沖區 1321 scanf(“%*c”); 1322 舉例:有關回車所占的位置清空 1323 int main() 1324 { 1325 char a,b; 1326 printf("input:"); 1327 scanf("%c",&a); 1328 scanf("%*c");//清空緩沖區 1329 1330 printf("input:"); 1331 scanf("%c",&b); 1332 printf("a;%db:%d",a,b); 1333 } 1334 1335 知識點 1336 十三、for循環嵌套(相當於乘法) 1337 int main() 1338 { 1339 1.循環嵌套 外面的循環執行一次 裡面的循環執行一遍 1340 2.描述的是一個二維表 外面的循環代表行 裡面的代表列 1341 3.使用循環的嵌套輸出指定的圖形 1342 4.for可以嵌套 while可以嵌套 do…while 也可以嵌套 1343 5.for…while混合嵌套 1344 for (int j=0; j<2; j++) {//行 1345 for (int i=0; i<3; i++) {//列 1346 printf("i:%d j:%d\n",i,j); 1347 } 1348 printf("|\n"); 1349 } 1350 return 0; 1351 } 1352 結果: 1353 i:0 j:0 1354 i:1 j:0 1355 i:2 j:0 1356 | 1357 i:0 j:1 1358 i:1 j:1 1359 i:2 j:1 1360 | 1361 2.輸出指定的圖形 1362 for (int j=0; j<3; j++) { 1363 for (int i=0; i<5; i++) { 1364 printf("*"); 1365 } 1366 printf("\n"); 1367 } 1368 1369 3.while裡面嵌套while 1370 int main() 1371 { 1372 int i=0; 1373 while (i<9) {//行 1374 int j=0; 1375 while (j<9) { 1376 printf("%d%d ",i,j); 1377 j++; 1378 } 1379 printf("\n"); 1380 i++; 1381 } 1382 1383 return 0; 1384 } 1385 執行結果: 1386 00 01 02 03 04 05 06 07 08 1387 10 11 12 13 14 15 16 17 18 1388 20 21 22 23 24 25 26 27 28 1389 30 31 32 33 34 35 36 37 38 1390 40 41 42 43 44 45 46 47 48 1391 50 51 52 53 54 55 56 57 58 1392 60 61 62 63 64 65 66 67 68 1393 70 71 72 73 74 75 76 77 78 1394 80 81 82 83 84 85 86 87 88 1395 4.while裡面嵌套for 1396 for (int i = 0; i<9; i++) { 1397 int j = 0; 1398 while (j<9) { 1399 printf("%d%d ",i,j); 1400 j++; 1401 } 1402 printf("\n"); 1403 } 1404 1405 作業: 1406 1407 1.打印圖形(簡單) 1408 a.***** 1409 for (int i = 0;i<5; i++) { 1410 printf("*"); 1411 } 1412 printf("\n"); 1413 b. * 1414 ** 1415 *** 1416 **** 1417 ***** 1418 for (int j = 1; j<6; j++) { //行 1419 for (int k = 0; k<j; k++) {//列打印內容 1420 printf("*"); 1421 } 1422 printf("\n"); 1423 } 1424 1425 c.***** 1426 **** 1427 *** 1428 ** 1429 * 1430 for (int j = 1; j<6; j++) { //行 1431 for (int k = 0; k<6-j; k++) {//列打印內容 1432 printf("*"); 1433 } 1434 printf("\n"); 1435 } 1436 1437 d. * 1438 *** 1439 ***** 1440 for(int i=1;i<4;i++){ 1441 1442 for(int p=0;p<2*i-1;p++){ 1443 printf("*"); 1444 } 1445 printf("\n"); 1446 } 1447 1448 e. * * * * 1449 * * * * 1450 * * * * 1451 * * * * 1452 for(int i=1;i<5;i++){ 1453 1454 for(int p=0;p<i;p++){ 1455 printf(" "); 1456 } 1457 for(int j=0;j<4;j++){ 1458 1459 printf("* "); 1460 1461 }printf("\n"); 1462 } 1463 1464 2.99乘法表(中) 1465 1*1=1 1466 2*1=2 2*2=4 1467 3*1=3 3*2=6 3*3=9 1468 …… 1469 for (int i=1; i<=9; i++) { 1470 for (int j=1; j<=i; j++) { 1471 printf("%d*%d=%d ",i,j,i*j); 1472 } 1473 printf("\n"); 1474 } 1475 1476 3.三角形的輸出(中) 1477 for(int i=1;i<5;i++){ 1478 1479 for(int p=1;p<5-i;p++){ 1480 printf(" "); 1481 } 1482 for(int j=0;j<2*i-1;j++){ 1483 1484 printf("*"); 1485 1486 }printf("\n"); 1487 } 1488 * 1489 *** 1490 ***** 1491 ******* 1492 1493 4.輸入一個數 求數的位數…(高) 1494 for/while/do…while 1495 123->3 4567->4 1496 int num = 0; 1497 printf("請輸入一個數:\n"); 1498 scanf("%d",&num); 1499 int length = 0;//除的次數(長度) 1500 while (1) { 1501 length++; 1502 num = num/10; 1503 if (num==0) { 1504 break; 1505 } 1506 } 1507 printf("length:%d\n",length); 1508 結果: 1509 請輸入一個數: 1510 12345 1511 length:5 1512 知識點 1513 十四、一維數組 1514 一維數組 1515 數組是用來存儲多條相同數據類型的數據結構(容器) 1516 定義數組: 1517 int array[3]; 1518 訪問元素:array[0]=10; 1519 1520 數組名是地址:不能給數組名賦值 1521 數組變量只可以在初始化的時候賦值並且是常量 1522 舉例:%p 1523 int array[3];//數組類型 元素類型 數組名【長度】 1524 array[0]=10;//數組名【下標】 變量=(存值)=變量(取值) 1525 array[1]=20; 1526 array[2]=30; 1527 printf("array[0]:%d\n",array[0]); 1528 printf("array[1]:%d\n",array[0]); 1529 printf("array[2]:%d\n",array[0]); 1530 return 0; 1531 1532 舉例 1533 int array[3];//數組類型 元素類型 數組名【長度】 1534 array[0]=10;//數組名【下標】 變量=(存值)=變量(取值) 1535 array[1]=20; 1536 array[2]=30; 1537 printf("array[0]:%d\n",array[0]); 1538 printf("array[1]:%d\n",array[0]); 1539 printf("array[2]:%d\n",array[0]); 1540 1541 int i=10; 1542 printf("address:%p\n",&i);//&取地址運算符 1543 1544 printf("array address:%p\n",&array);//array數組變量 array[0]數組元素變量 1545 printf("array address:%p\n",array); 1546 //得到數組中首元素的地址 &array[0] 1547 printf("array address:%p\n",&array[0]); 1548 結果:array[0]:10 1549 array[1]:10 1550 array[2]:10 1551 address:0x7fff5fbff8d8 1552 array address:0x7fff5fbff8dc 1553 array address:0x7fff5fbff8dc 1554 array address:0x7fff5fbff8dc 1555 1556 1557 1558 練習:通過鍵盤輸入5個數,輸入後輸出相應的5個數是什麼 1559 1560 int array2[5]={};//初始化 1561 int j; 1562 //數組使用的時候,經常與循環(for)結合使用 1563 //輸入5個數 1564 for (int i=0; i<5; i++) { 1565 printf("input:",i+1); 1566 scanf("%d",&array2[i]); 1567 1568 }//輸出5個數 1569 for (int j=0; j<5; j++) { 1570 printf("output:%d",array2[j]); 1571 } 1572 1573 2. //數組所占空間=元素所占空間*數組的長度 1574 //?只要知道數組的名字 就能求出數組的長度 1575 //數組的長度=數組所占空間/元素所占空間 1576 1577 float array3[3] = {10.1,20.1,30.1}; 1578 //數組變量只可以在初始化的時候賦值並且是常量 1579 //array3 = {10.1,20.1,30.1}; 1580 //array3 = &... 1581 1582 int length = 0; 1583 //sizeof 變量 類型 常量 表達式 1584 printf("sizeof(array3) size:%lu\n",sizeof(array3)); 1585 printf("sizeof(array3[0]) size:%lu\n",sizeof(array3[0])); 1586 length = sizeof(array3)/sizeof(array3[0]); 1587 printf("length:%d\n",length); 1588 1589 //輸出5個數 1590 for (int j=0; j<sizeof(array3)/sizeof(array3[0]); j++) { 1591 printf("第%d個數:%f\n",j+1,array3[j]); 1592 } 1593 結果: 1594 sizeof(array3) size:12 1595 sizeof(array3[0]) size:4 1596 length:3 1597 第1個數:10.100000 1598 第2個數:20.100000 1599 第3個數:30.100000 1600 1601 3.可變數組 1602 1、在C語言中,可變數組指的是數組在聲明前其長度是可變的,一旦聲明,數組的長度就不可變了。 1603 2、在oc語言中,專門有一種數據類型叫可變數組,數組在使用過程中,其長度是可變的。 1604 int count; 1605 printf("請輸入班級的人數:\n"); 1606 scanf("%d",&count); 1607 //可變數組在使用前 必須確定數組的長度 1608 //一但聲明,數組的長度不可修改 1609 int scores[count];//可變數組 是不能初始化 1610 int sum = 0; 1611 for (int i = 0; i<count; i++) { 1612 printf("請輸入第%d個的成績:\n",i+1); 1613 scanf("%d",&scores[i]); 1614 sum+=scores[i]; 1615 } 1616 printf("sum:%d\n",sum); 1617 1618 練習:輸入10個數,求10個數中的最大值,最小值,和。並且輸入該值所在位置(最大值,最小值) 1619 #include <stdio.h> 1620 #include <time.h> 1621 #include <stdlib.h> 1622 int main(int argc, const char * argv[]) 1623 { 1624 int nums[5] = {0}; 1625 srand((unsigned)time(0)); 1626 //1.輸入5個數 1627 for (int i = 0; i<5; i++) { 1628 /* 輸入5個數 1629 printf("請輸入第%d個數:\n",i+1); 1630 scanf("%d",&nums[i]); 1631 */ 1632 /*隨機生成5個數*/ 1633 nums[i]= rand()%100+1; 1634 1635 } 1636 //2.得到最大值 得到相應的位置 1637 int maxIndex = -1; 1638 int minIndex = -1; 1639 //a.標尺 (1)拿第一個值當標尺 1640 //int max = nums[0]; 1641 //(2)指定一個值作為標尺 1642 //給最小值一個最大值的初值 1643 //給最大值一個最小值的初值 1644 int max = 0; 1645 int min = 100; 1646 //b.每一個值和標尺比 1647 //得到數組中的每一個元素 "遍歷" 1648 for (int i = 0; i<5; i++) { 1649 if(nums[i]> max){ 1650 max = nums[i]; 1651 maxIndex = i;//保存最大值的下標 1652 } 1653 if (nums[i]<min) { 1654 min = nums[i]; 1655 minIndex = i; 1656 } 1657 } 1658 printf("max:%d maxIndex:%d\n",max,maxIndex); 1659 printf("min:%d minIndex:%d\n",min,minIndex); 1660 //3.得到最小值 得到相應的位置 1661 //4.求和 1662 結果: 1663 max:95 maxIndex:3 1664 min:29 minIndex:1 1665 1666 4.數組的復制、拷貝 1667 int array[3] = {4,5,6}; 1668 int array2[3]; 1669 //不可以直接賦值數組變量 1670 //array2 = array;//數組一但聲明 地址是不可修改 1671 for (int i = 0; i<3; i++) { 1672 array2[i] = array[i];//取出第一個數組中每一個元素 1673 } 1674 //查看數組2中的內容 1675 for (int j = 0; j<3; j++) { 1676 printf("array2[%d]:%d\n",j,array2[j]); 1677 } 1678 結果: 1679 array2[0]:4 1680 array2[1]:5 1681 array2[2]:6 1682 1683 5.數組的亂序 1684 1685 #include <stdio.h> 1686 #include <time.h> 1687 #include <stdlib.h> 1688 int main(int argc, const char * argv[]) 1689 { 1690 int array[10] = {1,2,3,4,5,6,7,8,9,0}; 1691 srand((unsigned)time(0)); 1692 for (int i = 0; i<10; i++) { 1693 //x交換位置 隨機生成 1694 /* 1695 0~9 1696 1~9 1697 2~9 1698 3~9 1699 */ 1700 int x = rand()%(10-i)+i;//只是為了更隨機 1701 //array[i]當前的位置 1702 //array[x]隨機生成的交換位置 1703 //交換兩個值 1704 int temp = array[i]; 1705 array[i] = array[x]; 1706 array[x] = temp; 1707 } 1708 //輸出交換後的數組內容 1709 for (int i = 0; i<10; i++) { 1710 printf("array[%d]:%d\n",i,array[i]); 1711 } 1712 1713 return 0; 1714 } 1715 結果: 1716 array[0]:4 1717 array[1]:1 1718 array[2]:8 1719 array[3]:0 1720 array[4]:9 1721 array[5]:6 1722 array[6]:3 1723 array[7]:7 1724 array[8]:5 1725 array[9]:2 1726 1727 6.正反向遍歷 1728 int main() 1729 { 1730 int array[5]={1,2,3,4,5}; 1731 for (int i=0; i<5; i++) { 1732 printf("%d",array[i]); 1733 1734 } 1735 printf("\n"); 1736 for (int i=4; i>=0; i--) { 1737 printf("%d",array[i]); 1738 } 1739 return 0; 1740 } 1741 結果 1742 12345 1743 54321 1744 7.數組元素的重復 1745 若輸入數據有重復的數字,把重復的數據表現出來 1746 int main() 1747 { 1748 int num=0; 1749 int count=0; 1750 // int temp=num;//復制一份輸入的值 1751 int array[count]; 1752 1753 printf("input"); 1754 scanf("%d",&num); 1755 int temp=num; 1756 while (temp) {//求長度 1757 count++; 1758 temp/=10; 1759 // printf("%d",temp); 1760 } 1761 for (int i=0; num; i++) {//求出數組中的每一個數值 1762 array[i]=num%10;//取出每一位的值並保存 1763 num/=10; 1764 } 1765 for (int i=0; i<count; i++) {//每次都是與前一次進行比較 1766 for (int j=0; j<i; j++) { 1767 // printf("%d%d",i,j); 1768 if (array[i]==array[j]) { 1769 printf("chongf%d\n",array[i]); 1770 } 1771 } 1772 } 1773 return 0; 1774 1775 } 1776 結果: 1777 input5864564 1778 chongf4 1779 chongf8 1780 chongf5 1781 1782 1783 練習: 1784 隨機產生6個紅球和1個籃球,並且紅球不重復,並輸出紅球和籃球 1785 int main() 1786 { 1787 //1.生成幾個隨機數 1788 //2.隨機數的范圍 1789 //3.隨機數的樣子 1790 //4.所求隨機數 紅 藍 1791 int blue=0; 1792 int red[6]={0}; 1793 srand((unsigned)time(0)); 1794 blue=rand()%16+1; 1795 for (int i=0; i<6; i++) {//red[i]=當前生成的隨機數 1796 red[i]=rand()%33+1; 1797 for (int j=0; j<i; j++) {//red[j]=之前生成的隨機數 1798 if (red[j]==red[i]) { 1799 i--; 1800 break;//只要發現一個重復的,後面的就不需要判斷了 1801 } 1802 } 1803 } 1804 1805 //判斷之前是否有重復 1806 for (int i=0; i<6; i++) { 1807 printf("%d ",red[i]); 1808 } 1809 printf("%d\n",blue); 1810 } 1811 1812 練習 日歷 1813 1814 int days[40] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,1,2,3,4,5,6,7,8,9,10};//40應該是365 1815 int startIndex = 1;//1號在星期幾 1816 int index = 0;//取到幾號了 1817 printf("一\t二\t三\t四\t五\t六\t日\n"); 1818 if (startIndex==1) { 1819 printf(" \t"); 1820 } 1821 do { 1822 if(startIndex%7!=0){//標識 所在位置 1823 printf("%d\t",days[index++]); 1824 }else{ 1825 printf("\n%d\t",days[index++]); 1826 } 1827 startIndex++; 1828 if (index==40) { 1829 break; 1830 } 1831 }while (1); 1832 printf("\n"); 1833 結果: 1834 一 二 三 四 五 六 日 1835 1 2 3 4 5 6 1836 7 8 9 10 11 12 13 1837 14 15 16 17 18 19 20 1838 21 22 23 24 25 26 27 1839 28 29 30 1 2 3 4 1840 5 6 7 8 9 10 1841 1842 知識點 1843 十五、二維數組 1844 //元素類型 數組名[數組長度]; 1845 int array[3]={0};初始化 1846 //array[下標] 下標<數組長度 1847 // 數組= 存值 =數組 取值 1848 //二維數組 3外層(一維)數組的長度,2內層(二維)數組的長度 1849 //元素類型 二維數組名[一維長度][二維長度]; 1850 int array[3][2]; 1851 //二維數組的操作 array[下標1][下標2] 1852 int array2[4][3]={1,2,3,4,5,6,7,8,9,10,11,12}; 1853 //二維數組與循環嵌套使用 1854 //外層循環對應二維數組一維的下標 1855 //內層循環對應二維數組二維的下標 1856 // printf("%d",array2[2][0]); 1857 1858 int array[3][2]={{1,2},{3,4},{5,6}};//對應元素內容 1859 int array1[3][2]={1,2,3,4,5,6};//整體賦值 1860 int array2[3][2]={1,2,3,4};//依次賦值 自動補零 1861 1862 練習 1863 1.輸入5個學生,3門課的成績, 1864 2.求每個學生 總成績 X 1865 求每個課程 總成績 Y 1866 3.顯示 1867 #include <stdio.h> 1868 1869 int main(int argc, const char * argv[]) 1870 { 1871 //保存5個學生3門課的成績 1872 int score[3][5] = {0}; 1873 int sum[3] = {0};//各門課的總成績 1874 int psum[5] = {0};//各個人的總成績 1875 //輸入每一個學生的成績 1876 for (int i=0; i<3; i++) { 1877 for (int j=0; j<5; j++) { 1878 //printf("請輸入%d行(課程)%d列(姓名)的成績\n",i,j); 1879 printf("請輸入"); 1880 //課程 1881 switch (i) { 1882 case 0: 1883 printf("語文"); 1884 break; 1885 case 1: 1886 printf("數學"); 1887 break; 1888 case 2: 1889 printf("英語"); 1890 break; 1891 } 1892 //姓名 1893 switch (j) { 1894 case 0: 1895 printf("張"); 1896 break; 1897 case 1: 1898 printf("李"); 1899 break; 1900 case 2: 1901 printf("王"); 1902 break; 1903 case 3: 1904 printf("趙"); 1905 break; 1906 case 4: 1907 printf("錢"); 1908 break; 1909 } 1910 printf("的成績\n"); 1911 scanf("%d",&score[i][j]); 1912 //求每門課的成績和 1913 sum[i]+=score[i][j]; 1914 //求每個人的總成績和 1915 psum[j]+=score[i][j]; 1916 } 1917 } 1918 printf("\t張\t李\t王\t趙\t錢\n"); 1919 //輸出每一個學生的成績 1920 for (int i=0; i<3; i++) { 1921 //每一行的行頭 1922 switch (i) { 1923 case 0: 1924 printf("語文"); 1925 break; 1926 case 1: 1927 printf("數學"); 1928 break; 1929 case 2: 1930 printf("英語"); 1931 break; 1932 } 1933 printf("\t"); 1934 for (int j=0; j<5; j++) { 1935 printf("%d\t",score[i][j]); 1936 } 1937 printf("\n"); 1938 1939 } 1940 //查看每門課的總成績 1941 for (int i = 0; i<3; i++) { 1942 switch (i) { 1943 case 0: 1944 printf("語文"); 1945 break; 1946 case 1: 1947 printf("數學"); 1948 break; 1949 case 2: 1950 printf("英語"); 1951 break; 1952 } 1953 printf("的總成績為:%d\n",sum[i]); 1954 } 1955 //每個人的總成績? 1956 return 0; 1957 } 1958 結果: 1959 …… 1960 80 1961 請輸入英語錢的成績 1962 80 1963 張 李 王 趙 錢 1964 語文 60 60 60 60 60 1965 數學 70 70 70 70 70 1966 英語 80 80 80 80 80 1967 語文的總成績為:300 1968 數學的總成績為:350 1969 英語的總成績為:400 1970 知識點 1971 十六、函數 1972 1973 特點:1.結構清晰2.重復使用 1974 1975 1.函數的參數 1976 #include <stdio.h> 1977 //1.聲明 1978 //返回值類型 函數名(參數); 1979 //推薦:***只要使用函數一定要聲明 1980 void sayHello(int i);//函數的原型 1981 //void代表空 聲明時不寫參數 代表任意個數的參數 1982 //如果不需要參數必須聲明成void 1983 //***函數的聲明與函數的定義可以一致 1984 //聲明的時候 定義的時候 參數形參 1985 //參數:如果函數執行的時候 需要有參考依據就要使用參數 1986 void sayHello(){ //函數體 真正解決問題代碼 1987 printf("Hello\n"); 1988 } 1989 //void sayHello5(); 1990 //2.定義 1991 void sayHello5(){ 1992 printf("Hello\n"); 1993 printf("Hello\n"); 1994 1995 } 1996 練習1: 1997 想輸出幾個Hello就輸出幾個Hello 1998 void sayHelloN(int n);//聲明 1999 void sayHelloN(int n){ 2000 for (int i=0; i<n; i++) { 2001 printf("Hello\n"); 2002 } 2003 } 2004 //程序執行的->main()->sayHello(); 2005 int main(int argc, const char * argv[]) 2006 { 2007 //3.調用 如果定義的時候有參數,調用的時候就必須輸入參數,聲明與調用要統一 2008 //sayHello(20);//調用時候的參數就是實參 2009 //sayHello5(); 2010 sayHelloN(3); 2011 printf("...幾百行\n"); 2012 //sayHello5();//函數中定義的代碼可以多次使用 2013 結果: 2014 Hello 2015 Hello 2016 Hello 2017 ...幾百行 2018 2019 練習2: 2020 早 晚 中 吃啥? 2021 //寫函數根據不同值來決定吃什麼 2022 //0魚香肉絲 1地三鮮 2土豆絲 3.宮爆雞丁 2023 //other.吃餃子 2024 #include <stdio.h> 2025 //1.聲明 2026 void eat(int num);//根據數據決定吃什麼 2027 //2.定義 2028 //如果函數需要多個參數,需要用,號分隔開。 2029 //參數的類型不限制,但必須聲明其類型。 2030 //void eat(int num1,int num2) 2031 //void eat(int num1,char ch) 2032 void eat(int num){ 2033 //0魚香肉絲 1地三鮮 2土豆絲 3.宮爆雞丁 2034 switch (num) { 2035 case 0: 2036 printf("魚香肉絲\n"); 2037 break; 2038 case 1: 2039 printf("地三鮮\n"); 2040 break; 2041 case 2: 2042 printf("土豆絲\n"); 2043 break; 2044 case 3: 2045 printf("宮爆雞丁\n"); 2046 break; 2047 default: 2048 printf("吃餃子\n"); 2049 break; 2050 } 2051 } 2052 #include <time.h> 2053 #include <stdlib.h> 2054 int main(int argc, const char * argv[]) 2055 { 2056 srand((unsigned)time(0)); 2057 int temp; 2058 printf("早上起床了,吃啥呢?\n"); 2059 //scanf("%d",&temp); 2060 temp = rand()%5; 2061 //參數也可以是一個表達式,但必須有結果 2062 eat(1+2); 2063 2064 printf("又到中午了,吃啥呢?\n"); 2065 temp = rand()%5; 2066 eat(temp); 2067 2068 printf("晚上了,吃啥呢?\n"); 2069 temp = rand()%5; 2070 eat(temp); 2071 結果: 2072 早上起床了,吃啥呢? 2073 宮爆雞丁 2074 又到中午了,吃啥呢? 2075 地三鮮 2076 晚上了,吃啥呢? 2077 宮爆雞丁 2078 2079 2.函數的返回值 2080 2081 練習 2082 /帶飯 2083 //吃什麼口味的 0甜 1鹹 2辣 2084 //0->魚(Y) 1->土(T) 2->尖(J) 2085 2086 #include <stdio.h> 2087 /char buy(int taste); 2088 //如果定義了返回值類型 函數執行後必須有返回值 2089 char buy(int taste){ 2090 switch (taste) { 2091 case 0: 2092 return 'Y'; 2093 break; 2094 case 1: 2095 return 'T'; 2096 break; 2097 case 2: 2098 return 'J'; 2099 break; 2100 default: 2101 return 'Y'; 2102 } 2103 } 2104 2105 int main(int argc, const char * argv[]) 2106 { 2107 //中午幫我帶個飯 我要辣的 2108 //調用一個函數的時候,如果函數有返回值,必須要接收或處理 2109 char ch = buy(0); 2110 printf("ch:%c\n",ch); 2111 結果:ch:Y 2112 2113 3.函數的參數是數組 2114 2115 1.求數組的長度 2116 int a[]={1,2,3,4,5}; 2117 int length=sizeof(a)/sizeof(a[0]); 求數組的長度 2118 printf("length:%d\n",length); 2119 結果: 2120 length:5 2121 2122 2.參數是數組 2123 #include <stdio.h> 2124 void func(int length,int *p); 2125 void func(int length,int *p){ 2126 for (int i = 0; i<length; i++) { 2127 printf("array[%d]:%d\n",i,*(p+i)); 2128 } 2129 } 2130 //參數 如果是數組,必須指定兩個值 2131 //1.數組的長度 2,數組名 2132 void func2(int lenght,int array[]); 2133 void func2(int lenght,int array[]){ 2134 for (int i = 0; i<lenght; i++) { 2135 printf("array[%d]:%d\n",i,array[i]); 2136 } 2137 } 2138 2139 2140 int main(int argc, const char * argv[]) 2141 { 2142 int array[] = {1,2,3,4,5}; 2143 int length = sizeof(array)/sizeof(array[0]); 2144 printf("length:%d\n",length); 2145 2146 //int *p = &i; 2147 //int *p = &array[0]; 2148 int *p = array; 2149 2150 //func(array); 2151 //如果函數的參數是數組 使用兩個參數 2152 //參數1 為數組的長度 參數2 數組的指針 2153 func2(length,array); 2154 2155 return 0; 2156 } 2157 結果:length:5 2158 array[0]:1 2159 array[1]:2 2160 array[2]:3 2161 array[3]:4 2162 array[4]:5 2163 2164 作業: 2165 1.求兩個數的和 2166 2167 #include <stdio.h> 2168 #include<stdlib.h> 2169 #include<time.h> 2170 2171 int count(int a,int b); 2172 int count(int a,int b){ 2173 2174 //printf("%d",sum); 2175 return a+b; 2176 } 2177 2178 int main(int argc, const char * argv[]) { 2179 int a; 2180 int i,j; 2181 srand((unsigned)time(0));//隨機得到兩個數 2182 i=rand()%10; 2183 j=rand()%10; 2184 a= count(i,j);// return的返回值賦給a 2185 printf("%d",a); 2186 結果:11 2187 2188 2.重構 成績打印 2189 2190 #include <stdio.h> 2191 void kemu(int i); 2192 void xingming(int j); 2193 2194 void kemu(int i){ 2195 switch (i) { 2196 case 0: 2197 printf("語文"); 2198 break; 2199 case 1: 2200 printf("數學"); 2201 break; 2202 case 2: 2203 printf("英語"); 2204 break; 2205 } 2206 2207 } 2208 void xingming(int j){ 2209 switch (j) { 2210 case 0: 2211 printf("張"); 2212 break; 2213 case 1: 2214 printf("李"); 2215 break; 2216 case 2: 2217 printf("王"); 2218 break; 2219 case 3: 2220 printf("趙"); 2221 break; 2222 case 4: 2223 printf("錢"); 2224 break; 2225 } 2226 2227 } 2228 2229 int main(int argc, const char * argv[]) 2230 { 2231 //保存5個學生3門課的成績 2232 int score[3][5] = {0}; 2233 int sum[3] = {0};//各門課的總成績 2234 int psum[5] = {0};//各個人的總成績 2235 //輸入每一個學生的成績 2236 for (int i=0; i<3; i++) { 2237 for (int j=0; j<5; j++) { 2238 printf("請輸入"); 2239 //課程 2240 kemu(i); 2241 //姓名 2242 xingming(j); 2243 printf("的成績:"); 2244 scanf("%d",&score[i][j]); 2245 //求每門課的成績和 2246 sum[i]+=score[i][j]; 2247 //求每個人的總成績和 2248 psum[j]+=score[i][j]; 2249 } 2250 } 2251 printf("\t張\t李\t王\t趙\t錢\n"); 2252 //輸出每一個學生的成績 2253 for (int i=0; i<3; i++) { 2254 //每一行的行頭 2255 kemu(i); 2256 printf("\t"); 2257 for (int j=0; j<5; j++) { 2258 printf("%d\t",score[i][j]); 2259 } 2260 printf("\n"); 2261 2262 } 2263 //查看每門課的總成績 2264 for (int i = 0; i<3; i++) { 2265 kemu(i); 2266 printf("的總成績為:%d\n",sum[i]); 2267 } 2268 //每個人的總成績 2269 for (int j=0; j<5; j++) { 2270 xingming(j); 2271 printf("的總成績為:%d\n",sum[j]); 2272 } 2273 return 0; 2274 } 2275 結果: 2276 請輸入語文張的成績:60 2277 請輸入語文李的成績:60 2278 請輸入語文王的成績:60 2279 請輸入語文趙的成績:60 2280 請輸入語文錢的成績:60 2281 請輸入數學張的成績:70 2282 請輸入數學李的成績:70 2283 請輸入數學王的成績:70 2284 請輸入數學趙的成績:70 2285 請輸入數學錢的成績:70 2286 請輸入英語張的成績:80 2287 請輸入英語李的成績:80 2288 請輸入英語王的成績:80 2289 請輸入英語趙的成績:80 2290 請輸入英語錢的成績:80 2291 張 李 王 趙 錢 2292 語文 60 60 60 60 60 2293 數學 70 70 70 70 70 2294 英語 80 80 80 80 80 2295 語文的總成績為:300 2296 數學的總成績為:350 2297 英語的總成績為:400 2298 張的總成績為:300 2299 李的總成績為:350 2300 王的總成績為:400 2301 趙的總成績為:60 2302 錢的總成績為:60 2303 2304 3.使用一個函數調換兩個數。 2305 #include <stdio.h> 2306 #include<stdlib.h> 2307 #include<time.h> 2308 void count(int i,int j); 2309 void count(int i,int j){ 2310 printf("交換之前的值:i=%d j=%d\n",i,j); 2311 int temp=0; 2312 temp=i; 2313 i=j; 2314 j=temp; 2315 printf("交換之後的值:i=%d j=%d\n",i,j); 2316 } 2317 2318 int main(int argc, const char * argv[]) { 2319 int a=0,b=0; 2320 srand((unsigned)time(0)); 2321 a=rand()%100; 2322 b=rand()%100; 2323 // printf("主函數交換之前的值:i=%d j=%d\n”,a,b);去掉 2324 count(a,b); 2325 //實參與形參不是一個內存空間(傳遞的只是值) 2326 // printf("主函數交換之後的值:i=%d j=%d\n”,a,b);去掉 2327 return 0; 2328 } 2329 結果: 2330 主函數交換之前的值:i=66 j=41 2331 交換之前的值:i=66 j=41 2332 交換之後的值:i=41 j=66 2333 主函數交換之後的值:i=66 j=41 2334 2335 4.求兩個數的最大值? 2336 5.求兩個數的最小值? 2337 #include <stdio.h> 2338 #include<stdlib.h> 2339 #include<time.h> 2340 void count(int i,int j); 2341 void count(int i,int j){ 2342 int min=0,max=0; 2343 max=i;min=i; 2344 if (i<j) { 2345 max=j; 2346 } 2347 if (i>j) { 2348 min=j; 2349 } 2350 printf("max:%d,min:%d\n",max,min); 2351 2352 } 2353 2354 int main(int argc, const char * argv[]) { 2355 int a=0,b=0; 2356 srand((unsigned)time(0)); 2357 a=rand()%100; 2358 b=rand()%100; 2359 count(a,b); 2360 結果: 2361 max:54,min:17 2362 2363 6.輸入分數求級別,輸入級別求分數?重構輸入10個學生信息,得到相應結果。 2364 #include <stdio.h> 2365 #include<stdlib.h> 2366 #include<time.h> 2367 //void a(int i); 2368 //void b(char j); 2369 //void xingming(int k); 2370 2371 void a(int i){ 2372 i=i/10; 2373 switch (i) { //輸入分數求級別0~60D 60~70C 70~90B 90~100A 2374 case 6: 2375 printf("C\n"); 2376 break; 2377 case 7: 2378 case 8: 2379 printf("B\n"); 2380 break; 2381 case 9: 2382 case 10: 2383 printf("A\n"); 2384 break; 2385 2386 default:printf("D\n"); 2387 break; 2388 } 2389 } 2390 2391 void b(char j){ 2392 switch(j){ 2393 case 'A': 2394 case 'a':printf("90~100\n");break; 2395 case 'B': 2396 case 'b':printf("70~90\n");break; 2397 case 'C': 2398 case 'c':printf("60~70\n");break; 2399 default:printf("60\n"); break; 2400 } 2401 2402 2403 } 2404 2405 2406 void xingming(int k){ 2407 switch (k) { 2408 case 0: 2409 printf("張"); 2410 break; 2411 case 1: 2412 printf("李"); 2413 break; 2414 case 2: 2415 printf("王"); 2416 break; 2417 case 3: 2418 printf("趙"); 2419 break; 2420 case 4: 2421 printf("錢"); 2422 break; 2423 } 2424 2425 } 2426 2427 int main(int argc, const char * argv[]) { 2428 2429 2430 for (int i=0; i<5; i++) {//輸入5個人的信息 2431 int fenshu; 2432 printf("請輸入"); 2433 xingming(i); 2434 printf("的分數:"); 2435 scanf("%d",&fenshu); 2436 printf("對應的等級是:");a(fenshu); 2437 } 2438 scanf("%*c");//緩存 2439 for (int i=0; i<5; i++) {//輸入5個人的信息 2440 char dengji; 2441 printf("請輸入"); 2442 xingming(i); 2443 printf("的等級:"); 2444 scanf("%c",&dengji); 2445 2446 printf("對應的范圍是:");b(dengji); 2447 } 2448 2449 return 0; 2450 } 2451 結果: 2452 請輸入張的分數:60 2453 對應的等級是:C 2454 請輸入李的分數:50 2455 對應的等級是:D 2456 請輸入王的分數:90 2457 對應的等級是:A 2458 請輸入趙的分數:80 2459 對應的等級是:B 2460 請輸入錢的分數:70 2461 對應的等級是:B 2462 請輸入張的等級:a 2463 對應的范圍是:90~100 2464 請輸入李的等級:對應的范圍是:60 2465 請輸入王的等級:D 2466 對應的范圍是:60 2467 請輸入趙的等級:對應的范圍是:60 2468 請輸入錢的等級:C 2469 對應的范圍是:60~70 2470 2471 4.return與exit關鍵字 2472 2473 return: 2474 2475 1.有返回值類型,必須有return關鍵字 2476 2.沒有返回值類型,也可以使用return關鍵字 2477 3.當函數的執行過程中,如果碰到return關鍵字,會終止函數的繼續執行 2478 2479 #include <stdio.h> 2480 void fun(); 2481 void fun(){ 2482 //有返回值類型,必須有return關鍵字 2483 //沒有返回值類型,也可以使用return關鍵字 2484 return ;//當函數的執行過程中,如果碰到return關鍵字,會終止函數的繼續執行 2485 printf("函數結尾"); 2486 } 2487 int main(int argc, const char * argv[]) { 2488 fun(); 2489 printf("程序結尾\n"); 2490 結果: 2491 程序結尾 2492 2493 exit:(#include <stdlib.h>) 2494 1.終止程序的繼續執行 2495 #include <stdio.h> 2496 #include <stdlib.h> 2497 void func(); 2498 void func(){ 2499 printf("2.func函數開始執行了\n"); 2500 //1.有返回值類型 必須有return關鍵字 2501 //2.沒有返回值類型 也可以使用return關鍵字 2502 //return ; 2503 exit(0);//終止程序的繼續執行 2504 //當函數的執行過程中 如果碰到return關鍵字,會終止函數的繼續執行 2505 printf("函數末尾!\n"); 2506 } 2507 int main(int argc, const char * argv[]) 2508 { 2509 printf("1程序開始!\n"); 2510 func(); 2511 printf("3.程序末尾!\n"); 2512 return 0; 2513 } 2514 結果: 2515 1程序開始! 2516 2.func函數開始執行了 2517 2518 練習: 2519 輸出一組數的和、最大值、最小 值 2520 在主函數中創建一個長度為10的數組,數組內放置10 個0~99之間(包含0,包含99)的隨機數作為數組內容。 按要求分別編制自定義函數求數組中的最大值、最小值並 計算出所有數組元素的和。 在主函數中將各自定義函數的返回值打印顯示在界面上。 2521 #include <stdio.h> 2522 #include <time.h> 2523 #include <stdlib.h> 2524 //得到一個隨機數 0~99 2525 int getRandom(); 2526 int getRandom(){ 2527 return rand()%100; 2528 } 2529 //得到一組數中的最大值 2530 int getArrayMax(int length,int array[]); 2531 int getArrayMax(int length,int array[]){ 2532 int max = 0; 2533 for (int i= 0; i<length; i++) { 2534 if(array[i]>max){ 2535 max = array[i]; 2536 } 2537 } 2538 return max; 2539 } 2540 //得到一組數中的最小值 2541 int getArrayMin(int length,int array[]); 2542 int getArrayMin(int length,int array[]){ 2543 int min = 99; 2544 for (int i= 0; i<length; i++) { 2545 if(array[i]<min){ 2546 min = array[i]; 2547 } 2548 } 2549 return min; 2550 } 2551 //得到一組數的和 2552 int getArraySum(int length,int array[]); 2553 int getArraySum(int length,int array[]){ 2554 int sum = 0; 2555 for (int i=0; i<length; i++) { 2556 sum+=array[i]; 2557 } 2558 return sum; 2559 } 2560 //得到數組所有的內容 2561 void outputArrayValue(int length,int array[]); 2562 void outputArrayValue(int length,int array[]){ 2563 for (int i = 0; i<length; i++) { 2564 printf("array[%d]:%d\n",i,array[i]); 2565 } 2566 } 2567 int main(int argc, const char * argv[]) 2568 { 2569 int array[10] = {0}; 2570 //生成隨機數 2571 srand((unsigned)time(0)); 2572 for (int i=0; i<10; i++) { 2573 array[i] = getRandom(); 2574 } 2575 //得到最大值 2576 int max = getArrayMax(10, array); 2577 //得到最小值 2578 int min = getArrayMin(10, array); 2579 //得到和 2580 int sum = getArraySum(10, array); 2581 printf("max:%d min:%d sum:%d\n",max,min,sum); 2582 //顯示數組中的所有內容 2583 outputArrayValue(10, array); 2584 2585 return 0; 2586 } 2587 結果: 2588 max:78 min:10 sum:504 2589 array[0]:18 2590 array[1]:30 2591 array[2]:46 2592 array[3]:75 2593 array[4]:78 2594 array[5]:52 2595 array[6]:50 2596 array[7]:10 2597 array[8]:76 2598 array[9]:69 2599 2600 2601 5.遞歸函數 2602 函數中調用函數就叫做遞歸。(一不小心死循環) 2603 1.遞歸工作原理: 2604 1.必須有退出條件 2605 2.必須保證遞歸後。算法簡化 2606 #include <stdio.h> 2607 int func(int num); 2608 int func(int num){ 2609 printf("num:%d\n",num); 2610 if (num==1) { 2611 return 1;//終止條件 2612 } 2613 return num*func(num-1);//保證遞歸後算法簡化 復制一個繼續執行然後返回值 2614 }//函數中調用函數 遞歸 一不小心死循環 2615 //程序的編譯順序是自上下向的 2616 //程序的運行順序main函數的調用順序 2617 int main(int argc, const char * argv[]) { 2618 int num1= func(3);3的階乘,是幾的階乘就寫幾 2619 printf("num1=%d\n",num1); 2620 return 0; 2621 } 2622 結果: 2623 num:3 2624 num:2 2625 num:1 2626 num1=6(6相當於3的階乘3!=3*2*1) 2627 2628 知識點 2629 十六、變量的作用域 2630 一、變量的作用域 (變量的使用范圍) 2631 1.不同級的代碼塊是可以重名的 2632 2.i取值是就近原則 2633 3.在上一級代碼中聲明的變量,是可以在下一級代碼中使用 2634 4.在下一級代碼中聲明的變量,是不可以在上一級代碼中使用 2635 5.聲明在大括號外面的變量叫全局變量(整個程序中都可以用) 2636 6.聲明在大括號裡面的變量叫局部變量(只能在大括號的內部使用) 2637 7.參數是個特殊的局部變量,作用域范圍,是函數的內部 2638 8.for 循環的表達式1也是個特殊的局部變量,作用域的范圍只能在for 循環體內部使用 2639 #include <stdio.h> 2640 2641 int main(int argc, const char * argv[]) { 2642 //變量i 作用域 2643 int i=10;上一級代碼塊 全局變量 2644 { 2645 //代碼塊 2646 int i=20;//不同級的代碼塊是可以重名的 下一級代碼塊 局部變量 2647 //i取值是就近原則 2648 printf("i1:%d\n",i); 2649 } 2650 printf("i2:%d\n",i); 2651 return 0; 2652 } 2653 結果: 2654 i1:20 2655 i2:10 2656 2657 二、變量的生命周期(局部變量)在內存中存在的情況 2658 1.自動變量auto 2659 auto關鍵字 是沒有動態變量一說的 不可使用 2660 2.靜態變量static 2661 static在聲明的開始,當程序結束時後結束 2662 2663 #include <stdio.h> 2664 void func2(){ 2665 //自動變量 默認值就是auto 2666 auto int i=10;//生 創建內存空間 auto可以省略 2667 //靜態變量 2668 static int i2=20;//生 死:當程序結束的時候 2669 i++; 2670 i2++; 2671 printf("i:%d\n",i); 2672 printf("i2:%d\n",i2); 2673 }//出了作用域 死 回收內存空間 2674 2675 int main(int argc, const char * argv[]) { 2676 func2(); 2677 func2(); 2678 2679 2680 return 0; 2681 } 2682 結果: 2683 i:11 2684 i2:21 2685 i:11 2686 i2:22 2687 二、變量的生命周期(全局變量) 2688 全局變量的作用域在整個程序的內部,多個函數可以共享這個全局變量 2689 全局變量的生命周期: 2690 程序開始的時候——生 2691 程序結束的時候——死 2692 2693 三、全局變量中的static和auto 2694 2695 1.auto關鍵字 是沒有動態變量一說的 不可使用 2696 2.static關鍵字 和生命周期沒有關系,在多文件開發中,如果要區分全局變量在不同文件中的訪問范圍,需要使用static關鍵字修飾 2697 2698 四、棧操作 2699 先進後出,後進先出 2700 練習:使用程序來模擬放球、取球的問題 2701 用數字來代表球,向棧中放入一個數字1代表放入了1 號球,向棧中放入一個數字2代表放入了2號球,依次類推。 同樣,從棧中取出數字1代表取出了1號球。 2702 #include <stdio.h> 2703 //網兜 2704 int balls[3]={0}; 2705 //網兜狀態標識 2706 int ballIndex = -1;//網兜空的時候為-1 2707 2708 //判斷有沒有滿 1.滿 0.未滿 2709 int isFull(){ 2710 if (ballIndex==2) { 2711 return 1; 2712 }else{ 2713 return 0; 2714 } 2715 } 2716 2717 //存球 2718 void push(int ball); 2719 void push(int ball){ 2720 //判斷有沒有滿 2721 if (!isFull()) {//沒滿 存 2722 ballIndex++; 2723 balls[ballIndex]=ball; 2724 }else{ //滿 不存 2725 printf("網兜已經滿了,不能存值!\n"); 2726 } 2727 } 2728 2729 //網兜是否為空 1空 0非空 2730 int isEmpty(); 2731 int isEmpty(){ 2732 if (ballIndex==-1) { 2733 return 1;//為空 2734 }else{ 2735 return 0;//非空 2736 } 2737 } 2738 2739 //取球 2740 int pop(); 2741 int pop(){ 2742 //網兜是否為空 2743 if (!isEmpty()) {//非空 取 2744 int temp = balls[ballIndex]; 2745 balls[ballIndex] = 0;//還要將原來位置的值清零 2746 ballIndex--; 2747 return temp; 2748 }else{//空 不能取 2749 printf("網兜為空,不能取球!\n"); 2750 return 0; 2751 } 2752 } 2753 2754 //查看網兜狀態 2755 void showBalls(); 2756 void showBalls(){ 2757 printf("===================\n"); 2758 for (int i=2; i>=0; i--) { 2759 printf("balls[%d]:%d\n",i,balls[i]); 2760 } 2761 printf("===================\n"); 2762 } 2763 2764 int main(int argc, const char * argv[]) 2765 { 2766 showBalls(); 2767 push(1); 2768 showBalls(); 2769 push(1); 2770 showBalls(); 2771 push(2); 2772 showBalls(); 2773 push(3); 2774 showBalls(); 2775 int ball = pop(); 2776 printf("取走了一個球:%d\n",ball); 2777 showBalls(); 2778 ball = pop(); 2779 printf("取走了一個球:%d\n",ball); 2780 showBalls(); 2781 ball = pop(); 2782 printf("取走了一個球:%d\n",ball); 2783 showBalls(); 2784 ball = pop(); 2785 printf("取走了一個球:%d\n",ball); 2786 showBalls(); 2787 return 0; 2788 } 2789 結果: 2790 =================== 2791 balls[2]:0 2792 balls[1]:0 2793 balls[0]:0 2794 =================== 2795 =================== 2796 balls[2]:0 2797 balls[1]:0 2798 balls[0]:1 2799 =================== 2800 =================== 2801 balls[2]:0 2802 balls[1]:1 2803 balls[0]:1 2804 =================== 2805 =================== 2806 balls[2]:2 2807 balls[1]:1 2808 balls[0]:1 2809 =================== 2810 網兜已經滿了,不能存值! 2811 =================== 2812 balls[2]:2 2813 balls[1]:1 2814 balls[0]:1 2815 =================== 2816 取走了一個球:2 2817 =================== 2818 balls[2]:0 2819 balls[1]:1 2820 balls[0]:1 2821 =================== 2822 取走了一個球:1 2823 =================== 2824 balls[2]:0 2825 balls[1]:0 2826 balls[0]:1 2827 =================== 2828 取走了一個球:1 2829 =================== 2830 balls[2]:0 2831 balls[1]:0 2832 balls[0]:0 2833 =================== 2834 網兜為空,不能取球! 2835 取走了一個球:0 2836 =================== 2837 balls[2]:0 2838 balls[1]:0 2839 balls[0]:0 2840 =================== 2841 2842 知識點 2843 十七、指針 2844 1.什麼是指針 2845 內存被分為字節,每個字節有唯一的地址,指針指的就是內 存地址 2846 2.指針變量 2847 保存指針的變量,就叫指針變量。(保存地址) 2848 int i;//int類型變量 2849 i=10; 2850 int* p;//*指針類型變量 2851 p=&i; 2852 printf("p->:%d\n",*p); 2853 結果: 2854 p->:10 2855 2856 3.每個指針變量能指向一種特定類型的對象(地址,內存區 域) 2857 2858 4.指針是引用數據類型,因為本身沒有保存數據,只是保存了 數據的地 址,間接的找到內存中的數據 2859 2860 *5.得到一個指針,可以得到兩個值 2861 1.直接得到數據在內存的地址 指針的值 地址 2862 2.間接得到內存中保存的數據 指針指向(值) 2863 int i;//int類型變量 2864 i=30; 2865 int* p;//*指針類型變量 2866 p = &i;//得到變量在內存中位置 (指針的值)一塊內存地址 2867 printf("p:%p\n",p); 2868 2869 //通過尋址運算符 根據地址直接操作內存 2870 //取 2871 printf("內存中的數據:%d\n",*p); 2872 //存 2873 *p = 40; 指針指向的內存區域 2874 printf("i:%d\n",i); 2875 2876 2877 結果: 2878 p:0x7fff5fbff70c 2879 內存中的數據:30 2880 i:40 2881 2882 6.指針可以作為參數(形參) 2883 2884 定義函數時,可以使指針類型作為參數,多個變量共用一個內存空間 2885 2886 練習 交換兩個值的地址 2887 2888 #include <stdio.h> 2889 //共用一塊內存區域 2890 void change(int* p1,int* p2); 2891 void change(int* p1,int* p2){ 2892 printf("change1 i:%d j:%d\n",*p1,*p2); 2893 int temp = *p1; 2894 *p1 = *p2; 2895 *p2 = temp; 2896 printf("change2 i:%d j:%d\n",*p1,*p2); 2897 } 2898 2899 int main(int argc, const char * argv[]) 2900 { 2901 int i = 10; 2902 int j = 20; 2903 printf("main1 i:%d j:%d\n",i,j); 2904 change(&i, &j); 2905 printf("main2 i:%d j:%d\n",i,j); 2906 return 0; 2907 } 2908 結果: 2909 main1 i:10 j:20 2910 change1 i:10 j:20 2911 change2 i:20 j:10 2912 main2 i:20 j:10 2913 2914 求一組數的最大值、最小值 2915 在主函數中創建一個長度為10的數組,數組內放置10 個0~99之間(包含0,包含99)的隨機數作為數組內容, 按要求編制一個自定義函數同時返回數組中的最大值、最 小值,然後在主函數中將自定義函數的返回值打印顯示在 界面上。 2916 #include <stdio.h> 2917 #include<stdlib.h> 2918 #include<time.h> 2919 int num(); 2920 int num(){ 2921 return rand()%100; 2922 } 2923 2924 void func(int length,int a[],int* maxp,int* minp); 2925 void func(int length,int a[],int* maxp,int* minp){ 2926 for (int i=0; i<length; i++) { 2927 if (a[i]>*maxp) { 2928 *maxp=a[i]; 2929 } 2930 if (a[i]<*minp) { 2931 *minp=a[i]; 2932 } 2933 } 2934 } 2935 int main(int argc, const char * argv[]) { 2936 int max=0,min=99; 2937 int a[10]={0}; 2938 //使用隨機數生成10個數 2939 srand((unsigned)time(0)); 2940 for (int i=0; i<10; i++) { 2941 a[i]=num(); 2942 printf("a[%d]=%d\n",i,a[i]); 2943 } 2944 //求一組數的最大值和最小值 2945 func(10,a, &max,&min); 2946 printf("max:%d min:%d\n",max,min); 2947 2948 return 0; 2949 } 2950 結果: 2951 a[0]=72 2952 a[1]=11 2953 a[2]=16 2954 a[3]=38 2955 a[4]=52 2956 a[5]=78 2957 a[6]=20 2958 a[7]=92 2959 a[8]=42 2960 a[9]=53 2961 max:92 min:11 2962 2963 7.指針可以作為返回值 2964 2965 定義函數的時候,可以使用指針類型作為返回值,可以共享函數中的內存空間。注意:函數中的變量不能是自動變量,自動變量一旦超出作用域就銷毀了,如果想使用,必須延長變量的生命周期,使它變成靜態變量。 2966 2967 2968 #include <stdio.h> 2969 //2.使用全局變量 2970 //int i=30; 2971 int* func(); 2972 int* func(){//指針作為參數,共享函數中的內存空間 2973 static int i=10;//1.延長變量生命周期 (只有第一次執行,第二次調用便使用i++) 2974 i++; 2975 printf("i:%d\n",i); 2976 return &i; 2977 } 2978 int main(int argc, const char * argv[]) { 2979 int* ip; 2980 ip=func(); 2981 *ip=20; 2982 func(); 2983 2984 return 0; 2985 } 2986 結果: 2987 i:11 2988 i:21 2989 2990 8.指針的加減操作 2991 指針支持加整數、減整數、指針的比較和相減,但運算的單位 由指針的類型決定。 2992 指針變量+1 相當於移動了一個數據位 2993 int類型指針+1 = 地址+4 2994 char類型指針+1 =地址+1 2995 1.int 類型的指針加減 2996 2997 #include <stdio.h> 2998 2999 int main(int argc, const char * argv[]) { 3000 int a[3]={1,2,3}; 3001 int* p=a;//等於int* p=&a[0]; 3002 printf("*p:%d %p\n",*p,p); 3003 printf("*(p+1):%d %p\n",*(p+1),p+1); 3004 printf("*(p+2):%d %p \n",*(p+2),p+2); 3005 return 0; 3006 } 3007 結果: 3008 *p:1 0x7fff5fbff77c 3009 *(p+1):2 0x7fff5fbff780 3010 *(p+2):3 0x7fff5fbff784 3011 3012 2.char類型的指針加減 3013 3014 #include <stdio.h> 3015 3016 int main(int argc, const char * argv[]) { 3017 char a[3]={'a','b','c'}; 3018 char* p=a;//等於int* p=&a[0]; 3019 printf("*p:%c %p\n",*p,p); 3020 printf("*(p+1):%c %p\n",*(p+1),p+1); 3021 printf("*(p+2):%c %p \n",*(p+2),p+2); 3022 return 0; 3023 } 3024 結果: 3025 *p:a 0x7fff5fbff77d 3026 *(p+1):b 0x7fff5fbff77e 3027 *(p+2):c 0x7fff5fbff77f 3028 3029 3.通過for循環 根據地址取值 3030 3031 #include <stdio.h> 3032 3033 int main(int argc, const char * argv[]) { 3034 int a[3]={1,5,2}; 3035 int* p=a;//等於int* p=&a[0]; 3036 3037 //通過for循環 根據地址取值 3038 for (int i=0; i<3; i++) { 3039 //*(p+i)與(*p)+1結果是不同的 3040 printf("*(p+i):%d\n",*(p+i));正確的輸出 3041 printf("*(p)+i:%d\n",(*p)+i); 3042 } 3043 結果: 3044 *(p+i):1 3045 *(p)+i:1 3046 *(p+i):5 3047 *(p)+i:2 3048 *(p+i):2 3049 *(p)+i:3 3050 3051 3052 9.二級指針 3053 int i=10; 3054 int* ip=&i;//指針 3055 int** ip2=&ip;//二級指針 3056 int*** ip3=&ip2;//三級指針 3057 printf("ip3:%d\n",***ip3); 3058 結果: 3059 ip3:10 3060 3061 10.指針與數組 3062 3063 共同點:兩者都可以表示地址 3064 3065 不同點: 3066 一、所占內存空間不同 3067 1. 和具體內存中,所保存的數據無關 3068 2.所有內存的地址所占內存空間都是一樣大的 3069 3.指針地址所占內存空間在macos64位系統下, 地址所占8字節 3070 4.數組所占的內存空間=元素所占的內存空間*元素的長度(個數) 3071 例題: 3072 int i = 10; 3073 char ch = 'a'; 3074 int* p1 = &i; 3075 char* p2 = &ch; 3076 //所占內存空間 3077 //和具體內存中,所保存的數據是無關 3078 //所有內存的地址所占內存空間都是一樣大的 3079 //macos64位 地址所占8B 3080 printf("p1 size:%ld\n",sizeof(p1)); 3081 printf("p2 size:%ld\n",sizeof(p2)); 3082 3083 //數組所占的內存空間=元素所占內存空間*元素個數 3084 int array[5]; 3085 int* p = array; 3086 printf("p size:%ld %p\n",sizeof(p),p); 3087 printf("array size:%ld *%p\n",sizeof(array),array); 3088 3089 結果: 3090 p1 size:8 3091 p2 size:8 3092 p size:8 0x7fff5fbff790 3093 3094 二、賦值 3095 1.指針變量的值是可以改變的 3096 2.數組一但聲明,其值是不可以改變的,而是保存數據在內存中的地址,在使 用的時候通過地址間接得到數據的值。 3097 3098 例題: 3099 int array[5]; 3100 int* p = array; 3101 printf("p size:%ld %p\n",sizeof(p),p); 3102 printf("array size:%ld *%p\n",sizeof(array),array); 3103 //賦值 3104 int i2 = 10; 3105 int j2 = 20; 3106 int* p3 = &i2; 3107 p3 = &j2;//指針變量的值是可以改變的 賦值 3108 3109 int array2[5]; 3110 int array3[10]; 3111 //array2 = array3;錯誤的表示//是不可以改變數組變量的值的 3112 結果: 3113 array size:20 *0x7fff5fbff790 3114 3115 11、引用———c語言中數據類型主要分為兩大類 3116 3117 基本數據類型:int char double float 3118 變量本身就保存了我們需要的數據 3119 引用數據類型:指針 3120 變量本身並沒有保存數據 3121 3122 數據->(Create創建Read讀取Update更新Delete刪除) 3123 3124 12.進程空間 3125 3126 •進程是正在運行的程序,在內存中。 • 每個進程在內存中占據的空間稱進程空間 3127 1.進程空間的內存分配 3128 1.代碼區(正文段, text) 只讀 程序代碼 3129 2.全局區(全局靜態區) 讀、寫 全局變量、靜態變量 3130 3.堆區(自由區, heap) 讀、寫 3131 4.棧區(堆棧, stack) 讀、寫 動態變量(局部變量) 3132 知識點 3133 十八、字符串 3134 1.三種字符串的創建: 3135 一、字面值字符串 3136 1.在代碼區創建了一個字符串 會在結尾自動加\0 (只讀) 3137 2.字符串有自己的占位符%s 3138 3.字符串使用,會從首地址一個字節一個字節的讀取數據,直到讀到\0位 置表示結束 3139 //在代碼區創建了一個字符串 會在結尾自動加\0 3140 char* p= "string1";//可以與指針變量結合使用 3141 printf("string2\n");//直接與輸出函數使用 3142 //字符串有自己的占位符%s 3143 printf("%s\n",p); 3144 char* p2= "string1"; 3145 //如果字符串的內容相同,代碼區只會創建一個字符串 3146 printf("p:%p,p2:%p\n",p,p2);//地址 3147 //字符串使用,會從首地址一個字節一個字節的讀取數據,直到讀到\0位置 表示結束 3148 char* p3="str\0ing1\n"; 3149 printf("p3:%s\n",p3); 3150 結果: 3151 string2 3152 string1 3153 p:0x100000f6e,p2:0x100000f6e 3154 p3:str 3155 4.證明 代碼區 只讀 3156 char* p3="str\0ing1\n"; 3157 printf("p3:%s\n",p3); 3158 char* cp=p3; 3159 printf("cp+1:%c\n",*(cp+1)); //讀 3160 //*(cp+1)='w';//如果非要改 程序就異常 //寫 3161 結果: 3162 p3:str 3163 cp+1:t 3164 3165 二、字符數組的字符串 3166 1.保存在內存中棧區 內容就算相同,也會開辟不同的內存空間 3167 2.字符數組的字符串與普通的字符數組最大的區別是否有 結束符\0 3168 3.棧區 讀寫.... 3169 char str[4]={'s','t','r','\0'}; 3170 char str2[4]={'s','t','r','\0'}; 3171 char* cp = str2; 3172 *(cp+1) = 'w';//可以改變棧區的數據 3173 printf("str address:%p value:%s\n",str,str); 3174 printf("str2 address:%p value:%s\n",str2,str2); 3175 結果: 3176 str address:0x7fff5fbff7a4 value:str 3177 str2 address:0x7fff5fbff7a0 value:swr 3178 3179 三、字符指針 3180 3181 對於字符串來講引用類型: 3182 3183 1.字符指針即可以與字面值字符串結合使用 3184 2.也可以與字符數組的字符串結合使用 3185 3186 練習:通過鍵盤輸入一個字符串 3187 //char* input="*********";通過字面值定義字符串不可取 3188 char input[10]; 3189 char* inputp=input; 3190 printf("請輸入一個字符串信息:\n"); 3191 scanf("%s",input); 3192 printf("str:%s\n",inputp); 3193 結果: 3194 請輸入一個字符串信息: 3195 hello 3196 str:hello 3197 3198 三種字符串創建的比較 3199 內存 內容相同 讀寫 結束符 3200 a.字面值 代碼區 只會創建一個 只讀 自動 3201 b.字符數組 棧區 會創建多個 讀寫 手動 3202 c.字符指針 保存地址(棧) 無關 無關 無關 3203 3204 2.字符串函數庫 3205 3206 #include <string.h> 3207 3208 幫我們解決常用字符串的問題 3209 a.字符串的賦值strcpy(參數1,參數2) 3210 參數1:目標字符串位置(復制到哪裡) 3211 參數2:源字符串位置(字符串的來源) 3212 *注: 3213 char* str="helloworld\n"; 3214 char str2[15]; 3215 //復制一個字符串 3216 strcpy(str2, str); 3217 printf("str2:%s\n",str2); 3218 結果: 3219 str2:helloworld 3220 3221 b.字符串的拼接strcat(參數1,參數2) 3222 1. 將第一個字符串的內容與第二個字符串的內容拼接在一起,保存在第一個 字符串中。 3223 *注:參數1的空間>=兩個字符串內容之和 3224 char str3[10]={'h','e','l','\0'}; 3225 char*str4="wor\n"; 3226 strcat(str3, str4); 3227 printf("str3:%s\n",str3); 3228 結果: 3229 str3:helwor 3230 3231 c.字符串的長度 (返回值長度)strlen(參數) 3232 練習:求字符串的長度,不包含結束符 3233 1. char* str5 = "helloworld!\n"; 3234 unsigned long length = strlen(str5); 3235 printf("length:%lu\n",length); 3236 結果: 3237 length:12 3238 2. char str5[10] = {‘h’,’e’,’l’,’\0’};// ‘\0’不占內存空間 3239 unsigned long length = strlen(str5); 3240 printf("length:%lu\n",length); 3241 結果:length:3 3242 3243 3244 d.字符串的比較 3245 比較兩個字符串的內容strcmp(參數1,參數2) 3246 1. 字符串的比較不可以使用==號,==通常比較的是兩個數的值,字符串是引用數據類型,比較的是兩個字符串的地址,與使用場景不符 3247 2.標准做法:比較兩個字符串中每一個字符的ASC碼值,全都相同,兩個字符串是相同的。 3248 *注:結果得到的是兩個字符串中ASC碼的差值,若差值為0,則兩個字符串相等。 3249 char *str6 = "Heflo"; 3250 char *str7 = "HEllo"; 3251 int i = strcmp(str6, str7); 3252 printf("i:%d\n",i);ASC碼的差值 3253 結果:i:32 3254 3255 練習:模擬登錄,三次輸入機會 3256 3257 //輸入內容 3258 char username[20],password[20]; 3259 //模擬數據庫中的數據 3260 char* d_username = "admin"; 3261 char* d_password = "123"; 3262 int count = 0; 3263 while (1) { 3264 count++; 3265 printf("請輸入用戶名:\n"); 3266 scanf("%s",username); 3267 printf("請輸入密碼:\n"); 3268 scanf("%s",password); 3269 //判斷登錄是否成功 3270 if (strcmp(username, d_username)==0 3271 && 3272 strcmp(password, d_password)==0 3273 ) { 3274 printf("登錄成功!\n"); 3275 break; 3276 }else{ 3277 printf("用戶名或密碼錯誤!\n"); 3278 if (count==3) { 3279 exit(0);//程序結束 3280 } 3281 } 3282 } 3283 printf("登錄成功後..."); 3284 結果: 3285 請輸入用戶名: 3286 fcp 3287 請輸入密碼: 3288 lbm 3289 用戶名或密碼錯誤! 3290 請輸入用戶名: 3291 admin 3292 請輸入密碼: 3293 123 3294 登錄成功! 3295 登錄成功後... 3296 3.字符串數組 3297 3298 兩種形式: 3299 1.字面值字符串數組 3300 字面值字符串數組中的字符串是不能改變的 3301 3302 //字面值字符串數組 3303 char* str = "zhangsan"; 3304 char* str2 = "lisi"; 3305 char* strs[2] = {str,str2}; 3306 printf("strs size:%lu\n",sizeof(strs)); 3307 //遍歷字符串數組 輸出strs[2] 3308 for (int i = 0; i<2; i++) { 3309 printf("strs[%d]:%s\n",i,strs[i]); 3310 } 3311 結果: 3312 strs size:16 3313 strs[0]:zhangsan 3314 strs[1]:lisi 3315 3316 2.數組字符串數組 3317 數組字符串數組中的字符串是可以改變的 3318 //數組字符串的數組 3319 //char str3[10] = {'z','h','a','\0'}; 3320 //char str4[10] = {'l','i','s','\0'}; 3321 char strs2[2][10]={{'z','h','a','\0'},{'l','i','s','\0'}}; 3322 printf("strs2 size:%lu\n",sizeof(strs2)); 3323 for (int i=0; i<2; i++) { 3324 printf("strs2[%d]:%s\n",i,&strs2[i][0]); 3325 } 3326 結果: 3327 strs2 size:20 3328 strs2[0]:zha 3329 strs2[1]:lis 3330 3331 作業 3332 a.所有功能在使用前一定要登錄 3333 b.先注冊才能登錄 3334 c.存錢存到帳號中(只有一個帳號) 3335 d.取錢,取帳號中的錢(減),不足,取錢失敗提示。 3336 e.查看余額 3337 f.0退出程序 如果不退出系統,循環執行。 3338 /==============/ 3339 系統功能 3340 1.注冊 3341 2.登錄 3342 3.存錢 3343 4.取錢 3344 5.查看余額 3345 0.退出 3346 /==============/ 3347 請輸入您要選擇的功能:_ 3348 3349 #include <stdio.h> 3350 #include <string.h> 3351 void registerUser(); 3352 int isLogin(); 3353 void save(); 3354 //登錄狀態的標識 3355 int flag = 0; 3356 3357 //保存用戶名/密碼 3358 char username[20]; 3359 char password[20]; 3360 //臨時保存用戶輸入的內容 3361 char inputUsername[20]; 3362 char inputPassword[20]; 3363 3364 void menu(){ 3365 printf("==================\n"); 3366 printf("系統功能\n"); 3367 printf("1.注冊\n"); 3368 printf("2.登錄\n"); 3369 printf("3.存錢\n"); 3370 printf("4.取錢\n"); 3371 printf("5.查看余額\n"); 3372 printf("0.退出\n"); 3373 printf("==================\n"); 3374 } 3375 3376 int inputNum(){ 3377 int num = 0; 3378 printf("請輸入您需要的功能(0~5):\n"); 3379 scanf("%d",&num); 3380 return num; 3381 } 3382 3383 void select(int num){ 3384 switch (num) { 3385 case 1: 3386 printf("進入注冊功能\n"); 3387 registerUser(); 3388 break; 3389 case 2: 3390 printf("進入登錄功能\n"); 3391 flag = isLogin(); 3392 break; 3393 case 3: 3394 printf("進入存錢功能\n"); 3395 save(); 3396 break; 3397 default: 3398 printf("您輸入的數據有誤,請重新輸入\n"); 3399 break; 3400 } 3401 } 3402 //向銀行存錢 3403 void save(){ 3404 //判斷登錄狀態 登錄成功才可以存錢,未登錄不能存錢 3405 if (flag) { 3406 printf("開始存錢!...\n"); 3407 }else{ 3408 printf("未登錄,請先登錄!\n"); 3409 } 3410 } 3411 3412 //注冊一個用戶 3413 void registerUser(){ 3414 printf("注冊一個用戶:\n"); 3415 printf("輸入一個用戶名:\n"); 3416 scanf("%s",username); 3417 printf("輸入一個密碼:\n"); 3418 scanf("%s",password); 3419 printf("注冊成功!\n"); 3420 } 3421 3422 //登錄功能 3423 int isLogin(){ 3424 printf("登錄功能!\n"); 3425 printf("輸入一個用戶名:\n"); 3426 scanf("%s",inputUsername); 3427 printf("輸入一個密碼:\n"); 3428 scanf("%s",inputPassword); 3429 //和數據庫進行匹配 3430 if (strcmp(inputUsername, username)==0 3431 && 3432 strcmp(inputPassword, password)==0) { 3433 printf("登錄成功!\n"); 3434 return 1; 3435 }else{ 3436 printf("用戶名或密碼錯誤!\n"); 3437 return 0; 3438 } 3439 } 3440 3441 int main(int argc, const char * argv[]) 3442 { 3443 //(高內聚 低耦合)->程序更靈活 3444 while (1) { 3445 //1.顯示菜單 3446 menu(); 3447 //2.輸入選擇的選項 3448 int num = inputNum(); 3449 //3.輸入不同的值,選擇相應的功能 3450 select(num); 3451 } 3452 return 0; 3453 } 3454 結果: 3455 ================== 3456 系統功能 3457 1.注冊 3458 2.登錄 3459 3.存錢 3460 4.取錢 3461 5.查看余額 3462 0.退出 3463 ================== 3464 請輸入您需要的功能(0~5): 3465 1 3466 進入注冊功能 3467 注冊一個用戶: 3468 輸入一個用戶名: 3469 fcp 3470 輸入一個密碼: 3471 lbm 3472 注冊成功! 3473 ================== 3474 系統功能 3475 1.注冊 3476 2.登錄 3477 3.存錢 3478 4.取錢 3479 5.查看余額 3480 0.退出 3481 ================== 3482 請輸入您需要的功能(0~5): 3483 3 3484 進入存錢功能 3485 未登錄,請先登錄! 3486 ================== 3487 系統功能 3488 1.注冊 3489 2.登錄 3490 3.存錢 3491 4.取錢 3492 5.查看余額 3493 0.退出 3494 ================== 3495 請輸入您需要的功能(0~5): 3496 2 3497 進入登錄功能 3498 登錄功能! 3499 輸入一個用戶名: 3500 fcp 3501 輸入一個密碼: 3502 lbm 3503 登錄成功! 3504 ================== 3505 系統功能 3506 1.注冊 3507 2.登錄 3508 3.存錢 3509 4.取錢 3510 5.查看余額 3511 0.退出 3512 ================== 3513 請輸入您需要的功能(0~5): 3514 3515 9.字符串數組 3516 有兩種形式,字面值字符串數組,數組字符串數組。 3517 字面值字符串數組中的字符串是不能改變的。 3518 數組字符串數組中的字符串是可以改變的。 3519 3520 作業: 3521 a.有五虎上將,zhangfei、guanyu、huangzhong、zhaoyun、machao。 3522 輸入一個人名,判斷是否是五虎上將? 3523 #include <stdio.h> 3524 #include <string.h> 3525 3526 int main(int argc, const char * argv[]) { 3527 char* tigger[5]={"zf","gy","hz","zhy","mc"}; 3528 char username[10]; 3529 printf("請輸入一個人名!\n"); 3530 scanf("%s",username); 3531 for (int i=0; i<5; i++) { 3532 if (strcmp(username,tigger[i])==0) { 3533 printf("%s是五虎上將",username); 3534 } 3535 } 3536 3537 return 0; 3538 } 3539 結果: 3540 請輸入一個人名! 3541 gy 3542 gy是五虎上將 3543 b.輸入三個人的姓名,並保存? 3544 char usernames[3][20]; 3545 //輸入三個人的姓名 3546 for (int i = 0; i<3; i++) { 3547 printf("請輸入第%d個人的名字:\n",i+1); 3548 scanf("%s",&usernames[i][0]); 3549 } 3550 //輸出三個人的姓名 3551 for (int i = 0; i<3; i++) { 3552 printf("第%d人的名字:%s\n",i+1,&usernames[i][0]); 3553 } 3554 結果: 3555 請輸入第1個人的名字: 3556 fcp 3557 請輸入第2個人的名字: 3558 lbm 3559 請輸入第3個人的名字: 3560 wjy 3561 第1人的名字:fcp 3562 第2人的名字:lbm 3563 第3人的名字:wjy 3564 3565 知識點 3566 十八、一些計算機操作指令 3567 3568 1.const關鍵字 3569 1.可以把一個變量,變成常量 3570 2. 由於指針變量相當於兩個值: 3571 指針的值 int* const p 3572 指針指向的值 const int* p 3573 3. 有些函數在使用內存地址是,希望內存中的數據是只讀的,不需修改,就會加上const關鍵字 3574 const int i=10;//將變量->常量 3575 //i=20; 3576 printf("i:%d\n",i); 3577 3578 int j=20; 3579 int k=30; 3580 int* p=&j; 3581 //指針的值 int* const p 3582 p=&k; 3583 //指針指向的值 const int* p 3584 *p=40; 3585 printf("k:%d",k); 3586 結果: 3587 i:10 3588 k:40 3589 3590 3591 2.命令行參數 3592 ./a.out 640*480->main()…… 3593 main(參數1:長度,參數2:值) 3594 數組中第一個內容是命令 … 3595 3.預處理指令 3596 3597 #預編譯指令 3598 在編譯之前做的事情: 3599 例:1.導入頭文件... 3600 2.條件編譯.... 3601 #ifndef ZBS 3602 沒有條件編譯此處 3603 #else 3604 有條件編譯此處 3605 #endif 3606 編譯:gcc main.c—DZBS 3607 ./a.out 3608 #ifdef SIZE //如果定義了SIZE宏條件成立 3609 #ifndef SIZE //如果沒定義SIZE宏條件成立 #if 1==1 //條件成立 #if 條件表達式或邏輯表達式 3610 #include <stdio.h> 3611 3612 int main(int argc, const char * argv[]) { 3613 int num=0; 3614 printf("輕點菜:"); 3615 scanf("%d",&num); 3616 #ifndef ZBS 3617 if (num==1) { 3618 printf("您點的是魚香肉絲\n"); 3619 }else if (num==2){ 3620 printf("您點的是地三鮮\n"); 3621 3622 }else { 3623 printf("沒有這個菜\n"); 3624 3625 } 3626 #else 3627 if (num==1) { 3628 printf("沒有這個菜\n"); 3629 }else if (num==2){ 3630 printf("沒有這個菜\n"); 3631 3632 }else { 3633 printf("真沒有這個菜\n"); 3634 3635 } 3636 #endif 3637 return 0; 3638 } 3639 結果:gcc main.c—DZBS就執行else的代碼 3640 3641 3.宏… (#define PI …) 3642 1.把復雜的操作變得更簡單 ,不會改變原代碼 3643 2.宏與變量最大的區別,不占內存空間,當編譯前會自動替換代碼中的變量 3644 3.宏的值一旦確定是不可改變的 3645 #include <stdio.h> 3646 //#預編譯指令 PI文本標識 3.1415926替換內容 3647 //宏與變量最大的區別,不占內存空間,當編譯前會自動替換代碼中的變量 3648 #define PI 3.1415926//PI宏的文本 3649 3650 int main(int argc, const char * argv[]) { 3651 //圓的面積=派*r*r; 3652 int r=0; 3653 printf("請輸入一個半徑:\n"); 3654 scanf("%d",&r); 3655 //printf("圓的面積為:%lf\n",3.1415926*r*r); 3656 printf("圓的面積為:%lf\n",PI*r*r); 3657 return 0; 3658 } 3659 結果: 3660 請輸入一個半徑: 3661 8 3662 圓的面積為:201.061926 3663 3664 4.宏可以和數組搭配使用 3665 #define SIZE 6 3666 int main(int argc, const char * argv[]) { 3667 3668 int a[SIZE]={0}; 3669 5.宏函數 3670 與內存空間沒有關系 跟類型與沒有關系 3671 #include <stdio.h> 3672 #define MUL(x,y)x*y 3673 int i=10; 3674 int j=20; 3675 printf("i:%d*j:%d=%d",i,j,i*j); 3676 printf("%d\n",MUL(i,j)); 3677 printf("%d\n",MUL(2+3,4+5));//2+3*4+5 3678 printf("%d\n",21/MUL(2+3,4+5));//21/2+3*4+5 3679 結果: 3680 i:10*j:20=200 3681 200 3682 19 3683 27 3684 3685 練習: 3686 1.輸入一個字母將小寫->大寫… 3687 2.條件編譯 3688 iphone4 3689 iphone5~5s 3690 iphone6 3691 iphone6plus 3692 ipad1~4 3693 ipad mini 3694 3695 知識點 3696 十九、大型軟件開發 3697 1.多文件編程 3698 當程序較大時,為了提高可讀性,一般將程序拆分成多個文 件,每個文件負責一個功能塊 3699 2.多文件編程的操作步驟 3700 多人開發 將原文件拆分成三個文件,分別為*.h、*.c、 main.c 3701 例:輸入一個數並輸出 3702 1.輸入功能拆分放到兩個文件中 3703 .h函數的聲明 3704 .c函數的定義 3705 2.使用前必須導入頭文件 3706 3.編譯的時候,必須連接 3707 系統的函數庫已經默認與程序連接到了一起 3708 連接:將多個文件的的目標文件合在一起,就是連接 3709 gcc -c input.c 目標文件->*.o 3710 如: gcc -c input.c轉成input.o 3711 gcc 目標文件1 目標文件2....->a.out 3712 如:gcc input.o main.o——>./a.out——-得到編譯結果 3713 ’ 總:1.只有.h 和.o別人可以使用你的函數了,但無法得到源代碼。閉源 3714 2 .h 和.c別人可以使用你的函數了,並且知道你是如何實現的。開源 3715 3.在多文件開發中 3716 .h文件中 ,主要放的是函數聲明、宏,但不能放變量的聲明,一切與內存有關的操作都不可以 3717 .c文件中,主要放程序源代碼,變量的聲明、函數的定義.. 3718 全局變量只能放在.c文件中 3719 **如果想使用其他文件中的全局變量必須使用extern關鍵字修飾。 3720 extern int array; 3721 **使用static修飾全局變量,該全局變量只能在當前文件中使用(私有) 3722 static不但可以修飾全局變量,還可以修飾函數 3723 4.批處理命令:make 3724 3725 知識點 3726 二十、結構體 3727 3728 • 結構體語法格式 3729 1.struct{ 3730 成員; 3731 }變量名; 3732 2.typedef struct { //常用格式 int age;//成員 3733 char name[20]; 3734 }Student2;//別名 3735 例: (標准定義) 3736 //給類型(定義)起名字 3737 typedef struct { 3738 int age;//成員 3739 char sex; 3740 }NewPerson2;//新名字 //變量名 3741 NewPerson2 person5 = {22,'F'}; 3742 //結構體如果聲明在函數的外部,所有函數都可以使用 3743 NewPerson2 person6 = {23,'M'}; 3744 printf("age5:%d sex5:%c\n",person5.age,person5.sex);//取值 3745 printf("age6:%d sex6:%c\n",person6.age,person6.sex);//取值 3746 結果: 3747 age5:22 sex5:F 3748 age6:23 sex6:M 3749 3750 3751 *結構體其他表示方法 3752 一、//數據結構 人的信息(年齡,性別) 3753 struct{ 3754 int age;//成員 3755 char sex; 3756 }person1,person2={19,'F'};//變量名 3757 person1.age = 18;//賦值 3758 person1.sex = 'M'; 3759 printf("age:%d sex:%c\n",person1.age,person1.sex);//取值 3760 printf("age2:%d sex2:%c\n",person2.age,person2.sex);//取值 3761 //int i 3762 //i = 10; 3763 //int i = 10; 3764 //給結構起個名字 struct Person == int 3765 二、 struct Person{ 3766 int age; 3767 char sex; 3768 }; 3769 3770 //struct Person person3 = {20,'M'}; 3771 struct Person person3; 3772 person3.age = 21; 3773 person3.sex = 'F'; 3774 printf("age3:%d sex3:%c\n",person3.age,person3.sex);//取值 3775 3776 三、 //給類型起名字 typedef 原來的名字 新名字 3777 typedef struct Person NewPerson; 3778 NewPerson person4 = {22,'M'}; 3779 printf("age4:%d sex4:%c\n",person4.age,person4.sex);//取值 3780 3781 結果: 3782 age:18 sex:M 3783 age2:19 sex2:F 3784 age3:21 sex3:F 3785 age4:22 sex4:M 3786 3787 2.結構體所占內存空 3788 3789 //結構體所占內存空 3790 typedef struct{ 3791 char ch;//1 3792 short i;//2 3793 } Stu; 3794 printf("Stu size:%ld\n",sizeof(Stu)); 3795 結果: 3796 Stu size:4 3797 3798 作業: 3799 練習:創建四個學生信息(學號、姓名、性別、年齡),所有的信息要使用鍵盤輸入並保存。 3800 typedef struct{ 3801 int num; 3802 char name[10];//保存字符串的內容 3803 //char *cp;//保存字符串的地址 3804 char sex; 3805 int age; 3806 } Student; 3807 Student stus[4]; 3808 for (int i = 0; i<4; i++) { 3809 printf("請輸入學號:\n"); 3810 scanf("%d",&stus[i].num); 3811 printf("請輸入姓名:\n"); 3812 scanf("%s",stus[i].name); 3813 scanf("%*c"); 3814 printf("請輸入性別:\n"); 3815 scanf("%c",&stus[i].sex); 3816 printf("請輸入年齡:\n"); 3817 scanf("%d",&stus[i].age); 3818 } 3819 3820 for (int i = 0; i<4; i++) { 3821 printf("學號:%d\n",stus[i].num); 3822 printf("姓名:%s\n",stus[i].name); 3823 printf("性別:%c\n",stus[i].sex); 3824 printf("年齡:%d\n",stus[i].age); 3825 } 3826 3827 知識點 3828 二十一、聯合、枚舉 3829 3830 一、聯合 3831 1. 聯合的用法、語法和結構非常相似,但聯合中所有成員分配 的內存是同一塊。(只能保存一個 成員信息,聯合的空間以 最大成員所占的空間為值) 3832 2. 聯合可以用一塊內存對應多種數據類型 3. 聯合與結構的區別,結構可以保存多個成員信息,而聯合只能保存一個成員信息且最後一個 3833 3834 #include <stdio.h> 3835 3836 typedef union{ //聯合語法格式 3837 int i; 3838 char ch; 3839 3840 }LianHe; 3841 3842 int main(int argc, const char * argv[]) 3843 { 3844 printf("LianHe:%ld\n",sizeof(LianHe)); 3845 LianHe lh; 3846 lh.i=10; 3847 printf("i:%d\n",lh.i); 3848 lh.ch='a'; 3849 printf("ch:%c\n",lh.ch); 3850 printf("i:%d\n",lh.i); 3851 3852 return 0; 3853 } 3854 結果: 3855 LianHe:4 3856 i:10 3857 ch:a 3858 i:97 3859 3860 二、枚舉 3861 3862 1.語法格式: 3863 //定義一個枚舉 3864 enum{MON,TUE,WEN}; 3865 或 3866 //typedef 類型名字 新名字 3867 typedef enum{ //常用類型 3868 MON,TUE,WEN 3869 }week; 3870 3871 2.在聲明的時候修改枚舉值 3872 //如果需要修改枚舉值 只能在聲明的時候修改 3873 //後面的元素=前面的元素+1 3874 1. typedef enum{ 3875 MON=1,TUE,WEN 3876 }week; 3877 結果: 3878 MON:1 3879 TUE:2 3880 WEN:3 3881 2. typedef enum{ 3882 MON,TUE=2,WEN 3883 }week; 3884 結果: 3885 MON:0 3886 TUE:2 3887 WEN:3 3888 3889 3.typedef enum{false,true} bool; 3890 bool b1 = false; 3891 printf("b1:%d\n",b1); 3892 結果:0 3893 3894 練習: 3895 #include <stdio.h> 3896 3897 //定義一個枚舉 3898 //enum{MON,TUE,WEN}; 3899 3900 //typedef 類型名字 新名字 3901 //如果需要修改枚舉值 只能在聲明的時候修改 3902 //後面的元素=前面的元素+1 3903 typedef enum{ 3904 MON=1,TUE,WEN 3905 }week; 3906 3907 void take(week i){ 3908 switch (i) { 3909 case MON: 3910 printf("星期一:要去交水費\n"); 3911 break; 3912 case TUE: 3913 printf("星期二:要去交電費\n"); 3914 break; 3915 case WEN: 3916 printf("星期三:要去交煤氣費\n"); 3917 break; 3918 default: 3919 break; 3920 } 3921 } 3922 3923 int main(int argc, const char * argv[]) 3924 { 3925 printf("MON:%d\n",MON); 3926 printf("TUE:%d\n",TUE); 3927 printf("WEN:%d\n",WEN); 3928 3929 int week=0; 3930 printf("請選擇今天星期幾:\n"); 3931 printf("1.星期一\n"); 3932 printf("2.星期二\n"); 3933 printf("3.星期三\n"); 3934 3935 scanf("%d",&week); 3936 take(week); 3937 return 0; 3938 } 3939 結果: 3940 MON:1 3941 TUE:2 3942 WEN:3 3943 請選擇今天星期幾: 3944 1.星期一 3945 2.星期二 3946 3.星期三 3947 1 3948 星期一:要去交水費 3949 3950 練習 3951 輸入一個整數,求春夏秋冬 3952 用戶從控制台輸入一個整數,由程序判斷該整數是春 夏秋冬哪個季節。春夏秋冬分別用一個枚舉常量表示 3953 #include <stdio.h> 3954 3955 typedef enum{ 3956 SPRING,SUMMER,AUTUMN,WINTER 3957 }Season; 3958 3959 void func(int num){ 3960 switch (num%4) { 3961 case SPRING: 3962 printf("春天來了!\n"); 3963 break; 3964 case SUMMER: 3965 printf("夏天來了!\n"); 3966 break; 3967 case AUTUMN: 3968 printf("秋天來了!\n"); 3969 break; 3970 case WINTER: 3971 printf("冬天來了!\n"); 3972 break; 3973 3974 default: 3975 break; 3976 } 3977 3978 3979 } 3980 3981 int main(int argc, const char * argv[]) 3982 { int num=0; 3983 printf("請輸入任意一個整數數字:"); 3984 scanf("%d",&num); 3985 func(num); 3986 結果: 3987 請輸入任意一個整數數字:897231 3988 冬天來了! 3989 3990 知識點 3991 二十二、高級指針 3992 3993 一.雙指針(二級指針) 3994 #include <stdio.h> 3995 void change(int j){//值傳遞 3996 j = 20; 3997 printf("j:%d\n",j); 3998 } 3999 void change2(int* p){//地址傳遞 4000 *p = 20; 4001 printf("*p:%d\n",*p); 4002 } 4003 /* 4004 char** change3(){ 4005 char* str = "Hello"; 4006 return &str; 4007 } 4008 */ 4009 void change4(char** p){ 4010 *p = "Hello"; 4011 } 4012 int main(int argc, const char * argv[]) 4013 { 4014 int i = 10; 4015 //change(i); 4016 change2(&i); 4017 printf("i:%d\n",i); 4018 char *p;//保存一個字符串的位置 4019 change4(&p); 4020 printf("p:%s\n",p); 4021 return 0; 4022 } 4023 結果: 4024 *p:20 4025 i:20 4026 p:Hello 4027 4028 二、void指針 4029 4030 1.任意類型的指針 4031 2.malloc分配堆內存時,由於無法確定內存存儲類型,所以可 以使用void*代表任意指針類型 4032 #include <stdio.h> 4033 typedef enum{INT,CHAR,FLOAT,DOUBLE} type; 4034 void output(void* p,type t){ 4035 switch (t) { 4036 case INT: 4037 //char c = (char)200;//類型轉換 4038 printf("%d\n",*((int*)p)); 4039 break; 4040 case CHAR: 4041 printf("%c\n",*(char*)p); 4042 break; 4043 case FLOAT: 4044 //char c = (char)200;//類型轉換 4045 printf("%f\n",*((float*)p)); 4046 break; 4047 case DOUBLE: 4048 printf("%lf\n",*(double*)p); 4049 break; 4050 } 4051 } 4052 int main(int argc, const char * argv[]) 4053 { 4054 int i = 10; 4055 output(&i,INT); 4056 char c = 'a'; 4057 float f = 10.1f; 4058 double d = 20.1; 4059 output(&f,FLOAT); 4060 return 0; 4061 } 4062 結果: 4063 10 4064 10.100000 4065 4066 三、函數指針 4067 #include <stdio.h> 4068 //1.返回值類型 4069 void func(){ 4070 printf("Hello, World!\n"); 4071 } 4072 //2. 4073 int func2(){ 4074 return 10; 4075 4076 } 4077 //3. 4078 int func3(){ 4079 return 1; 4080 4081 } 4082 int main(int argc, const char * argv[]) 4083 { printf("%p\n",&func); 4084 printf("%p\n",func); 4085 //函數指針變量*funcp 保存函數指針 func 4086 //1.返回值類型....參數... 4087 void(*funcp)()=func;//調用沒有括號func 4088 funcp(); 4089 //2. 4090 int(*funcp2)()=func2; 4091 int i=funcp2(); 4092 printf("i:%d\n",i); 4093 //3. 4094 int(*funcp3)(int)=func3; 4095 int i2=funcp3(5); 4096 printf("i2:%d\n",i2); 4097 4098 4099 return 0; 4100 } 4101 結果: 4102 0x100000e40 4103 0x100000e40 4104 Hello, World! 4105 i:10 4106 i2:1 4107 4108 四、對內存管理 4109 4110 1.malloc函數 4111 a.導入頭文件 4112 #include <stdlib.h> 4113 b.分配一個堆內存的空間,可以根據參數大小分配相應內存空間 4114 空間的首地址 malloc(空間大小) 4115 語法:void*malloc(4);//字節 4116 c.分配變量 4117 int *p; p = (int*)malloc(sizeof(int)); 4118 練習: 4119 #include <stdio.h> 4120 #include <stdlib.h> 4121 int main(int argc, const char * argv[]) 4122 { //輸入三個數並輸出 4123 int a[3]={0};//棧 4124 printf("a address:%p\n",a); 4125 //開辟堆空間 void*malloc(size_t) 4126 //堆內存的分配不一定成功 4127 //如果成功則得到一個地址,如果不成功得到NULL 4128 int*p;//分配變量 4129 p=(int*)malloc(sizeof(int)*3);//語法格式 4130 if (p!=NULL) { 4131 //使用前做類型轉換 4132 printf("p address:%p\n",p); 4133 for (int i=0; i<3; i++) { 4134 printf("請輸入%d第個數:",i+1); 4135 //scanf("%d",&a[i]); 4136 scanf("%d",(p+i)); 4137 } 4138 4139 //輸出函數 4140 for (int i=0; i<3; i++) { 4141 //printf("第%d個數為:%d\n",i+1,a[i]); 4142 printf("第%d個數為:%d\n",i+1,*(p+i)); 4143 } 4144 } 4145 else{ 4146 printf("分配內存失敗"); 4147 4148 } 4149 return 0; 4150 } 4151 結果: 4152 a address:0x7fff5fbff83c 4153 p address:0x100103b10 4154 請輸入1第個數:3 4155 請輸入2第個數:5 4156 請輸入3第個數:6 4157 第1個數為:3 4158 第2個數為:5 4159 第3個數為:6 4160 4161 2.calloc函數 4162 a.分配一個堆內存空間 4163 b.#include <stdlib.h> 4164 c.空間的首地址 calloc(元素的個數,元素的大小) 4165 語法:void*calloc(4,size(int)); 4166 calloc與malloc的區別是,不但分配內存空間,而且還會將分配到的內存空間清0 4167 //開辟堆空間 void*calloc(size_t,size_t) 4168 //參數1 元素的個數 參數2 元素的類型 4169 int*p;//分配變量 4170 p=(int*)calloc(3,sizeof(int)); 4171 以上輸入輸出函數程序只改變此句,結果不變 4172 4173 3.realloc函數 4174 調整一個內存空間,存在兩種情況,如果原來的位置可以調整,則首地址不變。如果原來的位置不可以調整,創建一個新的內存空間,並將原來數據自動復制過來,將原來的內存自動銷毀,返回新的內存的首地址。調整內存空間也可能有風險,即創建不成功。 4175 a.空間的首地址 realloc(原來首地址,調整後的空間大小) 4176 void* realloc(p,sizeof(int)*5); 4177 b.調整內存空間也不一定成功,所以盡量創建一個新的變量來保存。 4178 #include <stdio.h> 4179 #include <stdlib.h> 4180 int main(int argc, const char * argv[]) 4181 { 4182 //輸入三個數,保存並輸出 4183 int array[3]={0};//棧 4184 printf("array address:%p\n",array); 4185 //開辟堆空間 void* calloc(size_t,size_t) 4186 //三數1 元素的個數 參數2 元素的類型 4187 //堆內存分配不一定成功 4188 //如果成功則得到一個地址,如果不成功得到NULL 4189 int* p = (int*)malloc(sizeof(int)*3); 4190 printf("p address:%p\n",p); 4191 //調整內存空間 參數1 原來空間的首地址 參數2 調整後的大小 4192 int* p2=(int*)realloc(p,sizeof(int)*4); 4193 printf("p2 address:%p\n",p2); 4194 if (p2!=NULL) {//分配內存成功 4195 p = p2;//分配成功後,如果得到新的地址,會自動將原來的銷毀。 4196 printf("p address:%p\n",p); 4197 //使用前做類型轉換 4198 for (int i = 0; i<4; i++) { 4199 printf("請輸入第%d個數:\n",i+1); 4200 //scanf("%d",&array[i]); 4201 scanf("%d",(p+i)); 4202 } 4203 for (int i = 0; i<4; i++) { 4204 printf("第%d個數:%d\n",i+1,*(p+i)); 4205 } 4206 }else{ 4207 printf("分配內存失敗!\n"); 4208 } 4209 free(p);//釋堆空間 4210 //野指針:一個指針指向一個不合法區域 4211 p = NULL;//空指針 用來解決野指針 4212 //在OC訪問一個空指針是合法並且不會報錯 4213 //printf("p->value:%d\n",*p); 4214 //printf("p address:%p\n",p); 4215 return 0; 4216 } 4217 結果: 4218 array address:0x7fff5fbff82c 4219 p address:0x100103b10 4220 p2 address:0x100103b10 4221 p address:0x100103b10 4222 請輸入第1個數: 4223 6 4224 請輸入第2個數: 4225 4 4226 請輸入第3個數: 4227 3 4228 請輸入第4個數: 4229 4 4230 第1個數:6 4231 第2個數:4 4232 第3個數:3 4233 第4個數:4 4234 4235 4.free函數 4236 可以將堆空間銷毀掉(釋放) 4237 free(堆空間首地址); 4238 銷毀堆空間時,指針變量依然是有值的,但是指向了一個不合法的內存區域,野指針。當程序對野指針進行操作是不合法的,會報錯的。標准的做法,將野指針賦NULL值,變成空指針。在OC當中,就可避免操作問題,並且不會報錯。 4239