谭浩强 第六章利用数组处理批量数据

简介: 谭浩强 第六章利用数组处理批量数据

1.一维数组

在介绍一维数组之前,先来了解下什么是数组。数组,英文名为array,简写为arr(一般在C语言中用arr来指代数组)可以理解为数学中的集合。是具有相同特征元素的集合。比如,一群打篮球的人,你就可以创建一个数组,数组的元素就是打篮球的人的名字。

  • 一维数组的定义

定义方式:类型    int float double char .......

                  数组名   arr1,arr2,......

                  [常量表达式]   只能为常量不能为变量

int arr[10];定义了10个整型变量,将其存储到arr这个数组中。(相比于一个一个创建,效率提升)

常见错误举例:

//#define _CRT_SECURE_NO_WARNINGS 1
//常见错误
//1.[]中存入变量
//int n;
//scanf("%d", n);
//int arr[n];//[]中只能为常量
//若提前调用函数,则n会根据函数的值来
//void func(int n)
//{
//  int arr[2 * n];//在每次调用func函数时,都会得到不同的数组长度,成这样的数组为可变长数组,但在执行函数后n不变。
//
//}
  • 一维数组的初始化

初始化就是给数组赋值 ,初始化的方式多样,下面介绍常见初始化方式;

1.给所有元素赋值

int arr1[5]={12345};5个元素全部初始化

2.部分元素赋值

若部分元素赋值,则其余部分默认为0(整形数组),若为字符型数组,则默认为\0;若为指针型数组,默认为NULL,即空指针;

int arr2[5]= {1,2,3};则其余两个元素默认为0;

3.若数据个数确定,则可以不用添加长度(常用于字符型数组)

int arr3[]= {1,2,3,4,5};    char ch [] = {"i love c"};char ch [] = "i love c";

  • 一维数组的引用

引用,是通过下标(subscript)完成;C语言中,默认第一个元素的下标为0;即,若一个数组的长度为n,则其下标的最大值为n-1;

注意:引用时下标不要超过最大值,否则有溢出危险

   int arr[5] = { 1,2,3,4,5 };//定义了一个长度为5的数组

   printf("%d\n", arr[0]);//分别打印出数组中的元素

   printf("%d\n", arr[1]);

   printf("%d\n", arr[2]);

   printf("%d\n", arr[3]);

   printf("%d\n", arr[4]);

  printf("%d\n", arr[5]);//这是个错误的代码,数组长度为5,则下标最大值为4;

一维数组程序举

#include <stdio.h>//输出斐波那契数列前25个数字(要求每行输出5个)
int main()
{
  int i;
  int arr[20];//定义一个长度为20的数组,用于存放20个数字;
  arr[0] = 1;
  arr[1] = 1;
  for (i = 2; i < 20; i++)
  {
    arr[i] = arr[i - 1] + arr[i - 2];//根据数列性质,利用for循环实现将前20个数字存储到数组中
  }
  for (i = 0; i < 20; i++)
  {
    if (i % 5 == 0)//实现5个数一换行
      printf("\n");
    printf("%10d", arr[i]);
  }
   return 0;
}

冒泡排序法 (核心:for循环的嵌套)

  1.  
#define _CRT_SECURE_NO_WARNINGS 1
//练习冒泡排序法(输入五个数字,实现升序排列)
//冒泡排序法就是两两比较,将较大的数字通过比较移动到后面,实现升序或降序处理
#include<stdio.h>
int main()
{
  int i,j,t;
  int arr[5];
  printf("请输入五个数字");
  for (i = 0; i<5; i++)
  {
    scanf("%d", &arr[i]);//将5个数字存储到数组中
    }
  printf("\n");
  for (j = 0; j < 4; j++)//冒泡排序法的核心:for循环的嵌套;//一共5个数字,第一趟比较需要4次,第二趟比较需要3次,以此类推;
  {
    for (i = 0; i<4-j; i++)
    {
      if(arr[i]>arr[i+1])//接下来进行比较
      {
        t = arr[i + 1]; arr[i + 1] = arr[i]; arr[i] = t;//交换前后两个数字顺序
      }
    }
  }
  printf("升序处理的数字为:\n");
  for (i = 0; i < 5; i++)
  {
    printf("%d  ", arr[i]);
  }
  return 0;
}

