第六章:数组

本文详细介绍了C语言中一维数组、二维数组以及字符数组的定义、初始化方法、访问规则,以及一维数组的应用实例,包括查找和排序。同时涵盖了字符串处理函数如strlen、strcpy、strcmp和字符大小写转换函数strlwr和strupr的使用。

第六章:数组

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

6.1一维数组

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

int a[10]
在这里插入图片描述

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

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

访问数组元素时,下标的取值范围为 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 <string.h> 
一维数组的访问
  • 数组中的每个元素只能逐个被引用,而不能一次引用全部数组元素
  • 在c语言中引用数组元素时,其数组下标的数据类型允许是:整型常量或整型表达式
  • 数组的引用方式:数组名[下标]
  • 下标的取值范围:0<=下标<=数组长度-1
int a[5]={1,2,3};
for (i=0;i<5;i++)
   printf("%d ",a[i]);
一维数组应用举例
  • 查找
#include <stdio.h>
#include <math.h>
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 数组名[常量表达式][常量表达式];        //声明的时候,方括号中一定是常量或常量表达式,使用的时候可以是变量。其中常量表达式:整数、字符、符号常量 。 也可以用整型数组存放字符型数据,但是浪费存储空间
    
字符数组的存储

在这里插入图片描述

字符数组的初始化
  • 用单个字符对字符数组初始化
    • 如果花括号中提供的初值个数(即字符个数)大于数组长度,则出现语法错误
    • 如果提供的初值个数与预定的数组长度相同,在定义时可以省略数组长度,系统会自动根据初值个数确定数组长度
    • 如果初值个数小于数组长度,则只将这些字符赋给数组中前面那些元素,其余的元素自动定为空字符(即’\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’
字符串处理函数:

包含在头文件 <string.h >中

  • 字符串输出函数puts

    • 格式: puts(字符数组)

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

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

      #include<stdio.h>
      #include<string.h>
      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<stdio.h>
    #include<string.h>
    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<stdio.h>
    #include<string.h>
    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<stdio.h>
    #include<string.h>
    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<stdio.h>
    #include<string.h>
    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<stdio.h>
    #include<string.h>
    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(字符串)
    • 作用:将字符串中的小写字母换成大写字母
根据原作 https://pan.quark.cn/s/459657bcfd45 的源码改编 Classic-ML-Methods-Algo 引言 建立这个项目,是为了梳理和总结传统机器学习(Machine Learning)方法(methods)或者算法(algo),和各位同仁相互学习交流. 现在的深度学习本质上来自于传统的神经网络模型,很大程度上是传统机器学习的延续,同时也在不少时候需要结合传统方法来实现. 任何机器学习方法基本的流程结构都是通用的;使用的评价方法也基本通用;使用的一些数学知识也是通用的. 本文在梳理传统机器学习方法算法的同时也会顺便补充这些流程,数学上的知识以供参考. 机器学习 机器学习是人工智能(Artificial Intelligence)的一个分支,也是实现人工智能最重要的手段.区别于传统的基于规则(rule-based)的算法,机器学习可以从数据中获取知识,从而实现规定的任务[Ian Goodfellow and Yoshua Bengio and Aaron Courville的Deep Learning].这些知识可以分为四种: 总结(summarization) 预测(prediction) 估计(estimation) 假想验证(hypothesis testing) 机器学习主要关心的是预测[Varian在Big Data : New Tricks for Econometrics],预测的可以是连续性的输出变量,分类,聚类或者物品之间的有趣关联. 机器学习分类 根据数据配置(setting,是否有标签,可以是连续的也可以是离散的)和任务目标,我们可以将机器学习方法分为四种: 无监督(unsupervised) 训练数据没有给定...
本系统采用微信小程序作为前端交互界面,结合Spring Boot与Vue.js框架实现后端服务及管理后台的构建,形成一套完整的电子商务解决方案。该系统架构支持单一商户独立运营,亦兼容多商户入驻的平台模式,具备高度的灵活性与扩展性。 在技术实现上,后端以Java语言为核心,依托Spring Boot框架提供稳定的业务逻辑处理与数据接口服务;管理后台采用Vue.js进行开发,实现了直观高效的操作界面;前端微信小程序则为用户提供了便捷的移动端购物体验。整套系统各模块间紧密协作,功能链路完整闭环,已通过严格测试与优化,符合商业应用的标准要求。 系统设计注重业务场景的全面覆盖,不仅包含商品展示、交易流程、订单处理等核心电商功能,还集成了会员管理、营销工具、数据统计等辅助模块,能够满足不同规模商户的日常运营需求。其多店铺支持机制允许平台方对入驻商户进行统一管理,同时保障各店铺在品牌展示、商品销售及客户服务方面的独立运作空间。 该解决方案强调代码结构的规范性与可维护性,遵循企业级开发标准,确保了系统的长期稳定运行与后续功能迭代的可行性。整体而言,这是一套技术选型成熟、架构清晰、功能完备且可直接投入商用的电商平台系统。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蛰伏GR

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值