C语言基础(转载自大海笔记)

# C语言基础
2015年03月26日10:04:41
1、    语言排行榜
C——java——objective-C
2、    进制:
进制:进位机制。用普通的话讲,应该为人为的定义一种度量来标识一样东西。
计算机常用的进制有:十进制、二进制、八进制和十六进制。
➢    十进制:0-9(十个指头)(进制表示基数:10)
➢    二进制:0,1(基数为2)
➢    八进制:0-7(基数为8)
➢    十六进制:0-9,A-F(基数为16)
    可以有很多进制,比如分钟为60进制等等。
3、    位权
为了进制之间转换而出的一个概念。
位:一个通用的描述方式。最低位为第0位。之后依次+1。
例如:9AF(F为第0位,A为第1位,9为第2位)
权:进制是几,权就是几。

位权:某位上的数*权^该位
例如:231,权为:10,位是:2,位权1为10^0,位权3为10^1,位权2为10^2
4、    进制转换
    十进制转X进制:连除倒取余数(取余数是从下往上取)

用通俗的话讲:十进制的某个数转化为其他进制时,将该数除以进制,依次将余数写在除法每一步的旁边,一直除完为止。则所对应的转化后的值,从下往上按顺序记录余数,该余数即为转化后的结果。

X进制转十进制:按权求和

用通俗的话讲:用位权的计算方法,将某进制的数,从第0位开始,把第0位上得数*进制(权)的0次方,加上第1位上得数*进制(权)的1次方….以此类推,直至该进制的数的最高位,所得到的和,即为转化所得的十进制的结果。

进制修饰(区别什么数是什么进制):
➢    十进制:什么都不加修饰 如:111
➢    八进制:在前加0  如:0111
➢    十六进制:在前加0X   如:0X111
➢    二进制:在前加0b 如:0b111
当程序员不想自己用笔来计算较大的进制转换时,点击右上角搜索按钮spotlight 搜索“计算器”。command+1(简单型计算器)2为科学型,3为编程型

2015年03月26日14:31:45
5、    基本数据类型
记忆基本数据类型的时候,这样记——三大类:
➢    字符:
(关键字)char :字符型  占字节:1 = 8位 写得出来的都是字符’1’ ‘2’ ‘A’ 。对应十进制0~255之间任意 任意一个数都可以表示,但是>256的不能存储。

➢    整型:
(关键字)short 短整型 : 字节:2 = 16位 0~65535
(关键字)int 整型 :      字节:4 = 32位 0~2^33-1
(关键字)long 长整形 : 字节:8或4(C语言没有给一个明确的数字,而是这样定义的,long型的数不小于int型的数。Int型的数不小于short型的数)

➢    浮点:
(关键字)float 单精度浮点型 :  字节:4
(关键字)double 双精度浮点型 : 字节:8

字节:1字节 = 8位

看一个数是正数还是负数,看最高位是啥:0为正,1为负

6、    常量
不可改变的量。
如: 719,‘A’,‘a’等等。        
7、    变量
变量:变量相当于一个容器或位置.
//定义一个变量
        //整型
        int num1 = 10;
        //短整型
        short s1=111;
        //长整型
        long l1=123456789;
        //浮点型(单精度)
        float f1=1.2;
        //浮点型(双精度)
        double d1=2.22;
        //字符型
        char c1= '1';

变量命名规则

➢    数字0~9,下划线_,字母 a~z,A~Z 组成,不能以数字开头
➢    不可以用系统保留字
➢    不能使用重复变量名
➢    见名之意。(规范)定义一个变量,要明显知道变量名的意思。

赋值运算符:=  可以给一个变量赋值。

//赋值运算符:=,可以给一个变量赋值。
        //交换两个变量中的值。
        int number1=10;
        int number2=20;
        //准备另一个变量,用于临时存放
        int temp=0;
        printf("前number1:%d \n",number1);
        printf("前number2:%d \n",number2);
        
        temp=number1;
        number1=number2;
        number2=temp;
        
        printf("后number1:%d \n",number1);
        printf("后number2:%d \n",number2);
        
课后思考题,交换两个变量的值,不使用第三个变量。
提示:有两种方式。