2.二维数组

二维数组通常称为矩阵(matrix),写成row(行)和column(列)的形式。

  • 二维数组的定义:

类型 数组名称 [常量表达式] [常量表达式]

                       行(row)      列(column)

float arr [3][4];相当于创建了一个3*4的矩阵int arr[10][10];

  • 二维数组的初始化

1.各个元素都赋值

#include <stdio.h>
int main()
{
  int arr[2][2] = { {1,2},{3,4} };//全体元素都赋值
  int i, j;
  for (i = 0; i < 2; i++)
  {
    for (j = 0; j < 2; j++)
    {
      if (j% 2 == 0)
        printf("\n");
      printf("%5d", arr[i][j]);
    }
  }
    return 0;
}

2.部分赋值

int arr [3][4]={{1,2},{3,4}}//其余元素为0;

3.在赋值时行数可不做要求,系统会根据列数自动分配;

int arr[][3]={1,2,3,4,5,6};很明显是两行三列(尽量不要这么写,不是好的代码风格)

3.二维数组的引用

同一维数组,注意不要超过下标的最大值即可;

4.二维数组程序练习

//转置数组的练习
int main()
{
  int arr1 [2] [3] = { {1,2,3},{4,5,6} };
  int arr2[3][2];
  int i, j;
  printf("arr1:\n");
  for (i = 0; i < 2; i++)
  {
    for (j = 0; j < 3; j++)
    {
      if (j % 3 == 0)
        printf("\n");
      printf("%7d", arr1[i][j]);
      arr2[j][i] = arr1[i][j];
    }
  }
  printf("\n");
  printf("arr2(转置后):\n");
  for (i = 0; i < 3; i++)
  {
    for (j = 0; j < 2; j++)
    {
      if (j % 2 == 0)
        printf("\n");
      printf("%7d", arr2[i][j]);
    }
  }
  return 0;
}
//利用擂台算法来找出数组中最大值,并给出其row,column;
int main()
{
  int arr[4][5] = { {12,23,31,26,11},{10,11,56,67,79} ,{64,65,98,90,35 },{10,20,30,40,50} };
  int i, j,row,column;
  int max;
  max = arr[0][0];//定义一个最大值,并使数组第一个元素为擂主
  for (i = 0; i < 4; i++)
  {
    for (j = 0; j < 5; j++)
    {
      if (arr[i][j] > max)
      {
        max = arr[i][j];
        row = i;
        column = j;
      }
    }
  }
  printf("max=%d\nrow=%d\ncolumn=%d\n" ,max,row,column);
  return 0;
}

3.字符数组

字符数组,即用来存放字符的的数组。要注意,C语言中并没有字符串类型,字符串类型是以字符数组的形式出现。

1.字符数组的定义                                                                                                                                类似于数值型数组定义方式,类型   数组名称  [常量表达式]      char ch[];  char[][];二维数组                             注意:我们知道,字符型数据的存储是通过ascii值存放的,所以字符型数据可以看作整形数据的一部分,即一下定义方式也合法;

int ch [10];
ch[0]=1;//但是这种定义方式占用空间,因为int类型占4个字节,char类型占一个字节

2.字符数组的初始化

//对每个元素都赋值
char ch [4]={'l','o','v','e'};
//若字符长度确定,可以不指明长度.更加方便便捷
char ch []={'l','o','v','e'};
//若初始值小于指定长度,则系统自动补充\0;即空操作符;
char ch[5]={'l','o','v','e'};
char ch[3][3]={{' ','*',' '},{'*',' ','*'},{' ','*',' '}}
//注意单引号之内不能什么也没有,你可以添加空格
//也可以一次性输入,用''''括起来
char ch ={"i love you"};

