第六章:数组

文章目录

    • 第六章:数组
      • 6.1一维数组
        • 定义:
        • 一维数组的初始化
        • 一维数组的访问
        • 一维数组应用举例
      • 6.2-二维数组(即矩阵)
        • 定义:
        • 二维数组初始化
        • 二维数组的访问
      • 6.3-字符数组
        • 定义
        • 字符数组的存储
        • 字符数组的初始化
        • 字符数组的输入输出
        • 字符串处理函数:

第六章:数组

在C语言中,定义了一个数组后,就确定了它所容纳的具有相同数据类型元素的个数

6.1一维数组

数组是由若干个相同类型的变量在内存中有序存储的集合。

int a[10]
第六章:数组_第1张图片

定义:
数据类型  数组名[常量表达式,即数组元素的个数]

数据类型:每个数组元素的数据类型
数组名:满足标识符的命名规则,不能与其他变量重名
常量表达式:表示元素的个数,即数组的长度。不能包含变量

访问数组元素时,下标的取值范围为 0 ≤ index < length,过大或过小都会越界,导致数组溢出,发生不可预测的情况。

  • 一维数组在内存的存放、
    • 存储单元的大小由数组的类型和数组的长度决定
    • 数组名表示整个数组所占用的内存空间的首地址。同一数组中的所有元素, 按其下标的顺序占用若干连续的存储单元
一维数组的初始化
  • 定义:初始化指在定义时指定初始值,编译时将初始值赋给数组元素

  • 一般格式:

数据类型 数组名[常量表达式]={初值表};
  • 几种方式

    • 全部数组元素赋初值

      int a[6]={1,2,3,4,5,6};
      
    • 在对全部数组元素赋值时,由于数据的个数已经确定,因此可以不指定数组长度

      int a[]={1,2,3,4,5};
      
    • 部分数组元素赋初值

      int a[6]={1,2,3,4};   # 其余数组元素值为0
      
    • 数组定义后,若全部数组元素在使用前未赋值,则该数组元素的值不确定。若数组元素部分初始化,则未初始化部分元素值为0

      int a[10],b[10]={1,2,3,4};
      
    • 如果想使一个数组的全部元素值为0,可以写为:

      int a[10]={0};
      
  • 更高效的初始化方法

memset(a, 0, sizeof(a));  //将数组中的所有元素全部初始化为0