8、    算术运算符
算数运算符,主要是看什么,主要是看+,-,*,/ ,++,--,这几个运算符的用法,+,-,*就不说了,/(除法)主要是要看除数不能为0,虽然计算机不报错(因为语句都符合C语言的标准,程序会执行。),但是在运行后,给出的结果不正确。
++和—运算比较特殊,应该这样记:++在前则先++,++在后则后++。--和++一样。
要明白一点就是,运算过程中,会出现自动数据类型转换。
//+号
//        //n1=30
//        int n1 = 10+20;
//        //n2=40;
//        int n2 = n1+10;
//        //n3=70
//        int n3=n1+n2;
//        //n4=140;
//        int n4= n1+n2+n3;
        
        // -号
//        // n1=10;
//        int n1 = 30-20;
//        //n2=0;
//        int n2 = n1-10;
//        //n3=-10;
//        int n3 = n2-n1;
//        //n4=-20;
//        int n4 = n3-n2-n1;
        
        // *号
        
        //除法:/
        
//        //使用除号/,注意0不能坐除数! xcode不报错,只提出警告,并能运行。
////        int n1 = 10 / 0;
//        //除号两边都是整数,结果也是整数,不论除尽的小数点后面是什么值,都舍去。
//        int n2 = 3 / 2;
//        //除号两边都是浮点型,结果也是浮点型。n3=1.5
//        float n3 = 3.0/2.0;
//        //参与运算的数,如果 运算符 两边,只要有一个是浮点型,结果都为浮点型。n4=1.5
//        float n4 = 3/2.0;
        
        //取余 %
        
//        //n1 = 1
//        int n1 = 3 % 2;
//        //n2 = 0
//        int n2 = 4 % 2;
//        
//        //取余运算符两边的数,必须都为整型;
////        int n3 = 5.0 % 2.0;
//        
//        //取余之后的结果 < 除数,一定小于除数。
        
        
        //++在后
//        //n1=0
//        int n1 = 0;
//        //n1=0
//        //如果++在后面,只要这条语句没有执行完,n1++都表示原来的值。
//        //n3=0;
//        int n3 = n1++;
//        //n2= 1
//        int n2 = n1;
        
        //++在前
        
//        int n1 = 0;
//        //++在前,先加1,再赋值。n2=1
//        int n2 = ++n1;
        
        //符合运算符
//        int n1 = 10;
//        int n2 = 30;
//        n2 = n2 + n1;
////        n2 += n1;与n2 = n2 + n1;等效;

9、    表达式
表达式:常量、变量与运算符的组合。
例如:3,3+1,n1+1,3+(也是表达式,但是是错误的表达式)

表达式都会有返回值。

语句是程序执行的最小单位,以分号结尾。
例如:1; 1+7;

不以分号结尾的,不管前面写的再好,再标准,都不是语句。
10、    基本输入输出
基本输入输出函数    ,在C语言的第一个hello world程序里,有printf(“hello world”);这个语句,printf是标准输出函数,虽说打印语句都是程序里最简单的一个方法,但是在C语言中,printf函数输出,不仅仅是一个函数而已,它是由先人用汇编语言把计算机内存和显存的各种机理封装在了printf函数中,这个函数是在stdio.h这个库文件中的。
库文件:即为前人写好的代码,放在了一起,我们可以直接用。
输出:printf();
形式是这样的:printf(“%d”,100)这个是输出整型;printf(“%f”,100.0)这个是输出浮点型;printf(“%c”,’100’)这个是输出字符型的数据。
这个时候,输出整形还可以分:printf(“%sd”,100)这个输出短整型;printf(“%ld”,100)这个输出长整型。
输出函数printf还有一个要注意的地方:
➢    %和d中间的数字,代表预留几个位置:从右往左算。
➢    如果预留位置小于实际位置,按照实际位置来。
➢    如果预留位置大于实际位置,在输出的左边补上空格。
➢    如果数字前加0,则把空格变为补0;
例子:printf("%05d",12);输出结果:00012
➢    .X表示保留小数点后X位,%4.2f表示保留小数点后2两位。.前为代表预留几个位置。
例如:printf("%4.2f",1.2345);//1.23
➢    小数点也站位。
例如:printf("%4.1f",1.2345);//_1.2(下划线代表空格)
➢    正数表示右对齐(如果给出预留位大于实际位,左边空格代替),负数表示左对齐(如果给出预留位大于实际位,右边空格)。
例如:printf("%-4dabc",123);//123_abc(下划线代表空格)
另外C语言推出一些解决输出转义字符的办法
printf("123\n456");//换行。
        