3.字符数组的引用

方法和数值型数组相同,通过下标来引用;

4.字符串的结束标志

字符串的结束标志为\0,在ascii码值中对应空操作符;

printf("love\0you");
//字符串的结束标志为\0,这个程序的只会输出love;
//一般情况下,系统会自动在字符串末尾添加\0,作为结束标志;

   5.字符数组的输入与输出

1.逐个字符输出,char ch [4]={'h','e','h','e'};printf("%c",ch[i]);

若想从e输出,则:printf("%s",&a[1]);

2.以字符串输出   char ch ="hehe";printf("%s",ch);注意:输出字符串时类型为string,即%s;同时,输出时要用数组名,因为你要一下子输出所有元素,而不是单个元素输出;逻辑为,先找到数组ch的起始地址,逐个字符输出,直到遇到\0;

3.字符串的输入scanf("%s",ch);注意:这个地方不用&,因为数组一旦创建就有一个起始地址,自动存到内存中了;

补充:

//用for循环实现读取字符串结束标志
for(i=0;arr[i]!=\0;i++);
//实现从字符串中提取数字
if('0'<=arr[i] && '9'>=arr[i]);

4.字符串的处理函数

//以下函数在引用时要添加#include <string.h>
//1.puts函数  字符串输出函数    
puts(str);//注意puts输出的一定是以\0结尾的字符串;若不是,令arr[i]='\0'
//注意和putchar函数的区别,putchar只能输出单个字符;
//2.fgets函数  字符串输入函数
fgets(str,sizeof(str),stdin);输入时不会读取\0;
//函数对str作用后会得到他的初始地址;
//3.strlen函数  字符串长度计算函数
strlen(str);//他计算的是实际长度,且不包括\0;
char arr [10]={"i am you"}
strlen(arr)=6;
//4.strcmp函数  字符串比较函数
strcmp(str1,str2);
//strcmp(str1,str2)>0;str1在str2后面;
//strcmp(str1,str2)<0;str1在str2前面;
//strcmp(str1,str2)=0;str1和str2完全相同;
//后面的单词更大,且小写比大写大;
//5.strcat函数   字符串连接函数
strcat(str1,str2);//把str2连接到str1之后;
//一定要注意str1的长度是否足够大
//6.strcpy函数   字符串复制函数   strncpy函数  可以限制长度复制字符串
strcpy(str1,str2);将str2的字符串赋值给str1;
strcpy(str1,"china");
strncpy(str1,str2,2);//将str2的字符串前两个字符赋给str1;
strncpy(str1,"china",2);//将ch两个字符赋给str1;
//7.strupr函数   字符串变大写函数        strlwr函数   字符串变小写函数;
strupr(str);
strupr("china")=CHINA;

5.总结

数组概念是C语言学习中重要的一个概念,他解释了在C语言中如何表示字符串,即通过字符数组;一维数组,二维数组也很重要,他们为我们提供了一个简单的创建大量变量的方法,要充分理解数组的作用,即定义一个数组后,会自动产生一个初始地址;要理解二维数组的概念,可以用线性代数中的矩阵概念来理解,要认识到二维数组其实可以看为特殊的一维数组(和分块矩阵的概念类似);字符数组也很重要,告诉我们如何实现字符串的输出与输入;在数组中,我们还学习了两个重要的排序方法,一是冒泡排序法(核心为for循环的嵌套),二是擂台法,希望大家能够勤加练习,谢谢观看!