eg:
给数组赋值-1
int A[2];  
memset(A, -1, sizeof(A);  

用sizeof(a)来获得数组a 所占的内存字节数
需要包含头文件:#include  
一维数组的访问
  • 数组中的每个元素只能逐个被引用,而不能一次引用全部数组元素
  • 在c语言中引用数组元素时,其数组下标的数据类型允许是:整型常量或整型表达式
  • 数组的引用方式:数组名[下标]
  • 下标的取值范围:0<=下标<=数组长度-1
int a[5]={1,2,3};
for (i=0;i<5;i++)
   printf("%d ",a[i]);
一维数组应用举例
  • 查找
#include 
#include 
int main()
{
    int a[] = {21, 13, 52, 0, -25, 11, 54, 41, 87, 9, 3, 98, 43, 65, 11};
    int i, x, flag = 0, k;
    scanf("%d", &x);
    for (i = 0; i < 15; i++)
        if (a[i] == x)
        {
            k = i;
            flag = 1;
            break;
        }
    if (flag==1)
        printf("%d的下标是%d", x, k);
    else
        printf("not exist!");
    system("pause");
    return 0;
}
  • 排序

    • 交换排序:通过不断交换数组中数组元素的位置,直到数组排序完成为止。冒泡排序就是交换排序的典型示例。冒泡排序的基本思想就是:扫描整个数组,依次比较相邻的两个数,将小数放在前面,大数放在后面。
    • 冒泡排序总共排序(n-1)轮,总共比较[(n-1)×n]/2次,第i轮比较(n-i)次。
    • 选择排序:首先挑选最小的数,放在第一个数的位置,再从其余位置选最小的数,放在第二个位置,以此类推。
  • 拓展:

    • 指针数组

      char*a[10];
      
    • 结构体数组

      struct stu boy[10];
      

6.2-二维数组(即矩阵)

定义:
数据类型 数组名[常量表达式1,即行的个数][常量表达式2,即列的个数];
 eg:int b[3][5];
b组数据有3行5列,共15个数组元素
  • 二维数组有两个下标。常量表达式1代表第一维的长度,常量表达式2是第2维的长度

  • 定义一维数组后,则需要为其所有的元素分配内存单元,一维数组占用的内存字节数=数组 长度×每一元素占用的字节数,而且所占用的内存单元是连续的,并按照元素顺序依次排列

    eg: int a[5]; 所占字节数为:4×5=20个字节,用sizeof(a)即可计算内存数
    
  • 二维数组在概念上是二维的,但在内存中是连续存放的。换句话说,二维数组的各个元素是相互挨着的,彼此之间没有缝隙。在线性内存中存放二维数组有两种方式:

    • 一种是按行排列, 即放完一行之后再放入第二行;
    • 另一种是按列排列, 即放完一列之后再放入第二列。
  • 在C语言中,二维数组是按行排列的。

二维数组初始化
  • 一般格式:

    数据类型 数组名[常量表达式1][常量表达式2]={初值表};
    
  • 其他方式:

    • 按行初始化:每一行的数据用括号括起来
    全部元素赋值:
    int x[2][4]={{1,2,3,4},{5,6,7,8}};
    
    部分元素赋值:
    int y[3][5]={{1},{6,7},{}};  # 剩余用0补齐
    
    • 按顺序初始化:所有数据在一个花括号内,按数组元素排列的顺序对各元素赋初值,但容易遗漏。
    全部元素赋值:
    int x[2][4]={1,2,3,4,5,6,7,8};
    部分元素赋值:
    int y[3][5]={1,6,7};  # 剩余用0补齐
    
  • 省略指定第一维的长度:

    • 给二维数组的全部元素赋值时,可以不指定第一维的长度,但第二维的长度不能省略
    int x[][4]={{1,2,3,4},{5,6,7,8}};
    int x[][4]={1,2,3,4,5,6,7,8};
    
    • 按行初始化时,也可以只对部分元素赋初值而省略第一维的长度
    int a[][3]={{1},{},{9,11}};
    
二维数组的访问
  • 数组元素的引用方式:数组名[下标1] [下标2]

  • 下标取值范围:

    0<=下标1<常量表达式1
    0<=下标2<常量表达式2
    
    eg:
    int m[2][3]
    
    m[0][0] m[0][1] m[0][2]
    m[1][0] m[1][1] m[1][2]
    

    注意:定义的m[2] [3]数组中无m[2] [3]元素

  • 三维数组:是由多个相同的二维数组构成的

    int a[4][2][10];
    

6.3-字符数组

定义
  • 用来存放字符数据的数组是字符数组。

  • C语言用字符数组存放字符串,字符数组中的各元素依次存放字符串的各字符

  • 一维字符数组:存放一个字符串(每个数组元素存放一个字符)

  • 二维字符数组:存放多个一维数组(字符串);二维数组的行数是字符串的个数

  • 定义格式:

     char 数组名[常量表达式];
     
    char 数组名[常量表达式][常量表达式];        //声明的时候,方括号中一定是常量或常量表达式,使用的时候可以是变量。其中常量表达式:整数、字符、符号常量 。 也可以用整型数组存放字符型数据,但是浪费存储空间
    
字符数组的存储

第六章:数组_第2张图片

字符数组的初始化
  • 用单个字符对字符数组初始化
    • 如果花括号中提供的初值个数(即字符个数)大于数组长度,则出现语法错误
    • 如果提供的初值个数与预定的数组长度相同,在定义时可以省略数组长度,系统会自动根据初值个数确定数组长度
    • 如果初值个数小于数组长度,则只将这些字符赋给数组中前面那些元素,其余的元素自动定为空字符(即’\0’)
  • 用字符串常量对字符数组初始化
(1)char str[6]={"CHINA"};

(2)char str[6]="CHINA";            //省略{}

(3)char str[ ]="CHINA";            // 省略长度值

(4)char c[12]={"HOW ARE YOU"};与char c[ ]={'H','O','W',' ','A','R','E',' ','Y','O','U','\0'};  等价  

(5)char *p=c;     //用一个指针指向该数组,*(p+i) <=> a[i]
  • 字符数组逐个字符初始化比整个字符串初始化要少一个“\0”;即__用字符串方式赋值比用逐个字符赋值要多占1个字节,用于存放字符串结束标志’\0’__
字符数组的输入输出
  • 逐个字符输入:用%c按字符序列输入
  • 整个字符串输入:用%s字符串 //不同于数值型数组

注意:scanf以空格、回车作为结束的

char str[]="i am abc"
scanf("%s",str)

-->i  # 在第一个空格处结束
  • 说明
    • 数组名前不加&符号
    • 输入字符串的长度要小于数组长度
    • 只能输入不包括空格、\t和\n的字符串
    • 若要输入空格,用gets函数
    • 自动加’\0’
字符串处理函数:

包含在头文件

  • 字符串输出函数puts

    • 格式: puts(字符数组)

    • 功能:向显示器输出一个字符串(输出完,换行)

    • 说明:字符数组必须以’\0’结束。可以包含转义字符。输出时’\0’转换成’\n’,即输出字符后换行。

      #include
      #include
      int main()
      {
          char a[]={"china\ngood"};
          char b[]={"zhong\0guo"};
          puts(a);
          puts(b); 
          puts("CHINA");
      }
      
      运行结果:
      china
      good
      zhong   //将'\0'转换成'\n'
      CHINA
      
  • 字符串输入函数gets

    • 格式:gets(字符数组)
    • 功能:从键盘输入一个以回车结束的字符串放入字符数组中,并自动加’\0’
    • 说明:输入串长度要小于字符数组长度
    #include
    #include
    int main()
    {
        char a1[10],a2[10];
        gets(a1);
        scanf("%s",a2);
        printf("a1=%s\n",a1);
        printf("a2=%s\n",a2);
    }
    
    输入:
    china china  //在scanf中遇到空格字符串便结束了,而gets中,却将空格作为字符存放入字符数组中
    china china
    输出:
    a1=china china
    a2=china
    
    输入:
    abcdeabcdeabcde
    abcdeabcdeabcde
    输出:
    a1=abcdeabcde
    a2=abcdeabcdeabcde
    
  • 字符串连接函数stract

    • 格式:strcat(字符数组1,字符数组2)
    • 功能:把字符数组2连到字符数组1后面
    • 返值:返回字符数组1的首地址
    • 说明:
      • 字符数组1必须足够大
      • 连接前,两串均以’\0’结束;连接后,串1的’\0’取消,新串最后加’\0’。
    #include
    #include
    int main()
    {
        char str1[10]={"China is"};
        char str2[]={"good"};
        printf("%s\n",strcat(str1,str2));
    }
     
    输出: China is good
    
  • 字符串拷贝函数strcpy

    • 格式:strcpy(字符数组1,字符串2)
    • 功能:把字符数组2,拷贝到字符数组1中去
    • 返值:返回字符数组1的首地址
    • 说明:
      • 字符数组1必须足够大,至少大于字符串2
      • 字符数组1必须是数组名形式(str1),字符串2可以是字符数组名或字符串常量
      • 拷贝时’\0’一同拷贝
    #include
    #include
    int main()
    {
        char str1[20],str2[]="Hello!";
           strcpy(str1,str2);
        printf("%s\n",str1);
        printf("%d\n",strlen(str1));
        printf("%d\n",sizeof(str1));
    }  
    
    Hello!
    6
    20   //总长度
    
  • 字符串比较函数strcmp

    • 格式: strcmp(字符串1,字符串2)
    • 功能:比较两个字符串
    • 比较规则:对两串从左向右逐个字符比较(ASCII码),直到遇到不同字符或’\0’为止
    • 返回值:返回int型整数。其值是ASCII码的差值(根据编译器的不同,也有可能返回1,0,-1)
    • 说明:字符比较必须用strcmp
    若字符串1大于字符串2,返回正整数;
      
    若字符串1等于字符串2,返回零;
      
    若字符串1小于字符串2,返回负整数;
    
    #include
    #include
    int main()
    {
        char a[]={"china"},b[]={"henan"};
        int x.y.z;
        x=strcmp(a,b);
        y=strcmp("china","beijing");
        z=strcmp(a,"china");
        printf("x=%d\ny=%d\nz=%d\n",x,y,z);
        return 0;
    }
    
    x=-1  //只比较了c与h的ASCII码值,在ASCII码表中,c的值小于h的值
    y=1   // 在ASCII码表中,c的值大于b的值
    z=0   
    
  • 字符串长度函数strlen

    strlen是函数,要在运行的时候才能计算。参数必须是字符型指针。当数组名作为参数传入时,实际上数组就退化成指针了

    • 格式: strlen(字符数组)
    • 功能:返回字符串的长度。该字符串可能时自己定义的,也可能时内存中随机的,该函数实际完成的功能是从代表该字符串的第一个地址开始遍历,直到遇到结束符NULL。返回的长度大小不包括NULL。
    • 返值:返回字符串实际长度,不包括‘\0’在内
    #include
    #include
    int main()
    {
        char a[]="china";
        printf("%d\n",strlen(a));
        printf("%d\n",sizeof(a));
    }
    
    5  //china后面自带'\0',strlen返回的字符串长度不带'\0'
    6
    
  • strlwr函数

    • 格式:strlwr(字符串)

    • 作用:将字符串中的大写字母换成小写字母

  • strupr函数

    • 格式:strupr(字符串)
    • 作用:将字符串中的小写字母换成大写字母

你可能感兴趣的:(C,c语言,数组)