printf("\\");//打印\
        
printf("%%");//打印%

输入:scanf()
在用户输入一个数据时,需要在程序里定义一个变量来接收这个输入进来的值。
//        int n1 = 0;
//        printf("请输入一个数字,按回车结束:");
//        scanf("%d",&n1);
//        printf("n1 = %d",n1);
值得注意的是,scanf("%d",&n1);中变量需要用&n1表示。&表示取地址。后面会介绍。
关于输入数据类型,也需要注意,如果输入的数据类型和程序里定义的变量数据类型不匹配,则定义的变量拒绝接收输入进来的数据。
在输入函数中,与输出函数还有一个区别就是:输出函数的double类型占位符,用%f,但是输入函数的double类型占位符是%lf。
//        double d1 = 0;
//        scanf("%lf",&d1);
输入函数接收多个参数时,可以这样写:但是不推荐。
        //接收多个输入值。
//        int num1 = 0;
//        int  num2 = 0;
//        printf("请输入两个数字,按回车结束:");
        //不推荐这么写
//        scanf("%d%d",&num1,&num2);
//        printf("num1 = %d , num2 = %d",num1,num2);

推荐的时分开接收:
        //推荐分开写
//        int num1 = 0;
//        int  num2 = 0;
//        scanf("%d",&num1);
//        scanf("%d",&num2);

scanf中,不推荐写除了占位符以外的东西,因为输入的时候需要一一对应输入,否则不接收输入数据。
例如:scanf(“sum = %d”,&n1);则需要在控制台输入:sum=100,才能匹配,n1才能接收到数据,否则拒绝接收数据。
Scanf中的占位符,不能加\n,否则在输入数据时匹配回车将会和\n(换行)进行匹配后,无法得出结果。

——大海
2015年03月26日21:05:54 北京

2015年03月27日09:44:50
11、分支结构
在学分支结构之前,要知道一点就是C89标准中没有BOOl这个类型,因此需要将标准升级为C99标准。

C99标准在Xcode中,在新建一个工程的时候,选择type时,选择doundation。
创建工程之后,会发现,与之前的main.c的后缀已经变为main.m。这是objective-C环境下的后缀。
与之前.c的页面中,还有不同的是:
将#include<stdio.h>换成
#import <Foundation/Foundation.h>
//import是oc语法,作用和include是一样的。都是引入一个文件。

//Foundation/Foundation.h 是系统提供的一些功能,可以直接用,比stdio.h所包含的东西多得多。

12、bool数据类型
bool数据类型,只有yes和no两个值,非真即假。在C语言中,认为,非0即为真。
用处:用于if语句的时候和循环判断的时候。

在编译过程中,C语言将bool的yes值编译成1存在内存中,将no值编译成0,保存在内存中。
#define yes  1
#define no  0

13、关系运算符
关系运算符主要就是两者之间的比较,> (大于),>= (大于等于),< (小于),<= (小于等于),== (等于),!=(不等于) 。比较得出的结果是bool类型的值,用bool类型变量来存储。其他没什么了。
14、逻辑运算符

逻辑运算符就三个:与(&&),或(||),非(!)
参与运算的数,在符号两边都是bool值 。得出的结果不是真就是假。

&& 逻辑与:只要有一个为假,全都为假。
|| 逻辑或:只要有一个为真,结果都为真。
! 逻辑非:取反。
短路现象:
逻辑与运算的时候,如果系统检测到&&前的值是no,那么将不再去判断&&号后面的值,此时,如果&&后的值有赋值运算,赋值运算也不执行。
逻辑或运算的时候,如果系统检测到 || 号前的值是yes ,那么将不再去判断 || 号后面的值,此时,如果 || 后的值有赋值运算,赋值运算也不执行。
    //短路现象
    //逻辑与,如果前面判断是假,后面的判断不再执行。
//    int num1 = -1 ;
//    int num2 = -1;
//    BOOL b3 = (num1 = 0) && (num2 = 2);//假
//    
//    printf("%d",b3);//0
//    printf("num1 = %d \n",num1);// 0
//    printf("num2 = %d]\n",num2); // -1
    
    //短路现象
    //逻辑或,如果前面判断是真,后面的判断不再执行。
