第六章 数组

6.1 一维数组

6.1.1 一维数组的定义

  一维数组定义的一般形式:

            类型说明符 数组名[常量表达式];

  说明:

  1)类型说明符为类型描述符,常用的有int ,float,char等。

  2)数组名的命名规则和变量名相同,遵循标识符命名规则。

  3)常量表达式是数组的个数,可以是常量、符号常量、常量表达式。在C语言中不允许对数组的大小做动态定义,即数组大小不依赖于程序运行过程中变量的值。

6.1.2 一维数组的引用

  数组必须先定义,后使用。当定义了一个一维数组之后,就可以引用这个数组中的任何元素。引用方式如下:

  数组名[下标]。下标可以是整型常量或整型常量表达式,其最小值默认为0.

6.1.3 一维数组的初始化与赋值

  1)在定义数组时,对数组全部元素赋初始值。例如:int a[3] = {1,2,3};  

  将数组元素的初值依次放在一对大花括号内,相当于:a[0] = 1;a[1] = 2;a[2] = 3;

  此时可以省略数组长度,即:int a[ ] = {1,2,3};

  2)在定义数组时,可以只对数组部分元素赋初值,系统为其余元素符0。 例如: int a[3] = {1,2};定义数组有3个元素,但花括号内只提供2个初值,表示只给前两个元素赋初值,后1个数组元素值为0。

  3)利用输入语句初始化。例如:

  void main( )

  {

    int a[7],i;

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

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

  ……

  }

 

例题1.Fibonacci数列的第1,2项分别为1,1;以后各项的值均是其前两项之和,用数组来求该数列的前20项。

#include<stdio.h>
#include<stdlib.h>

void main()
{
    int fibo[20] = { 1,1 };
    int i;
    for (i = 2; i < 20; i++)
        fibo[i] = fibo[i - 1] + fibo[i - 2];

    for (i = 0; i < 20; i++)
    {
        if (i % 5 == 0) putchar('\n'); //每行输出5个数就换行
        printf("%12d", fibo[i]);
    } 

    system("pause");
}

 

例题2.用“冒泡排序法”对一维数组中的整数按从小到大排序。

  “冒泡排序法”思路:比较相邻两个数,将较小的数调到前面。也就是说,若后面的数小,就将两数交换,否则不交换。

  如果有n个数,则要进行n - 1趟比较。二是每一趟比较的次数,在第1趟中两两比较要进行n - 1次,在第j趟中两两比较要进行n - j次。

#include<stdio.h>
#include<stdlib.h>
#define N 5

void main()
{
    int a[N] = { 88,67,11,96,32 };
    int i, j, tmp;
    
    for (j = 0; j < N - 1; j++)
        for (i = 0; i < N - 1 - j; i++)
            if (a[i] > a[i + 1])
            {
                tmp = a[i];
                a[i] = a[i + 1];
                a[i + 1] = tmp;
            }

    printf("The sorted numbers:\n");
    for (i = 0; i < N; i++)
        printf("%3d", a[i]);

    system("pause");
}

 

6.2 二维数组

6.2.1 二维数组的定义

  二维数组定义的一般形式:

  类型说明符 数组名[常量表达式1][常量表达式2];

例如:

  float a[3][4],b[5][10];

  定义a为3行4列的数组,b为5行10列的数组。

说明:

  1)二维数组可看作特殊的一维数组,它的元素又是一个一维数组。例如,可以把a看作是一个一维数组,它有3个元素:a[0],a[1],a[2],而每个元素又是一个包含4个元素的一维数组。

  2)元素在内存中排列顺序为按行存放。

6.2.2 二维数组的引用

  数组名[下标][下标]    元素m行n列 a[m - 1][n - 1]

6.2.3 二维数组的初始化与赋值

  1)按行给二维数组初始化。例如: int a[3][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12} }; 把第1个花括号内的数据给第1行的元素,第2个花括号内的数据给第2行的元素,第3个花括号内的数据给第3行的元素。

  2)按数组排列的顺序将所有数据写在一个花括号内,例如:

  int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};

  3)对部分元素初始化。例如 int a[4][4] = { {,1},{0,6},{0,0,11},{} };

  4)如果对全部元素都赋初值,则定义数组时可以不指定第一维的长度,但第二维的长度不能省。例如:

  int a[][4] = {1,2,3,4,5,6,7,8,9,10,11,12};等价于:int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};

  5) 利用输入语句初始化。例如:

  int i, j, a[3][4];

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

    for(j = 0;j < 4;j++)

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

