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