//    int num1 = -1 ;
//    int num2 = -1;
//    BOOL b3 = (num1 = 2) || (num2 = 0);//真
//    
//    printf("%d",b3);//1
//    printf("num1 = %d \n",num1);// 2
//    printf("num2 = %d)\n",num2); // -1

15、if语句
程序的三种结构:
顺序结构:按顺序执行程序,直到完事为止。
分支结构:if语句和switch
循环结构:循环的执行一段语句。直到循环条件结束为止。
分支结构有两个: if语句和switch语句
if语句有三种方式:
(1)if(条件表达式){
}
    //分支结构
    //if的(第一种形式)
    
//    BOOL b1 = NO;
//    if (/*条件表达式:要明确的表明条件是真是假*/b1){
//        printf("你个大骗子。。。");
//    }
    //练习
    /*
     从控制台输入一个整数。
     判断这个整数是否>100。
     如果大于100,输出:“这个数大于100”
     */
//    int num = 0;
//    printf("请输入一个整数,按回车结束:\n");
//    scanf("%d",&num);
//    if(num > 100){
//        printf("你输入的数为:%d \n",num);
//        printf("这个整数大于100\n");
//    }
//    char c1 = 0;
//    printf("输入一个字符,按回车结束:\n");
//    scanf("%c",&c1);
//    BOOL b1 ='m' == c1;
//    if(b1){
//        printf("输入的是男性");
//    }

(2)if(条件表达式){
}else{
}

/    char c2 = 0;
//    printf("请输入字符:");
//    scanf("%c",&c2);
//    if ('m' == c2) {
//        
//        printf("正太");
//    }else{
//        printf("萝莉");
//    }
    
//    int year = 0;
//    printf("请输入年份,按回车结束:");
//    scanf("%d",&year);
//    
//   //判断闰年的条件
//    BOOL b1 = (year % 400 == 0 ) ;
//    BOOL b2 =(year % 100 !=0) && (year % 4==0);
//    if(b1 || b2){
//        
//        printf("%d\t是闰年\n",year);
//        
//    }else{
//        printf("%d\t是平年!",year);
//    }

(3)if(条件表达式){
}else if(条件表达式){
}else{
}
    
//    char c3 = 0;
//    printf("输入一个字符:");
//    scanf("%c",&c3);
//    
//    if('m' == c3){
//        printf("男性");
//    }else if ('f' == c3){
//        printf("女性");
//    }else{
//        printf("春哥");
//    }
    
    /*
     输入一个字符,判断
     s:春天
     m:夏天
     a:秋天
     w:冬天
     其他:输入有误。
     */
//    char c1 = 0;
//    
//    printf("输入一个字符,按回车结束:");
//    
//    scanf("%c",&c1);
//    
//    if('s' == c1){
//        printf("我是春天!");
//    }else if('m' == c1 ){
//        printf("我是夏天!");
//        
//    }else if('a' == c1){
//        printf("我是秋天!");
//        
//    }else if ('w' == c1){
//        printf("我是冬天!");
//    }else{
//        printf("输入有误!!");
//    }

16、条件表达式
    //条件表达式
//    int num1 = 10;
//    int num2 = 20;
//    
//    int num3 = num1>num2 ? num1 : num2;
//    
//    printf("num3 = %d",num3);
    
    //课后练习题
    /*
     使用条件运算符,选择出三个数中,哪个最大。
    */
洞房花烛夜 我 两小无猜
字符型就是整型。

Switch 分支语句
Switch分支语句就是为了优化if(){}else if(){}过多条件。
    //switch分支语句
//    switch (apple) {
//        case apple:
//            printf("我是苹果也!");
//            //break:终止往后继续执行
//            break;
//        case banana:
//            printf("我是香蕉也!");
//            break;
//        case orange:
//            printf("我是橘子也!");
//            break;
//        case watermelon:
//            printf("我是西瓜也!");
//            break;
//        default:
//            printf("我不是水果也!");
//    }

与else if一样的效果。
注意的是:switch ()括号中的条件必须为整型条件表达式。在每一个case下的语句代码,最后都要加上break,用来跳出switch语句。
    //练习
    
//    int season = 0;
//    printf("请输入一个数字,按回车结束:");
//    scanf("%d",&season);
//    
//    switch (season) {
//        case 1:
//            printf("春天啊我是!spring");
//            break;
//        case 2:
//            printf("夏天啊我是!summer");
//            break;
//        case 3:
//            printf("秋天啊我是!autumn");
//            break;
//        case 4:
//            printf("冬天啊我是!winter");
//            break;
//            
//        default:
//            printf("啥也不是啊我!nothing");
//            break;
//    }