例题1.转置矩阵。将一个二维数组行和列的元素互换,即可得到其转置矩阵。

  int a[2][3] = { {1,2,3},{4,5,6} }

  int b[3][2],i, j;

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

    for(j = 0;j < 3;j++)

      b[j][i] = a[i][j];

 

6.3 字符数组与字符串

6.3.1 字符数组的定义

  字符数组的定义形式:

            char 数组名[常量表达式];

6.3.2 字符数组的初始化与赋值

  1)逐个元素初始化,例如:char a[5] = {'C','h','i','n','a'};

  2)如果赋初值个数等于数组长度,则在定义时可以省略数组长度,系统会自动根据初值个数确定数组的长度。例如:

  char c[ ] = {'C','h','i','n','a'};

  3)如果赋初值的个数小于数组的长度,则将这些字符赋给数组中前面那些元素,其余元素自动为空字符'\0'。

C语言规定以字符'\0'作为字符串结束标志。系统对字符串常量自动添加一个'\0'作为结束标志。'\0'在内存中占据一个字节,但不计入字符串长度。

  4)字符串来初始化字符数组,例如:

  char a[11] = { "I am a boy"};

  或直接省略花括号,如:

            char a[11] = "I am a boy";

  用格式符"%s"将整个字符串一次输入或输出。例如:

    char s[ ] = "Hello";

    printf("%s",s);  //用字符数组名,数组中需要包含'\0',仅输出'\0'之前的字符。

    scanf("%s",s);    //用字符数组名,不加 & ,遇到空格或回车结束,自动加'\0'。

 

例题1.将大写字母的字符数组转换成小写字母的字符数组,用下标变量的方式实现。

#include<stdio.h>
#include<stdlib.h>

void main()
{
    char c[5] = { 'A','B','C','D','E' };
    int i;
    for (i = 0; i < 5; i++)
        c[i] = c[i] + 'a' - 'A';
        
    for (i = 0; i < 5; i++)
        printf("%2c", c[i]);

    system("pause");
}

 

例题2.将大写字母的字符数组转换成小写字母的字符数组,用字符串与数组元素结合方式实现。

#include<stdio.h>
#include<stdlib.h>

void main()
{
    char str[6];
    int i;
    scanf("%s", str);
    for (i = 0; i < 5; i++)
        str[i] = str[i] + 'a' - 'A';
    printf("%s\n", str);
    system("pause");
}

 

说明:

  1)char str[6]定义数组长度为字符串长度加1;

  2)scanf("%s",str)字符串的输入,%s是格式描述符,str是字符数组名,不能写出&str。字符串结束标志'\0'是输入结束时系统自动加上去的。

  3)printf("%s\n",str)字符串的输出,%s是格式描述符,str是数组名。

 

例题3.读入一个英文句子,把英文字母全部转换成大写字母。英文句子最后以“ . ”结束。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#define N 128
void main()
{
    char str[N];
    int i;
    printf("请输入英文句子(以句号.结束):");

    for (i = 0; i < N && ((str[i] = getchar( )) != '.'); i++);
    str[i] = '\0';

    for (i = 0; str[i] != '\0'; i++)
        if (str[i] >= 'a'&&str[i] <= 'z')
            str[i] = str[i] + 'A' - 'a';

    printf("转换结果:%s\n", str);

    system("pause");
}

 

6.3.3 字符串处理库函数

1. 字符串输出函数 puts( )

  调用格式:puts(str)  str可以是字符串常量、字符数组名或指向字符的指针变量。

  功能:输出一个字符串,输出后自动换行。

 

2. 字符串输入函数 gets_s( )  gets() 函数在ISO/IEC 9899 2011(C11)标准中被移除, 用一个新的更安全的函数gets_s()替代

  函数原型:char *gets_s( char *buffer, size_t sizeInCharacters );

  说明:gets_s()函数会从标准输入中读取字符串,直到遇到换行符“\n”或回车时停止读取。回车被舍弃,可以读取空格。之后,将读取到的字符串中的换行符“\n”替换为字符串结束符“\0”。其中第二个参数就是允许的输入的长度, 这里的sizeInCharacters应该分配为buffer - 1的长度,因为函数自动为'\0'分配空间的时候会溢出。函数返回保存输入的内存的首地址,即buffer的地址;如果失败则返回值是NULL。

 