目录
相关文章
|
小程序 数据安全/隐私保护 Android开发
八米云-N1盒子、机顶盒等设备-小白保姆式超详细刷机教程
这里以魔百盒CM211-1为例,本次刷机用到的零碎工具比较多,不过都是常见刚需设备,大家可以按照清单核对一下。 目前只支持S905 L3、L3a、L2 系列的各种盒子
2901 1
八米云-N1盒子、机顶盒等设备-小白保姆式超详细刷机教程
|
存储 缓存 NoSQL
把ruoyi-vue前后端分离项目的redis缓存改为本地缓存cache
把ruoyi-vue前后端分离项目的redis缓存改为本地缓存cache
1890 0
|
28天前
|
人工智能 JSON API
全网刷屏的 Jev 模型正式开放!一手实战测评 + 保姆级教程
Jev是TypeSafe AI推出的“决策型AI模型”,不聊天、不生成文本,专注做选择题/判断题/打分题,响应≤100ms、成本低、输出结构化。适用于AI Agent路由、内容审核、游戏NPC决策、金融风控等需快速精准判断的场景。
278 0
|
4月前
|
PyTorch API 调度
在 AMD ROCm DSW 上跑通 DeepSeek-V4-Flash:vLLM 兼容部署、长上下文验证与 8K 性能扫参
本文记录一次在 ModelScope DSW AMD GPU/ROCm 环境中部署 DeepSeek-V4-Flash 的工程实践:通过 vLLM、ROCm/AITER/PyTorch fallback 与兼容补丁建立可复现 baseline,并用短问答、2K/8K/32K needle retrieval 和 8K top-k 扫参验证正确性与性能边界。
1034 1
在 AMD ROCm DSW 上跑通 DeepSeek-V4-Flash:vLLM 兼容部署、长上下文验证与 8K 性能扫参
|
5月前
|
安全 算法 物联网
2026 人员定位系统主流技术解析:飞远光电融合方案适配全场景
飞远光电提供室内外多技术融合人员定位系统,集成UWB、蓝牙AOA与北斗,实现厘米级精度与无缝切换。具备实时定位、轨迹回放、电子围栏、SOS求助、智能考勤及数据可视化功能,广泛应用于化工、矿山、工地等高危场景,助力安全管理与运营效率双提升。
489 3
|
9月前
|
人工智能 Kubernetes 应用服务中间件
AI 网关这一年,成了 AI 进化的缩影
未来,让每一个想用 AI 的企业,都能稳稳地迈出第一步。
438 62
|
安全 数据处理 数据安全/隐私保护
C/S架构与B/S架构的适用场景分析
C/S架构(客户端/服务器架构)与B/S架构(浏览器/服务器架构)在适用场景上各有特点,主要取决于应用的具体需求、用户群体、系统维护成本、跨平台需求等因素。
1681 6
|
6月前
|
开发者
阿里云百炼Coding Plan总是显示售罄,抢不到怎么办?附上解决攻略
阿里云百炼Coding Plan Pro版常“售罄”?主因Lite停售+每日9:30限量补货。技巧:提前登录、卡点刷新、速付。替代方案:直用百炼平台,享Qwen3.5-Max等满血模型、新用户100万Token免费额度,按量付费更灵活。
982 5
|
10月前
|
数据采集 Java 调度
从10个协程到1000个协程:性能下降的背后究竟发生了什么?
本文探讨了异步程序中常见的误解“协程越多越快”,并通过一个实际的异步抓取学术论文元数据的例子来阐明这一点。文章首先解释了协程过多可能导致的效率低下的原因,包括事件循环的调度限制、网络瓶颈、代理并发限制以及Python协程切换的成本。接着,文章提供了一个使用代理、从DOAJ抓取开放论文元数据并存入SQLite数据库的完整异步代码示例,并强调了合理设置并发量的重要性。最后,文章总结了初学者在编写异步抓取程序时容易遇到的几个陷阱,并提供了相应的解决方案。
410 2
|
机器学习/深度学习 人工智能 算法
VE-Bench:北京大学开源首个针对视频编辑质量的评估指标,从多角度考虑审美并准确地评估视频编辑效果
北京大学开源了首个针对视频编辑质量评估的新指标 VE-Bench,旨在通过人类感知一致的度量标准,更准确地评估视频编辑效果。
1309 14
VE-Bench:北京大学开源首个针对视频编辑质量的评估指标,从多角度考虑审美并准确地评估视频编辑效果

热门文章

最新文章