17、枚举enum
#import <Foundation/Foundation.h>
//枚举,建议写在这个地方。
enum season{
    //第一个元素,默认为0.后面元素依次+1.spring 自动被赋值为0,summer 为1.
    //每个值都可以改变默认值,后面的数还是依次+1.初始化过的默认值,后面的数还是依次+1
    spring = 100, //100
    summer = 200, // 200
    autumn, //201
    winter //202

};
// 练习,定义一个枚举

//定义五个水果:苹果(10),香蕉,橘子,西瓜
enum fruits{
    apple = 10,
    banana,
    orange,
    watermelon
};
int main(){
}

——大海
2015年03月27日20:38:00 北京

18、循环
特点:在满足特定条件的情况下,反复执行某程序段。
While循环
While循环的格式是这样的:while(条件表达式){语句代码},意思是满足括号内的条件时,执行花括号内的语句代码。或者更专业一点来说,当括号内的条件表达式返回值为真时,执行花括号内的代码,一直到条件表达式的返回值为假时,跳出循环。

While循环很容易出现死循环这种状况,就是因为忘记写了“增量”这个东西。
//死循环
int count = 0 ;
//    while (count < 100) {
//        printf("今天我真帅...\n");
//    }
上面的代码就是少了count++,这个增量,所以,条件表达式一直满足,就一直执行,就造成了死循环。
此时,应该这样改进:
    //循环变量 :控制循环次数
//    int count = 0;
//    while (/* ++ 在前,打印两次 */count/* ++ 在后,打印三次*/ < 3 ) {
//        
//        printf("今天我真帅...\n");
////        count = count +1;
//        
//        //此处,++ 在前在后都不影响打印次数。
//        
//        //循环增量
//        count ++;
////        ++ count;
//    }
一些例子:
    //练习
    //打印1~100
//    int num = 0;
//    while (num < 100) {
//        printf(" %d \n",(num + 1));
//        
//        num ++;
//    }
    
    //用while 打印能被7整除的1~100之间的数。
//    int num = 1;
//    while (num <= 100) {
//        
//        if(num % 7 == 0){
//            printf("%d \t",num);
//        }
//        num ++;
//    }
    
    //用while循环打印出1~100之间各位为7的数。
//    int num = 0;
//    
//    while (num < 100) {
//        
//        if(num % 10 == 7){
//            printf("%d \t",(num));
//        }
//        num ++ ;
//    }
    
    //用while循环打印出1~100之间十位为7的数。 num / 10 == 7
    
//    int num = 0;
//    while (num < 100) {
//        if(num / 10 ==7){
//            printf("%d \t",num);
//        }
//        num ++;
//    }

Do-while循环
与while不同的只有一个地方,就是先执行一遍代码,再进行判断。也就是说,不管你while的条件表达式成不成立,返回值为不为假,我都执行一遍循环体的代码。
        // do while
    
//    do{
//        printf("至少执行一次,不管后面的判断条件是真还是假");
//    }while (1) ;// ; 分号不能丢

随机数arc4random()
产生随机数的方法,arc4random()可以产生int范围内的任意一个随机数,包括有正数和负数,为什么会出现负数呢?因为,在存储的时候,生成的数的最高位的数字为1,此时,会认为这个1是符号位的负,因此会出现负数。这时,我们应该把这些情况避免掉,在输出之前,用unsigned 来定义一个变量来接收产出的随机数;在输出的过程中,占位符不再用%d,而是用%u来代替。
另一个值得注意的是,随机数产生的时候,数字会很大,而我们在代码过程中,不需要这么大的数,此时,想要把这个数减小,可以用取余的办法来限制。
    //随机数 arc4random(),
    //用%u来打印,表示无符号。
    //由于随机函数给的值很大,我们采用取余的方法,使值变小。 取余的随机数的范围就是,0~被除数-1
    
    
//    printf("%u \t", arc4random() % 10);//打印 只有0~10的数

在产生一个随机数的时候,可以让它在固定的区间内产生,那么就会用到这个公式:
    //取某区间[a,b]的数,用公式:arc4random() % (b-a+1)+a