3. 字符串连接函数 strcat( )

  调用格式:strcat(str1,str2)  str2可以是字符串常量、字符数组名或指向字符的指针变量。

  功能:把str2中的字符串连接到str1字符串的后面,结果放在str1数组中,函数返回值是str1。 此函数把第二个字符串拼接到第一个的到结尾。函数不会分配内存,这意味着第一个字符串必须足够长,能容纳拼接后的结果,否则函数可能会越界写入,导致不可预期的行为。函数的返回值的地址跟第一个参数的地址一样。

 

4. 字符复制函数 strcpy( )

  调用格式: strcpy(str1,str2) str2可以是字符串常量、字符数组名或指向字符的指针变量。 str1必须是足够大且'\0'结束的字符数组或malloc函数分配的内存。

  功能:将str2中的字符串复制到str1数组中,覆盖str1中原有字符串。

 

5. 字符串比较函数 strcmp( )

  调用格式: strcmp(str1,str2)  str1、str2可以是字符串常量、字符数组名或指向字符的指针变量。

  功能:对两个字符串str1 和 str2自左向右按字符的ASCII码值逐个字符比较大小,直到遇到不同字符(当前大的字符所在的字符串大)或'\0'为止,函数返回结果为整数1(若str1 > str2)、0(若str1 = str2)或 -1(若str1 < str2)。

 

6. 求字符串长度函数 strlen( )

  调用格式:strlen(str)

  功能:计算字符串长度。函数值是字符串str中字符(不含"\0")的个数。str可以是字符串常量、字符数组名或指向字符的指针变量。

例题.反序输出一个字符串。

  char str[ ] = "ABCDEFG"; int i;

  for(i = strlen(str) - 1;i >= 0;--i)

  printf("%c",str[i]);

 

7.字符查找函数 strchr( )

  函数原型:char *strchr(const char *str, int c)  str可以是字符串常量、字符数组名或指向字符的指针变量。c单引号括起来的字符或字符变量。

  说明:在参数str所指向的字符串中搜索第一次出现字符c(一个无符号字符)的位置。返回一个指向该字符串中第一次出现的字符的指针,如果字符串中不包含该字符则返回NULL空指针。第一个参数不一定要求是字符串的首地址,可以是任意一个位置检索指针。

 

8.字符串查找函数 strstr( )

  函数原型:char *strstr(char *str1, const char *str2)  

  说明:若str2是str1的子串,则返回str2在str1的首次出现的地址;如果str2不是str1的子串,则返回NULL。str1、str2可以是字符串常量、字符数组名或指向字符的指针变量。

 

9.大写字母转换成小写字母函数 _strlwr( str )     str只能是字符数组

10.小写字母转换成大写字母函数 _strupr( str )

 

例题. 用gets_s( )函数读字符串,分别统计字符串中的数字字符,字母字符和其它字符的数量。

    for (i = 0; str[i] != '\0'; i++)
    {
        if (str[i] >= '0'&&str[i] <= '9') digit++;
        else if (str[i] >= 'A'&&str[i] <= 'Z' || str[i] >= 'a'&&str[i] <= 'z')
            letter++;
        else
            other++;
    }

例题. 编写程序实现比较两个字符串的大小,要求不能使用库函数 strcmp。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

void main()
{
    int i;
    char str1[100], str2[100];
    puts("请输入字符串 str1:"); gets_s(str1, 99);
    puts("请输入字符串 str2:"); gets_s(str2, 99);

    for (i = 0; str1[i] == str2[i] && str1[i] != '\0'; i++); //跳过字符串相同的部分
    if (str1[i] == '\0'&&str2[i] == '\0')  
        printf("字符串 %s == 字符串 %s\n", str1, str2);
    else if (str1[i] > str2[i])
            printf("字符串 %s > 字符串 %s", str1, str2);
        else
            printf("字符串 %s < 字符串 %s", str1, str2);

    system("pause");
}
posted @ 2020-08-16 10:37  YangXinYi  阅读(445)  评论(0编辑  收藏  举报
//color="150,150,150"粒子的颜色设置 opacity="1"粒子的透明度 count="100"粒子的个数