精华内容
下载资源
问答
  • 1.C语言数组的概念在《更加优美的C语言输出》一节中我们举了一个例子,是输出一个 4×4 的整数矩阵,代码如下:#include <stdio.h>#include <stdlib.h>int main(){ int a1=20, a2=345, a3=700, a4=22; ...

    1.C语言数组的概念

    在《更加优美的C语言输出》一节中我们举了一个例子,是输出一个 4×4 的整数矩阵,代码如下:
    
       
    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. int main()
    4. {
    5. int a1=20, a2=345, a3=700, a4=22;
    6. int b1=56720, b2=9999, b3=20098, b4=2;
    7. int c1=233, c2=205, c3=1, c4=6666;
    8. int d1=34, d2=0, d3=23, d4=23006783;
    9. printf("%-9d %-9d %-9d %-9d\n", a1, a2, a3, a4);
    10. printf("%-9d %-9d %-9d %-9d\n", b1, b2, b3, b4);
    11. printf("%-9d %-9d %-9d %-9d\n", c1, c2, c3, c4);
    12. printf("%-9d %-9d %-9d %-9d\n", d1, d2, d3, d4);
    13. system("pause");
    14. return 0;
    15. }

    运行结果:
    20        345       700       22
    56720     9999      20098     2
    233       205       1         6666
    34        0         23        23006783
    矩阵共有 16 个整数,我们为每个整数定义了一个变量,也就是 16 个变量。那么,为了减少变量的数量,让开发更有效率,能不能为多个数据定义一个变量呢?比如,把每一行的整数放在一个变量里面,或者把 16 个整数全部都放在一个变量里面。
     
    我们知道,要想把数据放入内存,必须先要分配内存空间。放入4个整数,就得分配4个int类型的内存空间:
    
       
    1. int a[4];
    这样,就在内存中分配了4个int类型的内存空间,共 4×4=16 个字节,并为它们起了一个名字,叫a。
     
    我们把这样的一组数据的集合称为 数组(Array),它所包含的每一个数据叫做数组 元素(Element),所包含的数据的个数称为数组 长度(Length),例如int a[4];就定义了一个长度为4的整型数组,名字是a。
     
    数组中的每个元素都有一个序号,这个序号从0开始,而不是从我们熟悉的1开始,称为 下标(Index)。使用数组元素时,指明下标即可,形式为:
    
       
    1. arrayName[index]

    arrayName 为数组名称,index 为下标。例如,a[0] 表示第0个元素,a[3] 表示第3个元素。
     
    接下来我们就把第一行的4个整数放入数组:
    
       
    1. a[0]=20;
    2. a[1]=345;
    3. a[2]=700;
    4. a[3]=22;

    这里的0、1、2、3就是数组下标,a[0]、a[1]、a[2]、a[3] 就是数组元素。
     
    我们来总结一下数组的定义方式:
    
       
    1. dataType arrayName[length];

    dataType 为数据类型,arrayName 为数组名称,length 为数组长度。例如:
    
       
    1. float m[12];
    2. char ch[9];

     
    注意:
    1) 数组中每个元素的数据类型必须相同,对于int a[4];,每个元素都必须为 int。
     
    2) 数组下标必须是整数,取值范围为 0 ≥ index > length。
     
    3) 数组是一个整体,它的内存是连续的,下面是int a[4];的内存示意图:
     

    ①.数组的初始化

     
    上面的代码是先定义数组再给数组赋值,我们也可以在定义数组的同时赋值:
    
       
    1. int a[4] = {20, 345, 700, 22};

    { }中的值即为各元素的初值,各值之间用,间隔。
     
    对数组赋初值需要注意以下几点:
    1) 可以只给部分元素赋初值。当{ }中值的个数少于元素个数时,只给前面部分元素赋值。例如:
    
       
    1. int a[10]={12, 19, 22 , 993, 344};

    表示只给 a[0]~a[4] 5个元素赋值,而后面5个元素自动赋0值(int 类型变量的默认值就是0)。
     
    2) 只能给元素逐个赋值,不能给数组整体赋值。例如给十个元素全部赋1值,只能写为:
    
       
    1. int a[10]={1, 1, 1, 1, 1, 1, 1, 1, 1, 1};

    而不能写为:
    
      
    1. int a[10]=1;

    3) 如给全部元素赋值,那么在数组定义时可以不给出数组的长度。例如:
    
       
    1. int a[]={1,2,3,4,5};

    等价于
    
       
    1. int a[5]={1,2,3,4,5};

     
    最后,我们借助数组来输出一个 4×4 的矩阵:
    
       
    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. int main()
    4. {
    5. int a[4] = {20, 345, 700, 22};
    6. int b[4] = {56720, 9999, 20098, 2};
    7. int c[4] = {233, 205, 1, 6666};
    8. int d[4] = {34, 0, 23, 23006783};
    9. printf("%-9d %-9d %-9d %-9d\n", a[0], a[1], a[2], a[3]);
    10. printf("%-9d %-9d %-9d %-9d\n", b[0], b[1], b[2], b[3]);
    11. printf("%-9d %-9d %-9d %-9d\n", c[0], c[1], c[2], c[3]);
    12. printf("%-9d %-9d %-9d %-9d\n", d[0], d[1], d[2], d[3]);
    13. system("pause");
    14. return 0;
    15. }

    2.C语言二维数组

    上节讲解的数组可以看作是一行连续的数据,只有一个下标,称为一维数组。在实际问题中有很多量是二维的或多维的,因此C语言允许构造多维数组。多维数组元素有多个下标,以确定它在数组中的位置。本节只介绍二维数组,多维数组可由二维数组类推而得到。

    ①.二维数组的定义

     
    二维数组定义的一般形式是:
    
        
    1. dataType arrayName[length1][length2];

    其中, dataType 为数据类型,arrayName 为数组名,length1 为第一维下标的长度,length2 为第二维下标的长度。例如:
    
        
    1. int a[3][4];

    定义了一个3行4列的数组,共有3×4=12个元素,数组名为a,即:
    
        
    1. a[0][0], a[0][1], a[0][2], a[0][3]
    2. a[1][0], a[1][1], a[1][2], a[1][3]
    3. a[2][0], a[2][1], a[2][2], a[2][3]

     
    在二维数组中,要定位一个元素,必须给出一维下标和二维下标,就像在一个平面中确定一个点,要知道x坐标和y坐标。例如,a[3][4] 表示a数组第3行第4列的元素。
     
    二维数组在概念上是二维的,但在内存中地址是连续的,也就是说存储器单元是按一维线性排列的。那么,如何在一维存储器中存放二维数组呢?有两种方式:一种是按行排列, 即放完一行之后顺次放入第二行。另一种是按列排列, 即放完一列之后再顺次放入第二列。
     
    在C语言中,二维数组是按行排列的。也就是先存放a[0]行,再存放a[1]行,最后存放a[2]行;每行中的四个元素也是依次存放。数组a为int类型,每个元素占用4个字节,整个数组共占用4×(3×4)=48个字节。
     
    【示例】一个学习小组有5个人,每个人有三门课的考试成绩。求全组分科的平均成绩和各科总平均成绩。
    --
    Math8061598576
    C7565638777
    English9271709085
    可设一个二维数组a[5][3]存放五个人三门课的成绩。再设一个一维数组v[3]存放所求得各分科平均成绩,设变量average 为全组各科总平均成绩。编程如下:
    
        
    1. #include <stdio.h>
    2. int main(){
    3. int i, j; //二维数组下标
    4. int sum=0; //当前科目的总成绩
    5. int average; //总平均分
    6. int v[3]; //各科平均分
    7. int a[5][3]; //用来保存每个同学各科成绩的二维数组
    8. printf("Input score:\n");
    9. for(i=0; i<3; i++){
    10. for(j=0; j<5; j++){
    11. scanf("%d", &a[j][i]); //输入每个同学的各科成绩
    12. sum+=a[j][i]; //计算当前科目的总成绩
    13. }
    14. v[i]=sum/5; // 当前科目的平均分
    15. sum=0;
    16. }
    17. average =(v[0]+v[1]+v[2])/3;
    18. printf("Math: %d\nC Languag: %d\nEnglish: %d\n", v[0], v[1], v[2]);
    19. printf("Total:%d\n", average);
    20. return 0;
    21. }

    运行结果:
    Input score:
    80
    61
    59
    85
    76
    75
    65
    63
    87
    77
    92
    71
    70
    90
    85
    Math: 72
    C Languag: 73
    English: 81
    Total:75
     
    程序中首先用了一个双重循环。在内循环中依次读入某一门课程的各个学生的成绩,并把这些成绩累加起来,退出内循环后再把该累加成绩除以5送入v[i]之中,这就是该门课程的平均成绩。外循环共循环三次,分别求出三门课各自的平均成绩并存放在v数组之中。退出外循环之后,把v[0]、v[1]、v[2]相加除以3即得到各科总平均成绩。最后按题意输出各个成绩。

    ①.二维数组的初始化

     
    二维数组的初始化可以按行分段赋值,也可按行连续赋值。
     
    例如对数组a[5][3],按行分段赋值可写为:
    
        
    1. int a[5][3]={ {80,75,92}, {61,65,71}, {59,63,70}, {85,87,90}, {76,77,85} };

    按行连续赋值可写为:
    
        
    1. int a[5][3]={80, 75, 92, 61, 65, 71, 59, 63, 70, 85, 87, 90, 76, 77, 85};

    这两种赋初值的结果是完全相同的。
     
    【示例】求各科平均分和总成绩平均分。
    
        
    1. #include <stdio.h>
    2. int main(){
    3. int i, j; //二维数组下标
    4. int sum=0; //当前科目的总成绩
    5. int average; //总平均分
    6. int v[3]; //各科平均分
    7. int a[5][3]={ {80,75,92}, {61,65,71}, {59,63,70}, {85,87,90}, {76,77,85} };
    8. for(i=0; i<3; i++){
    9. for(j=0; j<5; j++){
    10. sum+=a[j][i]; //计算当前科目的总成绩
    11. }
    12. v[i]=sum/5; // 当前科目的平均分
    13. sum=0;
    14. }
    15. average =(v[0]+v[1]+v[2])/3;
    16. printf("Math: %d\nC Languag: %d\nEnglish: %d\n", v[0], v[1], v[2]);
    17. printf("Total:%d\n", average);
    18. return 0;
    19. }

    运行结果:
    Math: 72
    C Languag: 73
    English: 81
    Total:75
     
    对于二维数组初始化赋值还有以下说明
     
    1) 可以只对部分元素赋初值,未赋初值的元素自动取0值。例如:
    
        
    1. int a[3][3]={{1},{2},{3}};

    是对每一行的第一列元素赋值,未赋值的元素取0值。 赋值后各元素的值为:
    1  0  0
    2  0  0
    3  0  0
     
    
        
    1. int a [3][3]={{0,1},{0,0,2},{3}};

    赋值后的元素值为:
    0  1  0
    0  0  2
    3  0  0
     
    2) 如对全部元素赋初值,则第一维的长度可以不给出。例如:
    
        
    1. int a[3][3]={1,2,3,4,5,6,7,8,9};

    可以写为:
    
        
    1. int a[][3]={1,2,3,4,5,6,7,8,9};

     
    3) 数组是一种构造类型的数据。二维数组可以看作是由一维数组的嵌套而构成的。设一维数组的每个元素都又是一个数组,就组成了二维数组。当然,前提是各元素类型必须相同。根据这样的分析,一个二维数组也可以分解为多个一维数组。C语言允许这种分解。
     
    如二维数组a[3][4],可分解为三个一维数组,其数组名分别为:a[0]、a[1]、a[2]。
     
    对这三个一维数组不需另作说明即可使用。这三个一维数组都有4个元素,例如:一维数组a[0]的元素为a[0][0], a[0][1], a[0][2], a[0][3]。必须强调的是,a[0], a[1], a[2]不能当作下标变量使用,它们是数组名,不是一个单纯的下标变量。

    3.C语言字符数组和字符串

    用来存放字符的数组称为字符数组,例如:
    
        
    1. char c[10];

    由于char和int可以相互转换,也可以定义为:
    
        
    1. int c[10];

    但这时每个数组元素占4个字节的内存。
     
    字符数组也可以是二维或多维数组。例如:
    
        
    1. char c[5][10];

    字符数组也允许在定义时进行初始化,例如:
    
        
    1. char c[10]={'c', ' ', 'p', 'r', 'o', 'g', 'r', 'a','m'}; // c[9]未赋值,所以为默认值0

    当对全体元素赋初值时也可以省去长度说明。例如:
    
        
    1. char c[]={'c', ' ', 'p', 'r', 'o', 'g', 'r', 'a', 'm' };

    这时c数组的长度自动定为9。
     
    字符数组和普通数组一样,也是通过下标引用各个元素。
     
    【示例】输出字符数组中的元素。
    
        
    1. #include <stdio.h>
    2. int main(){
    3. int i,j;
    4. char a[][7]={
    5. {'C',' ','L','a','n','g'},
    6. {'P','r','o','g','r','a','m'},
    7. {'F','u','n','n','y'}
    8. };
    9. for(i=0; i<=2; i++){
    10. for(j=0; j<=6; j++){
    11. printf("%c", a[i][j]);
    12. }
    13. printf("\n");
    14. }
    15. return 0;
    16. }

    运行结果:
    C Lang
    Program
    Funny
     
    本例的二维字符数组由于在初始化时全部元素都赋以初值,因此一维下标的长度可以不写。

    ①.字符串和字符串结束标志

     
    在C语言中没有专门的字符串变量,没有string类型,通常用一个字符数组来存放一个字符串。
     
    前面已经教大家用puts和printf函数输出字符串,例如:
    
        
    1. puts("http://c.biancheng.net");
    2. printf("C Language");

    在C语言中,字符串总是以'\0'作为串的结束符。上面的两个字符串,编译器已经在末尾自动添加了'\0'。
    '\0'是ASCII码表中的第0个字符,用NUL表示,称为空字符。该字符既不能显示,也不是控制字符,输出该字符不会有任何效果,它在C语言中仅作为字符串的结束标志。
    字符串处理函数遇到NUL时会认为字符串已经结束,不再继续操作,例如:
    
        
    1. #include <stdio.h>
    2. int main(){
    3. puts("C Lang\0 is funny!");
    4. return 0;
    5. }

    运行结果:
    C Lang
     
    可以发现,'\0' 后面的字符都没有输出。
     
    当把字符串存入字符数组时,也应该把结束符 '\0' 存入数组,并以此作为该字符串是否结束的标志。有了'\0'标志后,就不必再用字符数组的长度来判断字符串的长度了。
     
    C语言允许用字符串的方式对数组作初始化赋值。例如:
    
        
    1. char c[]={'c', ' ','p','r','o','g','r','a','m'};

    可写为:
    
        
    1. char c[]={"C program"};

    或去掉{}写为:
    
        
    1. char c[]="C program";

     
    用字符串方式赋值比用字符逐个赋值要多占一个字节, 用于存放字符串结束标志 '\0'。上面的数组c在内存中的实际存放情况为:

     
    '\0' 是由编译器自动加上的。由于采用了 '\0' 标志,所以在用字符串赋初值时一般无须指定数组的长度, 而由编译器自行处理。

    ②.字符数组的输入输出

     
    在采用字符串方式后,字符数组的输入输出将变得简单方便。除了上述用字符串赋初值的办法外,还可用printf函数和scanf函数一次性输出输入一个字符数组中的字符串,而不必使用循环语句逐个地输入输出每个字符。
     
    【示例】使用printf输出整个字符数组。
    
        
    1. #include <stdio.h>
    2. int main(){
    3. char c[]="C Lang\nJava\nC++\nPython";
    4. printf("%s\n", c);
    5. return 0;
    6. }

    运行结果:
    C Lang
    Java
    C++
    Python
     
    在printf函数中,使用%s输出字符串。注意在输出列表中给出数组名即可。不能写为printf("%s", c[]);。
     
    【示例】使用scanf从控制台输入一个字符串,然后使用printf将其输出。
    
        
    1. #include <stdio.h>
    2. int main(){
    3. char str[100]; //必须说明长度,不能写为 char str[];
    4. printf("Input string: ");
    5. scanf("%s", str);
    6. printf("Your string is: %s\n", str);
    7. return 0;
    8. }

    运行结果:
    Input string: http://c.biancheng.net↙
    Your string is: http://c.biancheng.net
     
    由于字符数组长度为100,因此输入的字符串长度必须小于100,以留出一个字节用于存放字符串结束标志`\0`。

    ③对程序的几点说明

     
    1) 对一个字符数组,如果不作初始化赋值,则必须说明数组长度。
     
    2) 当用scanf函数输入字符串时,字符串中不能含有空格,否则将以空格作为串的结束符。
     
    例如当输入的字符串中含有空格时,运行结果为:
    Input string: c language↙
    Your string is: c
     
    可以看出,空格以后的字符都未能输出。为了避免这种情况,可多设几个字符数组分段存放含空格的串。程序可改写如下:
    
        
    1. #include <stdio.h>
    2. int main(){
    3. char str1[20], str2[20], str3[20], str4[20];
    4. printf("Input string: ");
    5. scanf("%s %s %s %s",str1, str2, str3, str4);
    6. printf("Your string: %s %s %s %s\n", str1, str2, str3, str4);
    7. return 0;
    8. }

    运行结果:
    Input string: C C++ Java Python
    Your string: C C++ Java Python
     
    3) 在《从键盘输入数据》中讲到,scanf 的各个变量前面要加取地址符&,用以获得变量的地址,例如:
    
        
    1. int a, b;
    2. scanf("%d %d", &a, &b);

    但是在本节的示例中,将字符串读入字符数组却没有使用&,例如:
    
        
    1. char str1[20], str2[20], str3[20], str4[20];
    2. scanf("%s %s %s %s",str1, str2, str3, str4);

    这是因为C语言规定,数组名就代表了该数组的地址。整个数组是一块连续的内存单元,如有字符数组char c[10],在内存可表示为:
     
    C语言还规定,数组名所代表的地址为第0个元素的地址,例如char c[10];,c就代表c[0]的地址。第0个元素的地址就是数组的起始地址,所以称为 首地址。也就是说,数组名表示数组的首地址。
     
    设数组c的首地址为0X2000,也就是说c[0]地址为0X2000,则数组名c就代表这个首地址。
     
    因为c已经表示地址,所以在c前面不能再加取地址符&,例如写作 scanf("%s",&c); 是错误的。
     
    有了首地址,有了字符串结束符'\0',就可以完整的定位一个字符串了。例如:
    
        
    1. printf("%s", c);

    printf 函数会根据数组名找到c的首地址,然后逐个输出数组中各个字符直到遇到 '\0' 为止。
    int、float、char 类型的变量表示数据本身,数据就保存在变量中;而数组名表示的是数组的首地址,数组保存在其他内存单元,数组名保存的是这块内存的首地址。后面我们会讲解指针,大家将会有更加深刻的理解。

    4.C语言字符串处理函数

    C语言提供了丰富的字符串处理函数,例如字符串的输入、输出、合并、修改、比较、转换、复制、搜索等,使用这些现成的函数可大大减轻编程的负担。
     
    用于输入输出的字符串函数,例如printf、puts、scanf、gets等,使用时应包含头文件stdio.h,使用其它字符串函数则应包含头文件string.h。

    ①.字符串输入输出函数

     
    printf、puts、scanf 前面已经介绍过了,不再赘述,这里重点讲解gets函数。
     
    gets 是 get string 的缩写,意思是获取用户从键盘输入的字符串,语法格式为:
    gets(arrayName);
    arrayName 为字符数组。从键盘获得的字符串,将保存在 arrayName 中。请看下面的例子:
    
        
    1. #include <stdio.h>
    2. int main(){
    3. char str[60];
    4. printf("Input string: ");
    5. gets(str);
    6. puts(str);
    7. return 0;
    8. }

    运行结果:
    Input string: C Java C++ Python
    C Java C++ Python
     
    可以看出当输入的字符串中含有空格时,输出仍为全部字符串。说明 gets 函数并不以空格作为字符串输入结束的标志,而只以回车作为输入结束,这与 scanf 函数是不同的。

    ②.字符串长度函数strlen

     
    strlen 是 string length 的缩写,用来获得字符串的长度。所谓长度,就是包含多少个字符(不包括字符串结束标志 '\0')。语法格式为:
    
        
    1. strlen(arrayName);

    strlen 将返回字符串的长度,它是一个整数。请看下面的例子:
    
        
    1. #include <stdio.h>
    2. #include <string.h>
    3. int main(){
    4. char str[]="C language";
    5. int len = strlen(str);
    6. printf("The lenth of the string is %d\n", len);
    7. return 0;
    8. }

    运行结果:
    The lenth of the string is 10
     
    需要说明的是,strlen 会从字符串的第 0 个字符开始计算,直到遇到字符串结束标志 '\0'。将上面代码中的 str 改为:
    
        
    1. char str[]="C \0language";

    那么输出结果就是:
    The lenth of the string is 2

    ③.字符串连接函数 strcat

     
    strcat 是 string catenate 的缩写,意思是把两个字符串拼接在一起,语法格式为:
    
        
    1. strcat(arrayName1, arrayName2);

    arrayName1、arrayName2 为需要拼接的字符串。
     
    strcat 将把 arrayName2 连接到 arrayName1 后面,并删去 arrayName1 最后的结束标志 '\0'。 这就意味着,arrayName1 的长度要足够,必须能够同时容纳 arrayName1 和 arrayName2,否则会越界。
     
    strcat 返回值为 arrayName1 的首地址。请看下面的例子:
    
        
    1. #include <stdio.h>
    2. #include <string.h>
    3. int main(){
    4. char str1[40]="My name is ";
    5. int str2[20];
    6. printf("Input your name:");
    7. gets(str2);
    8. strcat(str1,str2);
    9. puts(st1);
    10. return 0;
    11. }

    运行结果:
    Input your name:xiao p
    My name is xiao p

    ④.字符串复制函数strcpy

     
    strcpy 是 string copy 的缩写,意思是字符串复制,语法格式为:
    
        
    1. strcpy(arrayName1, arrayName2);

    strcpy 会把 arrayName2 中的字符串拷贝到 arrayName1 中,串结束标志 '\0' 也一同拷贝。arrayName 也可以是一个字符串常量,这时相当于把一个字符串赋值给一个字符数组。请看下面的例子:
    
        
    1. #include <stdio.h>
    2. #include <string.h>
    3. int main(){
    4. char str1[15], str2[]="C Language";
    5. strcpy(str1, str2);
    6. puts(str1);
    7. printf("\n");
    8. return 0;
    9. }

    运行结果:
    C Language
     
    strcat 要求 arrayName1 要有足够的长度,否则不能全部装入所拷贝的字符串。

    5.对C语言数组的总结以及实例

    数组(Array)是一系列相同类型的数据的集合,可以是一维的、二维的、多维的;最常用的是一维数组和二维数组,多维数组较少用到。

    ①.对数组的总结

     
    1) 数组的定义格式为:
    
        
    1. type arrayName[length]

    type 为数据类型,arrayName 为数组名,length 为数组长度。
    需要注意的是:
    1. length 必须是一个数值常量,不能是变量,因为代码编译期间编译器要明确知道数组元素的个数,而变量的值是不确定的。
    2. 数组中的数据保存在一个内存区域A,而数组名保存另外一个内存区域B,数组名中包含的是A的首地址。
     
    2) 访问数组中某个元素的格式为:

    index 为数组下标。
    注意 index 的值不能大于 length,否则会发生数组越界,出现意想不到的错误。
     
    3) 可以对数组中的单个元素赋值,也可以整体赋值,例如:
    
        
    1. // 对单个元素赋值
    2. int a[3];
    3. a[0] = 3;
    4. a[1] = 100;
    5. a[2] = 34;
    6. // 整体赋值(不指明数组长度)
    7. float b[] = { 23.3, 100.00, 10, 0.34 };
    8. // 整体赋值(指明数组长度)
    9. int m[10] = { 100, 30, 234 };
    10. // 字符数组赋值
    11. char str[] = "http://c.biancheng.net";

    对数组整体赋值时,可以不指名数组的长度。未赋值的元素为默认值。

    ②.数组应用举例

     
    求一个整型数组中的最大值和最小值。
    
        
    1. #include <stdio.h>
    2. int main(){
    3. int a[10] = {2, 123, 45, 100, 575, 240, 799, 710, 10, 90};
    4. int max=a[0], min=a[0]; //最大值和最小值
    5. int i; //循环增量
    6. int len = sizeof(a) / sizeof(int); //计算数组长度
    7. for(i=1; i<len; i++){
    8. if(a[i] > max){
    9. max = a[i];
    10. }
    11. if(a[i] < min){
    12. min = a[i];
    13. }
    14. }
    15. printf("The max is %d, The min is %d\n", max, min);
    16. return 0;
    17. }

    运行结果:
    The max is 799, The min is 2
     
    思考一下,max 和 min 的初值为什么要设为 a[0] 呢,默认不可以吗?
     

    ③.关于排序和查找

     
    学完了数组,有两个重要的知识点要求大家掌握,那就是排序(Sort)和查找(Search),比如:
    1. 给你 10 个打乱顺序的整数,要能够按照从小到大或者从大到小的顺序输出;
    2. 给定一个字符串 str1,以及一个子串 str2,要能够判断 str2 是否在 str1 中。
     






    转载于:https://www.cnblogs.com/caizheng/p/6155215.html

    展开全文
  • 数组的优点在于它是连续的,所以查找数据速度很快。但这也是它的一个缺点。正因为它是连续的,所以当插入一个元素时,插入点后所有的元素全部都要向后移;而删除一个元素时,删除点后所有的元素全部都要向前移。插入...

    数组不擅长插入(添加)和删除元素。数组的优点在于它是连续的,所以查找数据速度很快。但这也是它的一个缺点。正因为它是连续的,所以当插入一个元素时,插入点后所有的元素全部都要向后移;而删除一个元素时,删除点后所有的元素全部都要向前移。

    插入算法

    # include

    int main(void)

    {

    int a[23] = {1, 5, 66, 8, 55, 9, 1, 32, 5, 65, 4, 8, 5, 15, 64, 156, 1564, 15, 1, 8, 9, 7, 215};

    int b[24]; //用来存放插入数字后的新数组, 因为又插入了一个值, 所以长度为24

    int Index; //插入值的下标, Index是“下标”的英文单词

    int num; //插入的值

    int i; //循环变量

    printf("请输入插入值的下标:");

    scanf("%d", &Index);

    printf("请输入插入的数值:");

    scanf("%d", &num);

    for (i=0; i<24; ++i)

    {

    if (i < Index)

    {

    b[i] = a[i]; /*循环变量i小于插入值位置Index时, 每一个元素所放的位置不变*/

    }

    else if (i == Index)

    {

    b[i] = num; //i等于Index时, 将插入值赋给数组b

    }

    else

    {

    b[i] = a[i-1]; /*因为插入了一个新的元素, 所以插入位置后的每一个元素所存放的位置都要向后移一位*/

    }

    }

    for (i=0; i<24; ++i)

    {

    printf("%d\x20", b[i]);

    }

    printf("\n");

    return 0;

    }

    输出结果是:

    请输入插入值的下标:10请输入插入的数值:22

    1 5 66 8 55 9 1 32 5 65 22 4 8 5 15 64 156 1564 15 1 8 9 7 215

    删除算法

    # include

    int main(void)

    {

    int a[23] = {1, 5, 66, 8, 55, 9, 1, 32, 5, 65, 4, 8, 5, 15, 64, 156, 1564, 15, 1, 8, 9, 7, 215};

    int b[22]; /*用来存放删除数字后的新数组, 因为删除了一个值, 所以长度为22*/

    int Index; //要删除的值的下标

    int i; //循环变量

    printf("请输入要删除的值的下标:");

    scanf("%d", &Index);

    for (i=0; i<23; ++i)

    {

    if (i < Index)

    {

    b[i] = a[i]; /*循环变量i小于插入值位置Index时, 每一个元素所存放的位置不变*/

    }

    else

    {

    b[i] = a[i+1]; /*删除值后面的元素都往前移一位, 要删除的值直接被覆盖*/

    }

    }

    for (i=0; i<22; ++i)

    {

    printf("%d\x20", b[i]); // \x20表示空格

    }

    printf("\n");

    return 0;

    }

    输出结果是:

    请输入要删除的值的下标:5

    1 5 66 8 55 1 32 5 65 4 8 5 15 64 156 1564 15 1 8 9 7 215

    实例

    37, 49, 51, 61。设计程序对数组中的数据实现一次删除及插入操作:

    利用getchar()函数接收键盘输入:

    ● 当输入字符'D'时,接收键盘输入一个数组中存在的整数n,并对数组中存在的该整数进行删除,要求删除后的数组各元素仍按照从小到大的顺序排列。

    要求:不使用冒泡法或选择法实现删除数据后的排序操作。

    ● 当输入字符'I'时,接收键盘输入一个数组中不存在的整数m,并将该整数m插入到数组中,要求插入后的数组各元素仍按照从小到大的顺序排列。

    要求:不使用冒泡法或选择法实现插入数据后的排序操作。

    样例输入和输出:

    数组排序后的结果为:5, 9, 11, 16, 24, 34, 37, 49, 51, 61

    请输入需要进行的操作(插入'I',删除'D'):D

    请输入需要删除的整数:9

    删除后的数组为:5, 11, 16, 24, 34, 37, 49, 51, 61

    请输入需要进行的操作(插入'I',删除'D'):I

    请输入需要插入的整数:13

    插入后的数组为:5, 11, 13, 16, 24, 34, 37, 49, 51, 61

    #include

    int main()

    {

    int a[10] = { 5, 9, 11, 16, 24, 34, 37, 49, 51, 61 };

    int i = 0,n=0,k=0;

    char get;

    for (i = 0; i < 10; i++)

    printf("%3d", a[i]);

    printf("\n");

    printf("请输入需要进行的操作(插入‘I',删除‘D')\n");

    get = getchar();

    getchar();

    if (get=='D')

    {

    printf("请输入要删除的整数:\n");

    n = getchar();

    getchar();

    n -= 48;

    for (i = 0; i < 10; i++)

    {

    if (a[i]==n)

    {

    for (; i < 10; i++)

    {

    a[i] = a[i + 1];

    }

    a[9] = 0;

    break;

    }

    }

    for (i = 0; i < 9; i++)

    printf("%3d", a[i]);

    printf("\n");

    }

    printf("请输入需要进行的操作(插入‘I',删除‘D')\n");

    get = getchar();

    getchar();

    if (get='I')

    {

    printf("请输入要插入的整数:\n");

    scanf_s("%d", &n); //注意陷阱,不能用getchar(),因为13其实是两个字符,回车之后,n只吸收了‘1',所以只能用scanf_s().

    for (i = 0; i < 10; i++)

    {

    if (a[i] < n&&n < a[i + 1])

    {

    k = i;

    for (i = 8; i > k; i--)

    {

    a[i+1] = a[i];

    }

    a[k+1] = n;

    break;

    }

    }

    for (i = 0; i < 10; i++)

    printf("%3d", a[i]);

    }

    return 0;

    }

    到此这篇关于C语言数组添加和删除元素的实现的文章就介绍到这了,更多相关C语言数组添加和删除元素内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    展开全文
  • 快速导读:Q1:C语言__数组中的查找某一元素,并显示其下标号!急!求高手!二分法.#include"stdio.h"int search(int a[],int x){int find,low,highwWW.eCAIBE‖i.com,mid;find=0;low=1;high=10;while(!find&&...

    快速导读:

    Q1:C语言__数组中的查找某一元素,并显示其下标号!急!求高手!

    二分法.

    #include"stdio.h"

    int search(int a[],int x)

    {

    int find,low,highwWW.eCAIBE‖i.com,mid;

    find=0;low=1;high=10;

    while(!find&&low<=high)

    {

    mid=(low+high)/2;

    if(x==a[mid])find=mid;

    else if(x else low=mid+1;

    }

    return find;

    }

    void main()

    {

    int i,x,a[11];

    printf("请按升序输入10个数:");

    for(i=1;i<11;i++)

    scanf("%d",&a[i]);

    printf("请输入待查找的数x:");

    scanf("%d",&x);

    printf("数%d在数组a中的位置为%d\n",x,search(a,x));

    }

    Q2:C语言中在整数数组中,查找某个元素,如果查找成功,返回其下标;否则,返回-1

    #include#includeintmain()

    {

    intlen,data,ret=-1,input;

    int*arr;

    scanf("%d%d",&len,&data);

    arr=(int*)malloc(len*sizeof(int));

    for(inti=0;i{

    scanf("%d",&input);

    arr[i]=input;

    }

    for(intj=0;jif(arr[j]==data)

    {

    ret=j;

    break;

    }

    }

    printf("

    %d",ret);

    }

    Q3:C语言题目:在数组中查找指定元素

    C语言程序:1234567891011121314151617181920212223242526272829303132333435363738394041#include#defineN11intsearch(intlist[],intn,intx){inti;for(i=0;i运行测试:

    Q4:C语言如何检查一个数组中元素的个数

    对于字符数组str[N],判断方法有以下三种:

    第一种:用库函数strlen

    len = strlen(str); // 数组长度

    第二种:利用计数器

    int i=0;

    while(str[i++] != \0); // 数组str的长度为i

    第三种:利用sizeof函数

    len = sizeof(str)/sizeof(str[0]); // 数组长度对于其他类型的数组,都可以用字符数组的第三种方法,第三种方法是通用的。

    Q5:请用C语言:求一个数组中所有元素的和,在主函数中检验

    如果说,数组中保存的是数字,那简单,全部加起来。

    如果说,数组中保存的是字符串型数字比如“100”,那你需要把字符串转成数字再相加。

    或者还可以把所有字符拼接在一起。

    eef6eecb5fb243c8285d3669da23fca2.png1234567891011121314151617181920212223242526#include#include#includeintmain(){intnums[10]={100,200,300,400,500,600,700,800,900,1000},i,sum=0;charnums2str[10][5]={"100","200","300","400","500","600","700","800","900","1000"},str[41];printf("数字型和字符串型的两个数组元素分别为:\n");printf("100,200,300,400,500,600,700,800,900,1000\n");printf("\"100\",\"200\",\"300\",\"400\",\"500\",\"600\",\"700\",\"800\",\"900\",\"1000\"\n");str[0]=0;for(i=0;i<10;i++)sum=sum+nums[i];printf("纯数字的数组元素相加,结果:%d\n",sum);sum=0;for(i=0;i<10;i++)sum=sum+(int)atof(nums2str[i]);printf("字符串型数字的数组元素转数字相加,结果:%d\n",sum);for(i=0;i<10;i++)strcat(str,nums2str[i]);printf("字符串型数字的数组元素拼接到一起,结果:%s\n",str);return0;}

    Q6:如何用c语言编写查询数组中的元素

    对于数组的查询,其实就是对数组中数据做一个遍历。

    最常用的方法就是通过循环对数组中的元素逐个取值,并与参考值(要查询的值)做比对,并处理结果。

    下面是一个简单的对一维数组进行查询的样例。

    函数功能:对输入的数组元素进行查询,打印符合查询值的元素位置,并返回查询到的元素总数。

    函数名:array_query

    函数声明: int array_query(int *a, int n, int v);

    参数介绍:

    a: 输入的数组,类型为整型指针,表示整型数组。可以根据实际需要进行调整。

    n:数组中现有元素的个数。

    v:要查询的元素值。

    返回值:

    整型,返回查询到的元素个数。如果出错返回-1。

    实现代码:intarray_query(int*a,intn,intv)

    {

    inti,ret;

    if(a==NULLn<=0)return-1;//出错处理

    for(ret=i=0;i{

    if(a[i]==n)

    {

    printf("%d\n",i);//找到元素,打印下标,并累计统计值

    ret++;

    }

    }

    returnret;//返回总数。

    }

    声明:该文观点仅代表作者本人,易采贝采用此文仅在于向读者提供更多信息,并不代表赞同其立场。

    展开全文
  • C语言数组

    千次阅读 2016-05-15 07:31:02
    1.C语言数组的概念 在《printf函数的高级用法》一节中我们举了一个例子,是输出一个 4×4 的整数矩阵,代码如下: #include #include int main(){ int a1=20, a2=345, a3=700, a4=22; int b1=56720, b2=9999...

    1.C语言数组的概念

    在《printf函数的高级用法》一节中我们举了一个例子,是输出一个 4×4 的整数矩阵,代码如下:

       
    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. int main()
    4. {
    5. int a1=20, a2=345, a3=700, a4=22;
    6. int b1=56720, b2=9999, b3=20098, b4=2;
    7. int c1=233, c2=205, c3=1, c4=6666;
    8. int d1=34, d2=0, d3=23, d4=23006783;
    9. printf("%-9d %-9d %-9d %-9d\n", a1, a2, a3, a4);
    10. printf("%-9d %-9d %-9d %-9d\n", b1, b2, b3, b4);
    11. printf("%-9d %-9d %-9d %-9d\n", c1, c2, c3, c4);
    12. printf("%-9d %-9d %-9d %-9d\n", d1, d2, d3, d4);
    13. system("pause");
    14. return 0;
    15. }
    运行结果:
    20        345       700       22
    56720     9999      20098     2
    233       205       1         6666
    34        0         23        23006783
    矩阵共有 16 个整数,我们为每个整数定义了一个变量,也就是 16 个变量。那么,为了减少变量的数量,让开发更有效率,能不能为多个数据定义一个变量呢?比如,把每一行的整数放在一个变量里面,或者把 16 个整数全部都放在一个变量里面。

    我们知道,要想把数据放入内存,必须先要分配内存空间。放入4个整数,就得分配4个 int 类型的内存空间:
    int a[4];
    
    这样,就在内存中分配了4个 int 类型的内存空间,共 4×4=16 个字节,并为它们起了一个名字,叫 a

    我们把这样的一组数据的集合称为 数组(Array) ,它所包含的每一个数据叫做数组 元素(Element) ,所包含的数据的个数称为数组 长度(Length) ,例如 int a[4]; 就定义了一个长度为4的整型数组,名字是 a

    数组中的每个元素都有一个序号,这个序号从0开始,而不是从我们熟悉的1开始,称为 下标(Index) 。使用数组元素时,指明下标即可,形式为:
    arrayName[index]
    arrayName 为数组名称,index 为下标。例如,a[0] 表示第0个元素,a[3] 表示第3个元素。

    接下来我们就把第一行的4个整数放入数组:
    a[0]=20;
    a[1]=345;
    a[2]=700;
    a[3]=22;
    这里的0、1、2、3就是数组下标,a[0]、a[1]、a[2]、a[3] 就是数组元素。

    我们来总结一下数组的定义方式:
    dataType  arrayName[length];
    dataType 为数据类型,arrayName 为数组名称,length 为数组长度。例如:
    float m[12];
    char ch[9];

    注意:
    1) 数组中每个元素的数据类型必须相同,对于 int a[4]; ,每个元素都必须为 int。

    2) 数组下标必须是整数,取值范围为 0 ≤ index < length。

    3) 数组是一个整体,它的内存是连续的,下面是 int a[4]; 的内存示意图:

    数组的初始化

    上面的代码是先定义数组再给数组赋值,我们也可以在定义数组的同时赋值:
    int a[4] = {20, 345, 700, 22};
    { } 中的值即为各元素的初值,各值之间用 , 间隔。

    对数组赋初值需要注意以下几点:
    1) 可以只给部分元素赋初值。当 { } 中值的个数少于元素个数时,只给前面部分元素赋值。例如:
    int a[10]={12, 19, 22 , 993, 344};
    表示只给 a[0]~a[4] 5个元素赋值,而后面5个元素自动赋0值。

    当赋值的元素少于数组总体元素的时候,剩余的元素自动初始化为 0:对于short、int、long,就是整数0;对于char,就是字符 '\0';对于float、double,就是小数0.0。

    我们可以通过下面的形式将数组的所有元素初始化为 0:
    int a[10] = {0};
    char c[10] = {0};
    float f[10] = {0};
    由于剩余的元素会自动初始化为0,所以只需要给第0个元素赋0值即可。

    示例:输出数组元素。
       
    1. #include <stdio.h>
    2. int main()
    3. {
    4. int a[6] = {299, 34, 92, 100};
    5. int b[6], i;
    6. //从控制台输入数据为每个元素赋值
    7. for(i=0; i<6; i++){
    8. scanf("%d", &b[i]);
    9. }
    10. //输出数组元素
    11. for(i=0; i<6; i++){
    12. printf("%d ", a[i]);
    13. }
    14. putchar('\n');
    15. for(i=0; i<6; i++){
    16. printf("%d ", b[i]);
    17. }
    18. putchar('\n');
    19. return 0;
    20. }
    运行结果:
    90 100 33 22 568 10
    299  34  92  100  0  0
    90  100  33  22  568  10

    2) 只能给元素逐个赋值,不能给数组整体赋值。例如给十个元素全部赋1值,只能写为:
    int a[10]={1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
    而不能写为:
    int a[10]=1;

    3) 如给全部元素赋值,那么在数组定义时可以不给出数组的长度。例如:
    int a[]={1,2,3,4,5};
    等价于
    int a[5]={1,2,3,4,5};

    最后,我们借助数组来输出一个 4×4 的矩阵:
       
    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. int main()
    4. {
    5. int a[4] = {20, 345, 700, 22};
    6. int b[4] = {56720, 9999, 20098, 2};
    7. int c[4] = {233, 205, 1, 6666};
    8. int d[4] = {34, 0, 23, 23006783};
    9. printf("%-9d %-9d %-9d %-9d\n", a[0], a[1], a[2], a[3]);
    10. printf("%-9d %-9d %-9d %-9d\n", b[0], b[1], b[2], b[3]);
    11. printf("%-9d %-9d %-9d %-9d\n", c[0], c[1], c[2], c[3]);
    12. printf("%-9d %-9d %-9d %-9d\n", d[0], d[1], d[2], d[3]);
    13. system("pause");
    14. return 0;
    15. }
    2.C语言二维数组

    上节讲解的数组可以看作是一行连续的数据,只有一个下标,称为一维数组。在实际问题中有很多量是二维的或多维的,因此C语言允许构造多维数组。多维数组元素有多个下标,以确定它在数组中的位置。本节只介绍二维数组,多维数组可由二维数组类推而得到。

    二维数组的定义

    二维数组定义的一般形式是:
    dataType arrayName[length1][length2];
    其中,dataType 为数据类型,arrayName 为数组名,length1 为第一维下标的长度,length2 为第二维下标的长度。例如:
    int a[3][4];
    定义了一个3行4列的数组,共有3×4=12个元素,数组名为a,即:
    a[0][0], a[0][1], a[0][2], a[0][3]
    a[1][0], a[1][1], a[1][2], a[1][3]
    a[2][0], a[2][1], a[2][2], a[2][3]

    在二维数组中,要定位一个元素,必须给出一维下标和二维下标,就像在一个平面中确定一个点,要知道x坐标和y坐标。例如,a[3][4] 表示a数组第3行第4列的元素。

    二维数组在概念上是二维的,但在内存中地址是连续的,也就是说存储器单元是按一维线性排列的。那么,如何在一维存储器中存放二维数组呢?有两种方式:一种是按行排列, 即放完一行之后顺次放入第二行。另一种是按列排列, 即放完一列之后再顺次放入第二列。

    在C语言中,二维数组是按行排列的。也就是先存放a[0]行,再存放a[1]行,最后存放a[2]行;每行中的四个元素也是依次存放。数组a为int类型,每个元素占用4个字节,整个数组共占用4×(3×4)=48个字节。

    【示例】一个学习小组有5个人,每个人有三门课的考试成绩。求全组分科的平均成绩和各科总平均成绩。
    --
    Math8061598576
    C7565638777
    English9271709085

    可设一个二维数组a[5][3]存放五个人三门课的成绩。再设一个一维数组v[3]存放所求得各分科平均成绩,设变量average 为全组各科总平均成绩。编程如下:
       
    1. #include <stdio.h>
    2. int main(){
    3. int i, j; //二维数组下标
    4. int sum=0; //当前科目的总成绩
    5. int average; //总平均分
    6. int v[3]; //各科平均分
    7. int a[5][3]; //用来保存每个同学各科成绩的二维数组
    8. printf("Input score:\n");
    9. for(i=0; i<3; i++){
    10. for(j=0; j<5; j++){
    11. scanf("%d", &a[j][i]); //输入每个同学的各科成绩
    12. sum+=a[j][i]; //计算当前科目的总成绩
    13. }
    14. v[i]=sum/5; // 当前科目的平均分
    15. sum=0;
    16. }
    17. average =(v[0]+v[1]+v[2])/3;
    18. printf("Math: %d\nC Languag: %d\nEnglish: %d\n", v[0], v[1], v[2]);
    19. printf("Total:%d\n", average);
    20. return 0;
    21. }
    运行结果:
    Input score:
    80 61 59 85 76 75 65 63 87 77 92 71 70 90 85↙
    Math: 72
    C Languag: 73
    English: 81
    Total:75

    程序中首先用了一个双重循环。在内循环中依次读入某一门课程的各个学生的成绩,并把这些成绩累加起来,退出内循环后再把该累加成绩除以5送入v[i]之中,这就是该门课程的平均成绩。外循环共循环三次,分别求出三门课各自的平均成绩并存放在v数组之中。退出外循环之后,把v[0]、v[1]、v[2]相加除以3即得到各科总平均成绩。最后按题意输出各个成绩。

    二维数组的初始化

    二维数组的初始化可以按行分段赋值,也可按行连续赋值。

    例如对数组a[5][3],按行分段赋值可写为:
    int a[5][3]={ {80,75,92}, {61,65,71}, {59,63,70}, {85,87,90}, {76,77,85} };
    按行连续赋值可写为:
    int a[5][3]={80, 75, 92, 61, 65, 71, 59, 63, 70, 85, 87, 90, 76, 77, 85};
    这两种赋初值的结果是完全相同的。

    【示例】求各科平均分和总成绩平均分。
       
    1. #include <stdio.h>
    2. int main(){
    3.     int i, j;  //二维数组下标
    4.     int sum=0;  //当前科目的总成绩
    5.     int average;  //总平均分
    6.     int v[3];  //各科平均分
    7.     int a[5][3]={ {80,75,92}, {61,65,71}, {59,63,70}, {85,87,90}, {76,77,85} };
    8.     for(i=0; i<3; i++){
    9.         for(j=0; j<5; j++){
    10.             sum+=a[j][i];  //计算当前科目的总成绩
    11.         }
    12.         v[i]=sum/5;  // 当前科目的平均分
    13.         sum=0;
    14.     }
    15.     average =(v[0]+v[1]+v[2])/3;
    16.     printf("Math: %d\nC Languag: %d\nEnglish: %d\n", v[0], v[1], v[2]);
    17.     printf("Total:%d\n", average);
    18.     return 0;
    19. }
    运行结果:
    Math: 72
    C Languag: 73
    English: 81
    Total:75

    对于二维数组初始化赋值还有以下说明

    1) 可以只对部分元素赋初值,未赋初值的元素自动取0值。例如:
    int a[3][3]={{1},{2},{3}};
    是对每一行的第一列元素赋值,未赋值的元素取0值。 赋值后各元素的值为:
    1  0  0
    2  0  0
    3  0  0

    int a [3][3]={{0,1},{0,0,2},{3}};
    赋值后的元素值为:
    0  1  0
    0  0  2
    3  0  0

    2) 如对全部元素赋初值,则第一维的长度可以不给出。例如:
    int a[3][3]={1,2,3,4,5,6,7,8,9};
    可以写为:
    int a[][3]={1,2,3,4,5,6,7,8,9};

    3) 数组是一种构造类型的数据。二维数组可以看作是由一维数组的嵌套而构成的。设一维数组的每个元素都又是一个数组,就组成了二维数组。当然,前提是各元素类型必须相同。根据这样的分析,一个二维数组也可以分解为多个一维数组。C语言允许这种分解。

    如二维数组a[3][4],可分解为三个一维数组,其数组名分别为:a[0]、a[1]、a[2]。

    对这三个一维数组不需另作说明即可使用。这三个一维数组都有4个元素,例如:一维数组a[0]的元素为a[0][0], a[0][1], a[0][2], a[0][3]。必须强调的是,a[0], a[1], a[2]不能当作下标变量使用,它们是数组名,不是一个单纯的下标变量。


    3.C语言数组元素的查询

    在实际开发中,经常需要查询数组中的元素。例如,学校为每位同学分配了一个唯一的编号,现在有一个数组,保存了实验班所有同学的编号信息,如果有家长想知道他的孩子是否进入了实验班,只要提供孩子的编号就可以,如果编号和数组中的某个元素相等,就进入了实验班,否则就没进入。

    不幸的是,C语言标准库没有提供与数组查询相关的函数,所以我们只能自己编写代码。

    对无序数组的查询

    所谓无序数组,就是数组元素的排列没有规律。无序数组元素查询的思路也很简单,就是用循环遍历数组中的每个元素,把要查询的值挨个比较一遍。请看下面的代码:
       
    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. int main(){
    4. int nums[10] = {1, 10, 6, 296, 177, 23, 0, 100, 34, 999};
    5. int i, num, subscript = -1;
    6. printf("Please input an integer: ");
    7. scanf("%d", &num);
    8. for(i=0; i<10; i++){
    9. if(nums[i] == num){
    10. subscript = i;
    11. break;
    12. }
    13. }
    14. if(subscript<0){
    15. printf("%d isn't in the array.\n", num);
    16. }else{
    17. printf("%d is in the array, and it's subscript is %d.\n", num, subscript);
    18. }
    19. system("pause");
    20. return 0;
    21. }
    运行结果:

    Please input an integer: 100
    100 is  in the array, and it's subscript is 7.

    或者

    Please input an integer: 28
    28 isn't  in the array.

    这段代码的作用是让用户输入一个数字,判断该数字是否在数组中,如果在,就打印出下标。

    第10~15行代码是关键,它会遍历数组中的每个元素,和用户输入的数字进行比较,如果相等就获取它的下标并跳出循环。

    注意:数组下标的取值范围是非负数,当 subscript >= 0 时,该数字在数组中,当 subscript < 0 时,该数字不在数组中,所以在定义 subscript 变量时,必须将其初始化为一个负数。

    对有序数组的查询

    查询无序数组需要遍历数组中的所有元素,而查询有序数组只需要遍历其中一部分元素。例如有一个长度为10的整型数组,它所包含的元素按照从小到大的顺序(升序)排列,假设比较到第4个元素时发现它的值大于输入的数字,那么剩下的5个元素就没必要再比较了,肯定也大于输入的数字,这样就减少了循环的次数,提高了执行效率。

    请看下面的代码:
       
    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. int main(){
    4. int nums[10] = {0, 1, 6, 10, 23, 34, 100, 177, 296, 999};
    5. int i, num, subscript = -1;
    6. printf("Please input an integer: ");
    7. scanf("%d", &num);
    8. for(i=0; i<10; i++){
    9. if(nums[i] >= num){
    10. if(nums[i] == num){
    11. subscript = i;
    12. }
    13. break;
    14. }
    15. }
    16. if(subscript<0){
    17. printf("%d isn't in the array.\n", num);
    18. }else{
    19. printf("%d is in the array, and it's subscript is %d.\n", num, subscript);
    20. }
    21. system("pause");
    22. return 0;
    23. }
    注意第11行代码,只有当 nums[i] >= num 成立时才进行处理,否则继续循环。nums[i] >= num 有两重含义:
    • 如果 nums[i] == num,则 num 在数组中,那么就需要给 subscript 赋值,记录当前元素的下标;
    • 如果 nums[i] > num,则 nums 不在数组中。

    无论哪种情况,都没有必要再继续循环下去了,所以一旦满足 nums[i] >= num,就应该使用 break 跳出循环。


    4.C语言字符数组和字符串

    用来存放字符的数组称为字符数组,例如:

       
    1. char a[10]; //一维字符数组
    2. char b[5][10]; //二维字符数组
    3. char c[20]={'c', ' ', 'p', 'r', 'o', 'g', 'r', 'a','m'}; // 给部分数组元素赋值
    4. char d[]={'c', ' ', 'p', 'r', 'o', 'g', 'r', 'a', 'm' }; //对全体元素赋值时可以省去长度
    字符数组实际上是一系列字符的集合,也就是 字符串(String) 。在C语言中,没有专门的字符串变量,没有string类型,通常就用一个字符数组来存放一个字符串。

    C语言规定,可以将字符串直接赋值给字符数组,例如:
       
    1. char str[30] = {"c.biancheng.net"};
    2. char str[30] = "c.biancheng.net"; //这种形式更加简洁,实际开发中常用
    数组第0个元素为 'c',第1个元素为 '.',第2个元素为 'b',后面的元素以此类推。也可以不指定数组长度,例如:
       
    1. char str[] = {"c.biancheng.net"};
    2. char str[] = "c.biancheng.net"; //这种形式更加简洁,实际开发中常用

    在C语言中,字符串总是以'\0'作为串的结束符。 上面的两个字符串,编译器已经在末尾自动添加了 '\0'
    '\0'是ASCII码表中的第0个字符,用 NUL表示,称为空字符。该字符既不能显示,也不是控制字符,输出该字符不会有任何效果,它在C语言中仅作为字符串的结束标志。
    puts 和 printf 在输出字符串时会逐个扫描字符,直到遇见 '\0' 才结束输出。 请看下面的例子:
       
    1. #include <stdio.h>
    2. int main(){
    3. int i;
    4. char str1[30] = "http://c.biancheng.net";
    5. char str2[] = "C Language";
    6. char str3[30] = "You are a good\0 boy!";
    7. printf("str1: %s\n", str1);
    8. printf("str2: %s\n", str2);
    9. printf("str3: %s\n", str3);
    10. return 0;
    11. }
    运行结果:
    str1: http://c.biancheng.net
    str2: C Language
    str3: You are a good

    str1 和 str2 很好理解,编译器会在字符串最后自动添加 '\0',并且数组足够大,所以会输出整个字符串。对于 str3,由于字符串中间存在 '\0',printf() 扫描到这里就认为字符串结束了,所以不会输出后面的内容。

    需要注意的是,用字符串给字符数组赋值时由于要添加结束符 '\0',数组的长度要比字符串的长度(字符串长度不包括 '\0')大1。例如:
    char str[] = "C program";
    该数组在内存中的实际存放情况为:

    字符串长度为 9,数组长度为 10。


    5.C语言字符串处理函数

    C语言提供了丰富的字符串处理函数,例如字符串的输入、输出、合并、修改、比较、转换、复制、搜索等,使用这些现成的函数可大大减轻编程的负担。

    用于输入输出的字符串函数,例如printfputsscanfgets等,使用时应包含头文件stdio.h,使用其它字符串函数则应包含头文件string.h

    字符串长度函数strlen

    strlen 是 string length 的缩写,用来获得字符串的长度。所谓长度,就是包含多少个字符(不包括字符串结束标志 '\0')。语法格式为:
    strlen(arrayName);
    strlen 将返回字符串的长度,它是一个整数。请看下面的例子:
       
    1. #include <stdio.h>
    2. #include <string.h>
    3. int main(){
    4. char str[]="C language";
    5. int len = strlen(str);
    6. printf("The lenth of the string is %d\n", len);
    7. return 0;
    8. }
    运行结果:
    The lenth of the string is 10

    需要说明的是,strlen 会从字符串的第 0 个字符开始计算,直到遇到字符串结束标志 '\0'。将上面代码中的 str 改为:
    char str[]="C \0language";
    那么输出结果就是:
    The lenth of the string is 2

    字符串连接函数 strcat

    strcat 是 string catenate 的缩写,意思是把两个字符串拼接在一起,语法格式为:
    strcat(arrayName1, arrayName2);
    arrayName1、arrayName2 为需要拼接的字符串。

    strcat 将把 arrayName2 连接到 arrayName1 后面,并删去 arrayName1 最后的结束标志 '\0'。 这就意味着,arrayName1 的长度要足够,必须能够同时容纳 arrayName1 和 arrayName2,否则会越界。

    strcat 返回值为 arrayName1 的首地址。请看下面的例子:
       
    1. #include <stdio.h>
    2. #include <string.h>
    3. int main(){
    4. char str1[40]="My name is ";
    5. char str2[20];
    6. printf("Input your name:");
    7. gets(str2);
    8. strcat(str1,str2);
    9. puts(str1);
    10. return 0;
    11. }
    运行结果:
    Input your name:xiao p
    My name is xiao p

    字符串复制函数strcpy

    strcpy 是 string copy 的缩写,意思是字符串复制,语法格式为:
    strcpy(arrayName1, arrayName2);
    strcpy 会把 arrayName2 中的字符串拷贝到 arrayName1 中,串结束标志 '\0' 也一同拷贝。请看下面的例子:
       
    1. #include <stdio.h>
    2. #include <string.h>
    3. int main(){
    4. char str1[15], str2[]="C Language";
    5. strcpy(str1, str2);
    6. puts(str1);
    7. printf("\n");
    8. return 0;
    9. }
    运行结果:
    C Language

    strcat 要求 arrayName1 要有足够的长度,否则不能全部装入所拷贝的字符串。

    字符串比较函数strcmp

    strcmp 是 string compare 的缩写,意思是字符串比较,语法格式为:
    strcmp(arrayName1, arrayName2);
    arrayName1 和 arrayName2 是需要比较的两个字符串。

    字符本身没有大小之分,strcmp() 是以各个字符在ASCII 码表上对应的数值进行比较的。strcmp() 首先将 arrayName1 中第0个字符的 ASCII 码值减去 arrayName2 中第0个字符的 ASCII 码值,若差值为 0,则说明两个字符相同,再继续比较下个字符,若差值不为 0 则将差值返回。例如字符串"Ac"和"ba"比较则会返回字符"A"(65)和'b'(98)的差值(-33)。

    返回值:若 arrayName1 和 arrayName2 相同,则返回0;若 arrayName1 大于 arrayName2,则返回大于 0 的值;若 arrayName1 小于 arrayName2,则返回小于0 的值。

    【示例】对4组字符串进行比较。
       
    1. #include <string.h>
    2. main(){
    3. char *a = "aBcDeF";
    4. char *b = "AbCdEf";
    5. char *c = "aacdef";
    6. char *d = "aBcDeF";
    7. printf("strcmp(a, b) : %d\n", strcmp(a, b));
    8. printf("strcmp(a, c) : %d\n", strcmp(a, c));
    9. printf("strcmp(a, d) : %d\n", strcmp(a, d));
    10. }
    运行结果:
    strcmp(a, b) : 32
    strcmp(a, c) :-31
    strcmp(a, d) : 0


    6.C语言字符串的输入输出

    字符串的输出

    在C语言中,输出字符串的函数有两个:
    • puts():直接输出字符串,并且只能输出字符串。
    • printf():通过格式控制符 %s 输出字符串。除了字符串,printf() 还能输出其他类型的数据。

    这两个函数前面已经讲过了,这里不妨再演示一下,请看下面的代码:
       
    1. #include <stdio.h>
    2. int main(){
    3. int i;
    4. char str[] = "http://c.biancheng.net";
    5. printf("%s\n", str); //通过变量输出
    6. printf("%s\n", "http://c.biancheng.net"); //直接输出
    7. puts(str); //通过变量输出
    8. puts("http://c.biancheng.net"); //直接输出
    9. return 0;
    10. }
    运行结果:
    http://c.biancheng.net
    http://c.biancheng.net
    http://c.biancheng.net
    http://c.biancheng.net

    在 printf() 函数中使用 %s 输出字符串时,在变量列表中给出数组名即可,不能写为 printf("%s", str[]);

    字符串的输入

    在C语言中,输入字符串的函数有两个:
    • scanf():通过格式控制符 %s 输入字符串。除了字符串,scanf() 还能输入其他类型的数据。
    • gets():直接输入字符串,并且只能输入字符串。

    1) 使用 scanf() 读取字符串

    请先看下面的例子:
       
    1. #include <stdio.h>
    2. int main(){
    3. char str1[30], str2[30];
    4. printf("Input str1: ");
    5. scanf("%s", str1);
    6. printf("Input str2: ");
    7. scanf("%s", str2);
    8. printf("str1: %s\nstr2: %s\n", str1, str2);
    9. return 0;
    10. }
    运行结果:
    Input str1: c.biancheng.net↙
    Input str2: Java Python C-Sharp↙
    str1: c.biancheng.net
    str2: Java

    由于字符数组长度为30,因此输入的字符串长度必须小于30,以留出一个字节用于存放字符串结束标志`\0`。

    对程序的说明:
    ① 我们本来希望将 "Java Python C-Sharp" 赋值给 str2,但是 scanf() 只读取到 "Java",这是因为 scanf() 读取到空格时就认为字符串输入结束了,不会继续读取了。请看下面的例子:
       
    1. #include <stdio.h>
    2. int main(){
    3. char str1[20], str2[20], str3[20];
    4. printf("Input string: ");
    5. scanf("%s", str1);
    6. scanf("%s", str2);
    7. scanf("%s", str3);
    8. printf("str1: %s\nstr2: %s\nstr3: %s\n", str1, str2, str3);
    9. return 0;
    10. }
    运行结果:
    Input string: Java Python C-Sharp↙
    str1: Java
    str2: Python
    str3: C-Sharp

    第一个 scanf() 读取到 "Java" 后遇到空格,结束读取,将"Python C-Sharp" 留在缓冲区。第二个 scanf() 直接从缓冲区中读取,不会等待用户输入,读取到 "Python" 后遇到空格,结束读取,将 "C-Sharp" 留在缓冲区。第三个 scanf() 读取缓冲区中剩下的内容。

    ② 在《 从键盘输入数据 》中讲到,scanf 的各个变量前面要加取地址符 & ,用以获得变量的地址,例如:
    int a, b;
    scanf("%d %d", &a, &b);
    但是在本节的示例中,将字符串读入字符数组却没有使用 & ,例如:
    char str1[20], str2[20], str3[20], str4[20];
    scanf("%s %s %s %s",str1, str2, str3, str4);
    这是因为C语言规定,数组名就代表了该数组的地址。 整个数组是一块连续的内存单元,如有字符数组char c[10],在内存可表示为:

    C语言还规定,数组名所代表的地址为第0个元素的地址,例如 char c[10]; c 就代表 c[0] 的地址。第0个元素的地址就是数组的起始地址,称为 首地址 也就是说,数组名表示数组的首地址。

    设数组c的首地址为0X2000,也即c[0]地址为0X2000,则数组名c就代表这个地址。因为c已经表示地址,所以在c前面不能再加取地址符&,例如写作 scanf("%s",&c); 是错误的。

    有了首地址,有了字符串结束符'\0',就可以在内存中完整定位一个字符串了。例如:
    printf("%s", c);
    printf 函数会根据数组名找到c的首地址,然后逐个输出数组中各个字符直到遇到 '\0' 为止。
    int、float、char 类型的变量表示数据本身,数据就保存在变量中;而数组名表示的是数组的首地址,数组保存在其他内存单元,数组名保存的是这块内存的首地址。后面我们会讲解指针,大家将会有更加深刻的理解。

    2) 使用 gets() 读取字符串

    gets 是 get string 的缩写,意思是获取用户从键盘输入的字符串,语法格式为:
    gets(arrayName);
    arrayName 为字符数组。从键盘获得的字符串,将保存在 arrayName 中。请看下面的例子:
       
    1. #include <stdio.h>
    2. int main(){
    3. char str1[30], str2[30];
    4. printf("Input str1: ");
    5. gets(str1);
    6. printf("Input str2: ");
    7. gets(str2);
    8. printf("str1: %s\nstr2: %s\n", str1, str2);
    9. return 0;
    10. }
    运行结果:
    Input str1: Java Python C-Sharp↙
    Input str2: http://c.biancheng.net↙
    str1: Java Python C-Sharp
    str2: http://c.biancheng.net

    可以发现,当输入的字符串中含有空格时,输出仍为全部字符串,这说明 gets() 函数不会把空格作为输入结束的标志,而只把回车换行作为输入结束的标志,这与 scanf() 函数是不同的。

    总结:如果希望读取的字符串中不包含空格,那么使用 scanf() 函数;如果希望获取整行字符串,那么使用 gets() 函数,它能避免空格的截断。


    7.C语言数组的静态行、越界以及溢出

    在C语言中,数组一旦被定义后,占用的内存空间就是固定的,不能在任何位置插入元素,也不能在任何位置删除元素(当然可以修改元素),我们将这样的数组称为静态数组(Static Array)

    数组越界

    C语言数组不会自动扩容,当下标小于零或大于等于数组长度时,就发生了 越界(Out Of Bounds) ,访问到数组以外的内存。如果下标小于零,就会发生 下限越界(Off Normal Lower) ;如果下标大于等于数组长度,就会发生 上限越界(Off Normal Upper)

    C语言为了提高效率,并不会对越界行为进行检查,即使越界了,也能够正常编译,只有在运行期间才可能会发生问题。请看下面的代码:
       
    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. int main()
    4. {
    5. int a[3] = {10, 20, 30}, i;
    6. for(i=-2; i<=4; i++){
    7. printf("a[%d]=%d\n", i, a[i]);
    8. }
    9. system("pause");
    10. return 0;
    11. }
    运行结果:
    a[-2]=-858993460
    a[-1]=-858993460
    a[0]=10
    a[1]=20
    a[2]=30
    a[3]=-858993460
    a[4]=-858993460

    越界访问的数组元素都是垃圾值,没有实际的含义,因为数组之外的内存我们并不知道是什么,可能是其他变量的值,可能是附加数据,可能是一个地址,这些都是不可控的。

    由于C语言的”放任“,我们访问数组时必须非常小心,要确保不会发生越界。

    当发生数组越界时,如果我们对该内存有访问权限,程序将正常运行,但会出现不可控的结果(如上例所示);如果没有访问权限,程序将会崩溃。请看下面的例子:
       
    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. int main()
    4. {
    5. int a[3];
    6. printf("%d", a[10000]);
    7. system("pause");
    8. return 0;
    9. }
    在 C-Free 5.0 下运行,会弹出程序停止工作的对话框:


    在VS2010下运行,会出现运行时错误:


    每个程序可访问的内存都是有限的,该程序要访问 4*10000 字节处的内存,显然太远了,超出了程序的访问范围。这个地方的内存可能是其他程序的内存,可能是系统本身占用的内存,可能是没被使用的内存,如果放任这种行为,将带来非常危险的后果,操作系统只能让程序停止运行。

    数组溢出

    当赋予数组的元素个数超过数组长度时,就会发生 溢出(Overflow) 。如下所示:
    int a[3] = {1, 2, 3, 4, 5};
    数组长度为3,初始化时却赋予5个元素,超出了数组容量,所以只能保存前3个元素,后面的元素被丢弃。

    VC/VS 发现数组溢出会报错,禁止编译通过;而GCC不会,它只给出警告。

    一般情况下数组溢出不会有什么问题,顶多是丢弃多余的元素。但对于字符数组,有时会产生不可控的情况,请看下面的代码:
       
    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. int main()
    4. {
    5. char str[10] = "http://c.biancheng.net";
    6. puts(str);
    7. system("pause");
    8. return 0;
    9. }
    可能的运行结果:


    字符串的长度大于数组长度,数组只能容纳字符串的前面一部分,也就是 "http://c.b",即使编译器在最后添加了 '\0',它也保存不到数组里面,所以 printf() 扫描数组时不会遇到结束符 '\0',只能继续向后扫描。而后面内存中的数据我们不知道是什么,字符能否识别,何时遇到 '\0',这些都是不确定的。当字符无法识别时,就会出现乱码,显示奇怪的字符。

    由此可见,在用字符串给字符数组赋值时,要保证数组长度大于字符串长度,以容纳结束符 '\0'。


    8.C语言变长数组

    目前使用的C语言有两个版本,C89和C99。C89(也称ANSI C)是较早的版本,也是最经典的版本,国内大学几乎都是以该版本为基础进行授课。C99是后来对C89的升级,增添了一些内容,语法更加灵活,同时兼容C89。关于C语言标准的更多内容请访问:C语言的发展及其版本

    各种编译器都遵循C89标准,但对C99的支持却不同:开源组织的GCC已经支持了大部分的C99标准,而微软的VC、VS对C99却不感兴趣(后来的VS2013、VS2015才慢慢支持)。

    为什么要讨论这个问题呢?因为C89和C99对数组做出了不同的规定:在C89中,必须使用数值常量指明数组长度,不能使用变量(不管变量有没有被初始化);而在C99中,可以使用变量指明数组长度。

    下面的代码使用数值常量指明数组长度,在任何编译器下都能编译通过:

       
    1. int a[10]; //长度为10
    2. int b[3*5]; //长度为15
    3. int c[4+8]; //长度为12
    下面的代码使用变量指明数组长度,在C-Free 5.0、GCC下编译通过,而在VC 6.0、VS2010下会报错:
       
    1. int m = 10, n;
    2. scanf("%d", &n);
    3. int a[m], b[n];
    变长数组仍然是静态数组,一旦确定长度后就不能改变。

    在实际编程中,有时数组的长度不能提前确定,如果这个变化范围小,那么使用数值常量定义一个足够大的数组就可以,如果这个变化范围大,就可能会浪费空间,这时就可以使用变长数组。请看下面的代码:
       
    1. #include <stdio.h>
    2. int main()
    3. {
    4. int n;
    5. printf("Input string length: ");
    6. scanf("%d", &n);
    7. fflush(stdin);
    8. char str[n];
    9. printf("Input string: ");
    10. gets(str);
    11. puts(str);
    12. return 0;
    13. }
    在C-Free 5.0下的运行结果:
    Input string length: 30↙
    Input string: http://c.biancheng.net↙
    http://c.biancheng.net


    9.对C语言数组的总结以及实例讲解

    数组(Array)是一系列相同类型的数据的集合,可以是一维的、二维的、多维的;最常用的是一维数组和二维数组,多维数组较少用到。

    对数组的总结

    1) 数组的定义格式为:
    type arrayName[length]
    type 为数据类型,arrayName 为数组名,length 为数组长度。 需要注意的是:
    • 在不支持C99的编译器中,length 必须是一个数值常量,不能是变量,例如 VC6.0、VS2010 等;在支持C99的编译器中,length 还可以是变量,例如 C-Free 5.0、GCC等。
    • 数组在内存中占用一段连续的空间,数组名表示的是这段内存空间的首地址。

    2) 访问数组中某个元素的格式为:
    arrayName[index]
    index 为数组下标。注意 index 的值必须大于等于零,并且小于数组长度,否则会发生数组越界,出现意想不到的错误。

    3) 可以对数组中的单个元素赋值,也可以整体赋值,例如:
       
    1. // 对单个元素赋值
    2. int a[3];
    3. a[0] = 3;
    4. a[1] = 100;
    5. a[2] = 34;
    6. // 整体赋值(不指明数组长度)
    7. float b[] = { 23.3, 100.00, 10, 0.34 };
    8. // 整体赋值(指明数组长度)
    9. int m[10] = { 100, 30, 234 };
    10. // 字符数组赋值
    11. char str1[] = "http://c.biancheng.net";
    12. // 将数组所有元素都初始化为0
    13. int arr[10] = {0};
    14. char str2[20] = {0};

    数组应用举例

    【示例1】求一个整型数组中的最大值和最小值。
       
    1. #include <stdio.h>
    2. int main(){
    3. int a[10] = {0}, max, min, i;
    4. //从控制台获取用户输入并赋值给数组元素
    5. for(i=0; i<10; i++){
    6. scanf("%d", &a[i]);
    7. }
    8. //假设a[0]是最大值也是最小值
    9. max = a[0], min = a[0];
    10. for(i=1; i<10; i++){
    11. if(a[i] > max){
    12. max = a[i];
    13. }
    14. if(a[i] < min){
    15. min = a[i];
    16. }
    17. }
    18. printf("The max is %d, The min is %d\n", max, min);
    19. return 0;
    20. }
    运行结果:
    2 123 45 100 575 240 799 710 10 90↙
    The max is 799, The min is 2

    这段代码有两点需要说明:
    1) 从控制台获取数组元素时,我们一次性输入10个整数才按下回车键,而不是每输入一个整数就按一次回车键,这正是利用了标准输入缓冲区。

    2) 要想求得数组中的最大值和最小值,就得循环比较数组中的所有元素,并设置两个变量 max 和 min 来接收。以最大值为例,开始循环之前,先假设第0个元素是最大值(当然你也可以假设第1、2、3 个元素),然后用 max 和数组中剩余的元素进行比较,如果某个元素的值比 max 大,就用这个元素的值替换 max 的值,等把所有元素遍历完了,max 中就是最大值了。

    关于排序和查找

    学完了数组,有两个重要的知识点要求大家掌握,那就是 排序(Sort) 查找(Search) ,比如:
    • 给你 10 个打乱顺序的整数,要能够按照从小到大或者从大到小的顺序输出;
    • 给定一个字符串 str1,以及一个子串 str2,要能够判断 str2 是否在 str1 中。

    10.C语言非阻塞式键盘监听

    监听键盘可以使用C语言的字符输入函数,例如 getchar、getch、getche 等,我们会在《结合缓冲区谈谈C语言getchar()、getche()、getch()的区别》一节中重点讲解它们的区别。

    使用getche函数监听键盘的例子:

       
    1. #include <stdio.h>
    2. #include <conio.h>
    3. int main(){
    4. char ch;
    5. int i = 0;
    6. //循环监听,直到按Esc键退出
    7. while(ch = getch()){
    8. if(ch == 27){
    9. break;
    10. }else{
    11. printf("Number: %d\n", ++i);
    12. }
    13. }
    14. return 0;
    15. }
    运行结果:
    Number: 1  //按下任意键
    Number: 2  //按下任意键
    Number: 3
    Number: 4
    Number: 5  //按下Esc键

    这段代码虽然达到了监听键盘的目的,但是每次都必须按下一个键才能执行getch后面的代码,也就是说,getch后面的代码被阻塞了。

    阻塞式键盘监听非常不方便,尤其是在游戏中,往往意味着用户要不停按键游戏才能进行,所以一般采用非阻塞式键盘监听。

    使用 conio.h 头文件中的 kbhit 函数可以实现非阻塞式键盘监听。

    我们每按下一个键,都会将对应的字符放到键盘缓冲区,kbhit 函数会检测缓冲区中是否有字符,如果有字符返回非0值,没有返回0。但是kbhit不会读取字符,字符仍然留在缓冲区。请看下面的例子:
       
    1. #include <stdio.h>
    2. #include <windows.h>
    3. #include <conio.h>
    4. int main(){
    5. char ch;
    6. int i = 0;
    7. //循环监听,直到按Esc键退出
    8. while(1){
    9. if(kbhit()){
    10. ch = getch();
    11. if(ch == 27){
    12. break;
    13. }
    14. }
    15. printf("Number: %d\n", ++i);
    16. Sleep(1000); //暂停1秒
    17. }
    18. return 0;
    19. }
    运行结果:
    Number: 1
    Number: 2
    Number: 3
    Number: 4
    Number: 5  //按下Esc键

    每次循环,kbhit 会检测用户是否按下某个键(也就是检测缓冲区中是否有字符),没有的话继续执行后面的语句,有的话就通过 getch 读取,并判断是否是 Esc,是的话就退出循环,否则继续循环。

    kbhit 之所以能够实现非阻塞式监听是因为它只检测字符,而不要求输入字符。

    Sleep 是“睡眠”的意思,用来让程序暂停执行一段时间,以毫秒记。


    11.C语言获取随机数

    可能大家在编程的时候需要电脑来获取一些随机的反应,这个时候我们可以使用随机数,比较常见的是 rand() 函数,它可以随机的产生 0 ~ rand_max 的随机数。rand_max 是一个很大的数字,具体关系到IDE和数据类型,我们一般的需要不可能超出它的范围。

    下面是一个实例:

       
    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. int main(){
    4. int a=rand();
    5. printf("%d\n",a);
    6. return 0;
    7. }

    编译后再运行几次,你会发现产生的随机数是相同的。实际上,rand() 函数产生的随机数是伪随机数,是根据一个数按照某个公式推算出来的,这个数我们称之为“种子”,但是这个种子在系统启动之后就是一个定值,我们需要用 srand() 来进行播种,即在int a前加一句:
       
    1. srand((unsigned)time(NULL)); //这里利用时间进行播种,需要time.h

    这样,我们就能得到不同的随机数,其实C语言中还有一个 random() 函数可以获取随机数,但是 random() 函数不是ANSI C标准,不能在VC等编译器通过,所以比较少用。

    那如何产生一定范围的随机数呢?我们可以利用取模的方法:
       
    1. int a=rand()%10; //产生0~9的随机数,注意10会被整除
    如果要规定上下限:
       
    1. int a=rand()%51+13; //产生13~63的随机数
    分析:取模即取余,rand()%51+13我们可以看成2部分:rand()%51是产生0~50的随机数,后面+13保证a最小只能是13,最大就是50+13=63。

    最后给出产生 13~63 范围内随机数的完整代码:
       
    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. int main(){
    4. int a;
    5. srand((unsigned)time(NULL));
    6. a=rand()%51+13;
    7. printf("%d\n",a);
    8. return 0;
    9. }

    展开全文
  • C语言 数组

    2018-12-22 10:52:36
     1、定义:数据类型 数组名 [整数1][整数2]……[整数n] ✔C语言数组的下标都是从0开始的。 ✔在定义数组时不能使用变量定义数组的大小。 ✔当数组被声明为静态存储变量或外部存储类型时,在不显示给出初值的...
  • C语言数组的总结以及实例讲解数组(Array)是一系列相同类型的数据的集合,可以是一维的、二维的、多维的;最常用的是一维数组和二维数组,多维数组较少用到。一、对数组的总结1) 数组的定义格式为:type arrayName...
  • C语言数组专题知识点总结

    千次阅读 2018-12-22 16:48:20
    C语言数组专题知识点易错点总结及做题感悟 一.知识点总结 1.一维数组的定义和初始化. 注: ① C语言数组的下标都是从0开始的; ②在定义数组时不能使用变量定义数组的大小,如果前面没有对n进行宏定义 #define n 5 则...
  • 数组(Array)是一系列相同类型的数据的集合,可以是一维的、二维的、多维的;最常用的是一维数组和二维数组,多维数组较少用到。对数组的总结1) 数组的定义格式为:type arrayName[length]type 为数据类型,arrayName...
  • C语言数组求鞍点: #include &lt;stdio.h&gt; #include &lt;time.h&gt; void main() { int i, j, m = 0, n = 0, a[5][5]; srand(time(0)); for (i = 0; i &lt; 5; i++) { for (j = 0;...
  • c语言数组、数组相关的计算

    千次阅读 2016-11-18 08:30:41
    数组 1.数组的创建: 元素类型 数组名 [常量或者常量表达式] 如:int arr1[10]; 注:即使是被const修饰的变量也不能作为[]中的内容,它本质上依然属于变量,只是具有常量属性 2.数组的初始化:  创建数组时...
  • C语言 有关数组查找

    千次阅读 2017-11-25 21:37:53
    1,给定两个整型数组,本题要求找出不是两者共有的元素,并且要求要按从大到小的顺序输出。 (这是这几个题中打的算是很麻烦的了,可能我的方法不是最优的,但是还不会用指针,所以再慢慢进化吧) 输入示例 10 3...
  • C语言数组长度极限

    千次阅读 2017-06-18 14:58:39
    今天在做《计算机图学实验》大作业的时候,定义了一个数组用于存放顶点坐标,数组长度为1025*1025,可是总是弹出错误,最后经过上网查找,发现错误原因在于我的数组是在函数体内定义的。 函数体内定义的的数组存在...
  • C语言数组之排序

    千次阅读 2019-03-25 19:56:34
    输入某门课的成绩,按编程将分数从高到低顺序进行排序输出 第一种:采用交换法排序,也称作冒泡排序。 基本过程是先将第一个数分别于后面的数一个一个进行比较,若后面的数小,则...下一篇介绍C语言查找算法。
  • 算法训练 数组查找及替换 时间限制:1.0s 内存限制:512.0MB 问题描述  给定某整数数组和某一整数b。要求删除数组中可以被b整除的所有元素,同时将该数组各元素按从小到大排序。如果数组元素数值在A到Z...
  • c语言数组相关练习

    2019-04-22 11:35:40
    输入一个整数数组,实现一个函数, 来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分, 所有偶数位`数组的后半部分。 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <...
  • 5:c语言数组

    2019-05-15 21:23:06
    1.数组的概念和定义 2.二维数组:2个下标 3。字符数组 4.字符串长度 5.字符串输入输出: 6.字符串处理函数: 字符串连接函数 strcat() 字符串复制函数 strcpy() 字符串比较函数 strcmp() 7.对字符串排序 8...
  • C语言 数组练习~

    千次阅读 2017-03-30 17:42:16
    //如果我要查找的字符跟数组的某个元素相同 if (searchnum == nums[i]) { printf ( "猿粪啊,找到了相同的元素!\n" ); //找到后,记得跳出循环 break ; //else{ // printf("没有找到!\n"); // }...
  • C语言数组题目训练3

    2019-04-23 20:41:16
    问题描述:定义一个10个元素的数组,输入9个已经是升序排列的整数,存入一维数组,再输入一个整数存入x,查找x在已有的排好序的数组中的位置,并将其插入,形成一个新的9个元素的升序排列的数组。 输入形式:升序排列...
  • 上周发布零碎小知识不小心删掉了,,,心痛到无以复加,,,失去的找不回来,,来点新的吧~ 1、数组的赋值 第一种,用赋值语句对数组元素逐个赋值,小白才会写的东东,很麻烦 第二种,初始化赋值或动态赋值 ...
  • C语言数组知识点梳理

    2020-03-14 21:49:18
    数组声明之后变为常量,不能放在等号左边;初值表{…}只能用于初始化。 数组元素只能逐个进行引用,不能一次性引用。 数组越界的危害: (1)会覆盖其他变量的值(越界短时) (2)会出现段错误(越界过长) a+i==&a...
  • C语言查找整数

    千次阅读 2018-11-21 18:56:58
    第三行包含一个整数a,为待查找的数。 输出格式 如果a在数列中出现了,输出它第一次出现的位置(位置从1开始编号),否则输出-1。 样例输入 6 1 9 4 8 3 9 9 样例输出 2 数据规模与约定 1 ...
  • C语言 · 查找整数

    2016-12-22 15:44:00
    问题描述  给出一个包含n个整数的数列,问整数a在... 第三行包含一个整数a,为待查找的数。 输出格式  如果a在数列中出现了,输出它第一次出现的位置(位置从1开始编号),否则输出-1。 样例输入 61 9 4 8 3 99...
  • 因为在C语言中没有专门的字符串变量,所有字符串的储存都是通过字符串数组来实现的。通常一个字符串就是用一维字符数组来储存的。二维字符数组是用来储存多个字符串,一般是一行数组就是一个字符串。然后我们在使用...
  • 数组一次性声明多个同类型的变量(1)声明 定义 数组数据类型 数组名[数组长度];声明定义一个数组,且相当于声明了 数组长度 个同类型变量int scores[10];scores[0] scores[1] scores[2] … scores[9] 这10个int类型...
  • 问题描述 给出一个包含n个整数的数列...第三行包含一个整数a,为待查找的数。 输出格式 如果a在数列中出现了,输出它第一次出现的位置(位置从1开始编号),否则输出-1。 样例输入 61 9 4 8 3 99 样例输出 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 30,994
精华内容 12,397
关键字:

c语言数组查找整数

c语言 订阅