若是规定在负空间生成随机数,那么就将公式改成:
/arc4random() % (b-a+1)-a
一些例子:

//用户输入一个N,用while打印N个随机数(10~30)
//    int num = 0;
//    int count = 0;
//    printf("输入一个数:");
//    scanf("%d",&num);
//    printf("产生 %d 随机数为: \n\t",num);
//    while (count < num) {
//        
//        //unsigned 声明一个无符号int 类型。
//        unsigned unum = (arc4random()%((30-10+1)+10));
//        printf(" 第 %d 个数为:%d \t",(count+1), unum);
//        count ++;
//    }
    
    //输入一个数,用while打印n个随机数(30~70),找出随机数中最大值。
    
//    int num = 0;
//    printf("输入一个数:\n");
//    scanf("%d",&num);
//    int count = 0;
//    int max = 0;
//    while (count < num ) {
//        unsigned unum = (arc4random()%((70-30+1)+30));
//        printf(" 第 %d 个数为:%d \n",(count+1), unum);
//        
//        if(max < unum ){
//            max = unum;
//        }
//        count ++;
//    }
//    printf("\n ");
//    printf("最大的数为:%d \n",max);

Break和continue
这两个关键字在开发过程中经常遇见,他们的区别如下:
break:在某个循环的时候,用上break,意思就是停止这个循环,不再执行这个循环,我要跳出这个循环。
continue :在某个循环的时候,在过程中用上continue,意思就是,我在的这个循环还在运行,但是我不运行这一次的循环,我要跳到下一次的循环去,但是还是在这个循环里,没有跳出去,只是不执行这次罢了。
   //循环变量
//    int count = 0;
//    while (count <10) {
//        
//        count ++;
//        
//        if(count == 3){
//            //结束本次循环
//            continue;
//            /*
//             输出结果:
//             
//             第 1 天
//             第 2 天
//             第 4 天
//             第 5 天
//             第 6 天
//             第 7 天
//             第 8 天
//             第 9 天
//             第 10 天 */
//        }
//        if(count == 5){
//            //结束循环
//            break;
//            
//            /*
//             输出结果:
//             
//             第 1 天
//             第 2 天
//             第 4 天 */
//        }
//        
//        printf("第 %d 天 \n",count);
//        
//    }

for循环
for循环和while差不多,但是是将条件和增量,循环变量都一起放在了小括号里。
值得注意的是:while与for的比较时,for的一个好处
相比于while 循环:while 中存在浪费内存的情况,因为循环变量在while循环外边,直到它所在的花括号结束,才释放内存。而 for循环 的循环变量 在for循环结束后,即释放。
for循环的执行过程是这样的:
for(①int i= 0 ; ②i < 100;④i++){
    ③循环体
}
在运行到本处时,先进行①赋初值,然后判定条件,满足则跳进循环体执行代码③,执行循环体代码结束后,对i进行自增④i++,然后进行②判断,执行③,自增四。。。如此循环下去。

// for 循环
//    int count = 0;
//    while (count < 5) {
//        printf("\n我是 while 循环。。。");
//        count ++;
//    }
    
    // for(循环变量 ; 条件 ; 增量){ 循环体 }
//    for (int i = 0;i < 5; i++) {
//        printf("\n我是 for 循环哦。。。");
//    }
    
    //练习
    
    //打印 0 ~100
    
//    for (int i = 0; i <= 100; i ++) {
//        printf("%d \t",i);
//    }
    //打印1~100
    
    
    // 相比于while 循环:while 中存在浪费内存的情况,因为循环变量在while循环外边,直到它所在的花括号结束,才释放内存。
    // 而 for循环 的循环变量 在for循环结束后,即释放。
//    for (int j = 0; j < 100; j ++) {
//        printf("%d \t",(j + 1));
//    }
    
    //打印 ***
//    for (int i = 0; i < 3; i ++ ) {
//        printf("*");
//    }

循环嵌套
当我们发现,一个循环自身又要循环多次时,用循环嵌套:循环里有循环。
    //打印
    /*
     ***
     ***
     ***     
     */
    
    //两层for循环
    //外层for:负责控制行
//    for (int j = 0; j < 3; j++) {
//        //内层 for 负责每行打印多少个
//        for (int i = 0; i < 3; i ++ ) {
//            printf("*");
//        }
//        printf("\n");
//    }
    
    //打印
    /*
     1
     1 2
     1 2 3
     */
    // 里边的个数跟行数一样,(第一行有一个,第二行有2个。。。)那么只要 i <= j 就可以了。
    
    
//    for (int j = 1; j <= 3; j++) {
//        for (int i = 1; i <= j; i ++) {
//            printf("%d ",i);
//        }
//        printf("\n");
//    }
    
    
    //打印乘法口诀表
//    for (int i = 0; i < 9; i ++) {
//        //列
//        for (int j = 0; j <= i ; j ++) {
//            printf(" %d * %d = %d \t",j+1,i+1,(j+1)*(i+1));
//        }
//        printf("\n");
//    }    
    //三维数组合:
    // 三个for循环
    //百位 1~9
    for (int i = 1; i <= 9 ; i++) {
        //十位 0~9
        for ( int j = 0 ; j <= 9; j++) {
            //个位 0~9
            for (int k = 0 ; k <= 9 ; k++) {
                printf("%d\n",i * 100 + j * 10 + k);
            }
        }
    }

——大海
2015年03月30日20:14:46 北京

19、数组
数组:相同的数据类型成员组成的数据。
如:整型数组,浮点型数组。
数组的形式为:
类型修饰符 数组名[常量表达式] = { 1,2,3……..};

说明:数组在定义的时候,[ ]里必须用常量表达式,不能用变量表达式来代替。但是数组在使用的时候,[ ]中可以用变量来代替。

数组和循环是一对好基友。

数组的几个注意的点:
1、只有定义时,[ ]内为常量表达式。不能放变量。
//    int n =3;
//    int arr1[n] = {10,20,30};//报错

2、[ ]可以放算术式。
    
//    int arr2[1+2] = {10,20,30};

3、初始化时可以放多余空间的元素(但是这是不对的)
//    int arr3[3] = {10,20,30,40};

4、定义时,可以不给出常量表达式。(数组可以通过元素个数推算空间)。给出多少个元素,会自动给你分配多少空间
//    int arr4[] = {10,20,30};
5、前三个空间值分别为10,20,30,后面的7个空间全部清0,为0。

//    int arr5[10] = {10,20,30};
6、数组初始化
//    int arr6[3] = {0};
//    //错误的
//    int arr7[] = {0};

一些例子:
    //练习
    
//    float arr_f[3] = {3.1,5.2,7.9};
    
    
    //使用数组
//    int arr8[3] = {10,20,30};
    
//    printf("%d",arr8[0]);
//    printf("%d",arr8[1]);
//    printf("%d",arr8[2]);

数组取值:
    //使用数组可以用下标取值
    //下标可以使用变量
//数组可以使用循环取出所有值
//    for (int i = 0; i < 3; i ++) {
//        printf("%d \n",arr8[i]);
//    }
越界
1、存储的时候越界:
    
    //第一种,存储的时候越界
//    int arr9[3] = {10,20,30,40};//此时,40 已经被写入内存,但是取值的时候,40所在的内存空间已经被修改,所以取值的时候,很难取到40
//    
//    for (int i = 0; i < 4; i ++) {//循环4次,打印10,20,30,0(不同的计算机打印出来的值不同)
//
//        printf("%d\n",arr9[i]);
//    }
//

2、使用的时候越界
    //第二种,使用的时候越界
    
//    int arr10[3] = {10,20,30};
//    
//    arr10[0] = 50;//自己定义的数组,可以随便改。
//    
//    printf("%d",arr10[0]);//打印50
//    
//    
//    arr10[3] = 50;//可以访问之后的任意空间,本数组的第4个内存空间位置,被改动。
//    
//    printf("%d",arr10[3]);//打印50

C语言可以通过我们定义的数组,操作本数组之后的所有内存空间,那些空间不属于这个数组,谁都可以去用。因此可以在上面进行读写。这样就会使得程序不安全。

数组越界是一件很危险的事情,我们无法把控,因此我们在操作程序是,尽可能的避免越界产生。
数组是一个整体,不能直接参与运算,只能对各个元素进行处理。

一些代码:
//练习
    
    //1、定义一个具有20个元素的整型数组,30~70 间的随机数,求和。
    
//    //定义数组,并清零,初始化。
//    int array[20] = {0};
//    // 求和变量
//    int sum = 0;
//    printf("20个随机数为:\n");
//    //产生20 个随机数
//    for (int i = 0; i < 20; i++) {
//        unsigned num = arc4random() % (70-30+1)+30;
//        printf("%d\t",num);
//        array[i] = num;
//        //不要在这个地方求和,一个for一个功能。增加代码的重用性。
////        sum = sum + array[i];
//    }
    
//    //求和
//    for (int i = 0; i < 20 ; i ++) {
//        sum += array[i];
//    }
//    
//    
//    printf("\n\n20个数的和 sum = %d",sum);
    
    
    //2、复制数组。
//    int array1[5] = {10,20,30,40,50};
//    int array2[5] = {0};
//    for (int i = 0; i < 5; i ++) {
//        array2[i] = array1[i];
//        printf("%d\t",array2[i]);
//    }

排序
冒泡排序
从第一个数开始,用第一个数分别与后面的数进行比较,若是大于后面的数,则将该数放在后面。然后再用第二个数跟后面的数比较,若大于后面的数,则将该数放在后面,依次类推,一直到最后一个数比较完毕为止。此时,排序已经完成。
    //数组排序
    
//    //冒泡排序(只适合小范围的数据排序)(20遍)
//    int sort_arr[5] = {5,4,3,2,1};
//    //外层循环,控制排序趟数,趟数为 :数组元素个数-1
//    for (int i = 0; i < (5-1)/*5-1,表示数组有n个数比较,只比较n-1趟*/; i ++) {
//        //内层for循环,控制比较次数
//        for (int j = 0; j < 5 - (i+1)/*本来应该是5-i,但是i是从0 开始的,我们要得是从1开始,因此要5-(i+1)。此处的意思是每一趟,比较多少次。*/; j ++) {
//            //判断,并且交换。
//            if (sort_arr[j] > sort_arr[j+1]) {
//                //交换,不使用第三个变量交换,用亦或 ^ 的方法最好。
//                sort_arr[j] = sort_arr[j] ^ sort_arr[j+1];
//                sort_arr[j+1] = sort_arr[j] ^ sort_arr[j+1];
//                sort_arr[j] = sort_arr[j] ^ sort_arr[j+1];
//            }
//        }
//    }
//    //打印
//    printf("冒泡排序后:");
//    for (int i = 0; i < 5; i ++) {
//        printf("%d\t",sort_arr[i]);
//    }
    
    //练习
//    //随机产生10个[20,40]间的数,排序
//    
//    int array[10] = {0};
//    printf("排序前的10个数为:\n");
//    //取随机数
//    for (int i = 0; i < 10 ; i ++) {
//        unsigned num = arc4random() % 21+20;
//        array[i] = num;
//        printf("%d\t",array[i]);
//    }
//    
//    //排序开始
//    //外层for循环,控制比较多少趟。
//    for (int i = 0; i < 10-1; i ++) {
//        //内层for循环,控制比较多少次
//        for (int j = 0; j < 10 -(i+1); j ++) {
//            //冒泡排序
//            if (array[j] > array[j+1]) {
//                //亦或,用来交换两个变量的值。
//                array[j] = array[j] ^ array[j+1];
//                array[j+1] = array[j] ^ array[j+1];
//                array[j] = array[j] ^ array[j+1];
//            }
//        }
//    }
//    printf("\n排序后的10 个数为:\n");
//    for (int i = 0 ; i < 10 ; i ++) {
//        printf("%d\t",array[i]);
//    }

字符数组
第一种定义:
char array[5] = {'h','e','l','l','o'};
第二种定义:
char array1[6] = "hello";
第二种定义在定义的时候,自动添加一个'\0'。这个\0有着特定的意义,在接下来输出这个数组时,将会用%s来作为占位符,当%s在输出数组时,遇到了’\0’这个特定意义的“结束标识符”时,就会终止打印,停止输出。

此时,数组的实际长度为:字符数组元素个数+1,要留出'\0'的位置。
//    //%s占位符
////    for (int i = 0; i <5 ; i++) {
////        printf("%c",array[i]);
////    }
//    printf("%s",array);//打印:hello
一些情况:
//    //自动推算出有6个位置
//    char array2[] = "hello";
//    
//    
//    //前面补满,后面补0
//    char array3[10] = "hello";
    
    //存储打印中文
//    char array3[20] = "蓝欧

上一篇:Mybatis按SQL查询字段的顺序返回查询结果


下一篇:Filter 数组过滤函数精解示例