数组Array

news2024/11/15 21:50:45

数组的基本用法

概念

数组是有序元素序列。如果将若干个数据类型相同的变量的集合命名,那么该命名就是数组名。数组元素的重点是类型相同并且连续在内存中存放的数据。

定义格式

存储类型 数据类型 数组名 [ 元素个数 ] ;

例如:

        (auto)int arr[5] ;

数组名:代表数组的首地址,是地址常量,不能够作为左值,不能被赋值。

数组定义方法:

  1. 数组名的定义规则和变量相同,遵循标识符命名规则。
  2. 数组名后使用方括号括起来的是元素个数,并且必须是常量或常量表达式,不能是变量。

访问数组元素

数组名 [ 下标 ] ;

数组的下标从0开始!!!

例如:

        int a[ 5 ] ;

        访问第一个元素:a[ 0 ] ;

        访问最后一个元素:a[ 4 ] ;

注意数组越界!!!!

 注意:

1.数组的数据类型就是数组元素的数据类型。

2.数组名要符合标识符命名规则。

3.同一个函数中,数组名不要和变量名相同。

        例如:

        int a;

        int a[ 5 ];//错误,变量名和数组名重复

4.数组元素下标从0开始,到n-1结束,一定要注意数组越界问题。

一维数组

一维数组和二维数组

一维数组的概念

只有一个下标的数组。

格式:存储类型 数据类型 数组名[ 元素个数 ];

访问元素:数组名[ 下标 ];

下标从0开始到n-1。

数组名:数组的首地址。

初始化

1.定义时全部初始化

int a[5]={1,2,3,4,5};
printf("%d\n",a[0]);
printf("%d\n",a[1]);
printf("%d\n",a[2]);
printf("%d\n",a[3]);
printf("%d\n",a[4]);

2.定义时部分初始化,未初始化的部分自动为0。

int a[5]={1,2};
printf("%d\n",a[0]);
printf("%d\n",a[1]);
printf("%d\n",a[2]);
printf("%d\n",a[3]);
printf("%d\n",a[4]);

3.定义时未初始化,需要对单个元素进行赋值,要不然是随机数(垃圾数)。

int a[5];
a[0]=1;
a[1]=2;
a[2]=3;
a[3]=4;
a[4]=5;
printf("%d\n",a[0]);
printf("%d\n",a[1]);
printf("%d\n",a[2]);
printf("%d\n",a[3]);
printf("%d\n",a[4]);

注意数组越界:

int a[3]={5,6,7,8};//数组越界 

定义空数组

int a[5]={0,0,0,0,0};

int a[5]={0};

int a[5]={};

数组引用

  1. 先定义后引用。
  2. 每次只能引用一个数组元素a[i],如果想引用所有元素可以通过循环遍历数组中每一个元素。
  3. 引用时一定要防止数组越界,虽然有时候不会报错。
  4. 打印数组元素的地址用%p。

例如:

int a[10];
printf("%d",a);//错误,不能把数组名用来引用数组元素,因为数组名是数组首地址
printf("%p",a);//获取数组首地址

遍历数组可以使用循环

int a[5]={1,2,3,4,5};
for(int i=0;i<5;i++)
    printf("%d\n",a[i]);

练习:输入5个数组元素,然后依次打印出来

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

int main(int  argc,char const *argv[])
{
    int a[5]={};
    int i;
    for(i=0;i<5;i++)
        scanf("%d",&a[i]);
    for(i=0;i<5;i++)
        printf("%d\n",a[i]);
    return 0;
}

数组的大小

例如:

int a[5];//20
char c[32];//32
double b[2];//16
printf("%d %d %d\n",sizeof(a),sizeof(b),sizeof(c));//20 16 32

计算方式

  1. 元素个数*数据类型的大小
  2. sizeof(数组名)

数组元素个数=sizeof(数组名)/sizeof(元素数据类型)

练习:计算斐波那契数列前十五项并逆向输出

解析:斐波那契数列1 1 2 3 5 8 13 21 ······

#include <stdio.h>
#include <stdlib.h>
int main(int argc,char const *argv[])
{
    int b[15]={1,1};
    for(int i=2;i<15;i++)
        b[i]=b[i-1]+b[1-2];
    for(int j=14;j>=0;j--)
        printf("%d ",b[j]);
    printf("\n");
    return 0;
}

清零函数 

bzero()函数

#include <strings.h>
void bzero(void *s,size_t n);

功    能:将内存空间设置为0

参    数:s:要清空的空间的首地址

           n:要清空的内存空间大小(单位是字节)

返回值:无

练习:将数组清空

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

int main(int argc,char const *argv[])
{
    int a[10]={1,2,3};
    for(int i=0;i<10;i++)
        printf("%d ",a[i]);
    printf("\n");
    bzero(a,sizeof(a));
    for(int i=0;i<10;i++)
        printf("%d ",a[i]);
    printf("\n");
    return 0;
}

memset()函数

#include <strings.h>
void *memset(void *s,int c,size_t n);

功    能:将指定内存空间内容设置为0

参    数:s:要清空内存空间首地址

               c:要设置的数,一般为0

               n:要清空的内存大小

返回值:无

 练习:将数组清空

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

int main(int argc,char const *argv[])
{
    int a[10]={1,2,3};
    for(int i=0;i<10;i++)
        printf("%d ",a[i]);
    printf("\n");
    memset(a,0,sizeof(a));
    for(int i=0;i<10;i++)
        printf("%d ",a[i]);
    printf("\n");
    return 0;
}

数组内存分配 

数组在内存中的分配如下图:

 a是数组名,是数组的首地址,也是第一个数组元素的地址,即&a[0];

a+1是数组的第二个元素的地址,即&a[1]。

练习:获取数组元素的地址

int a[10]={1,2,3};
printf("%p %p\n",a,&a[0]);
printf("%p %p\n",a+1,&a[1]);
printf("%p %p\n",a+2,&a[2]);

打印结果:

0xbfe47dd4 0xbfe47dd4

0xbfe47dd8 0xbfe47dd8

0xbfe47ddc 0xbfe47ddc

字符串数组

因为C语言没有字符串类型,所以可以用字符数组的形式表示字符串。

概念:类型为字符的数组,也就是数组中每个元素的数据类型都是字符型,该数组组成字符串。

表示形式

单个字符表示

char s[]={'h','e','l','l','o'};//sizeof(s)=5
char s1[5]={'h','e','l','l','o'};//sizeof(s1)=5

字符串的形式表示,结尾自动加上' \0 '

char s2[]="hello";//sizeof(s2)=6
char s3[]={"hello"};//sizeof(s3)=6
char s4[6]={"hello"};//sizeof(s4)=6
char s5[]={};//错误

初始化和数组规则相同 

输入和输出

输入

用scanf输入
char s[32]={};
scanf("%s",s);
printf("%s\n",s);

如果用%s不能输入空格,如果有空格空格包括后面内容不会输入进入数组 存入;如果需要输入空格,则需要用%[^\n]: 

char s[32]={};
scanf("%[^\n]",s);//正则表达式,可以输入除了\n以外的字符,遇到\n结束
printf("%s\n",s);
用for循环遍历输入

例如:

char s[6]={};
for(int i=0;i<6;i++)
    scanf("%c",&s[i]);
printf("%s\n",s);
用gets()输入
#include <stdio.h>
char *gets(char *s);

功    能:从终端获取字符串输入

参    数:s:目标字符串的首地址

返回值:目标字符串的首地址

注意:

  1. 该函数没有数组越界检查,使用该函数时会有警告。
  2. 该函数可以输入空格,字符串结束的标志是换行符 ('\n') 或文件描述符(EOF)。

例如:

char s[32]={};
gets(s);
printf("%s",s);

练习:计算字符串空格数

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

int main(int argc,char const *argv[])
{
    char s[32]={};
    int num=0;
    scanf("%[^\n]",s);
    for(int i=0;i<32;i++)
    {
        if(s[i]==' ')
            num++;
    }
    printf("num:%d\n",num);
    return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc,char const *argv[])
{
    char s[32]={};
    int num=0;
    scanf("%[^\n]",s);
    int i=0;
    while(s[i]!='\0')
    {
        if(s[i]==' ')
            num++;
        i++;
    }
    printf("num:%d\n",num);
    return 0;
}

输出

用printf()输出
char s[32]="hello";
printf("%s\n",s);
用for()循环输出
char s[32]="hello";
for(int i=0;i<32;i++)
    printf("%c",s[i]);
printf("\n");
用puts()输出
#include <stdio.h>
int puts(const char *s);

功    能:向终端输出字符串

参    数:要输出的目标字符串首地址

返回值:字符串长度

例题:

看一下程序有哪些错误

char s[10]={};
s[10]="hello";
//s[10] 试图访问数组的第11个元素(数组索引从0开始),但数组 s 只有10个元素,所以这是越界访问:s[10] 是一个 char 类型的变量,而 "hello" 是一个字符串字面量(即 char 类型的数组),它们之间不能直接赋值。
s="hello";
//数组名 s 是一个指向数组首元素的指针常量,它不能重新被赋值指向另一个地址(即不能让它指向另一个字符串)也就是s不能作为左值使用,“hello”是一个常量字符数组,其地址是固定的
//如果想将字符串 "hello" 复制到数组 s 中,应该使用 strcpy 函数(需要包含头文件 <string.h>)

例题:

将字符串“This is a string.”用char s[17]={};记录下来,错误的输入语句为(A

A. scanf("%20s",s);

B.for(k=0;k<17;k++)

        s[k]=getchar();

C.while((c=getchar())!='\n')

        s[k++]=c;

解析:

A. scanf 函数中的 %20s 指示符意味着 scanf 会尝试读取最多 20 个字符(不包括结束的空字符)到一个字符数组中,但是s[17]只分配了17个字符空间大小,如果输入超过 16 个字符(加上一个空字符),就会发生缓冲区溢出,因此,正确的做法应该是使用 %16s,确保不会超过数组 s 的边界。

计算字符串长度

用循环

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

int main(int argc,char const *argv[])
{
    char str[15]="hello world";
    int i=0,len=0;
    while(str[i]!='\0')
    {
        len++;
        i++;
    }
    printf("%d",len);
    return 0;
}

用strlen()

#include <string.h>
size_t strlen(const char *s);

功    能:计算字符串实际长度

参    数:字符串首地址

返回值:返回字符串的实际长度,不包括 '\0'

例如:

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

int main(int argc,char const *argv[])
{
    char str[32]="hello world";
    int len=strlen(str);
    printf("%d\n",len);
    return 0;
}

sizeof()和strlen()的区别

sizeof()是关键字,strlen()是函数

sizeof()是计算数据所占空间大小,strlen()是计算字符串的实际长度

sizeof()计算包括 '\0' 在内,strlen()计算不包括 '\0' 在内,因此,sizeof计算的值比strlen多1

char str[]="hello world";
char str1[32]="hello world";
int len=strlen(str);
int len1=strlen(str1);
printf("%d\n",len);//11
printf("%d\n",len1);//11
printf("%d\n",sieof(str));//12
printf("%d\n",sizeof(str1));//32

二维数组 

下标是两个的数组是二维数组,其中下标分别为行下标和列下标。

定义格式

存储类型 数据类型 数组名 [行数] [列数];

int a[3][2];

访问元素

数组名 [行下标] [列下标];

//下标都是从零开始

int a[2][3];
a[0][0];//第一行第一列的元素
a[1][2];//最后一行最后一列的元素

注意:

  1. 行下标和列下标都不能越界。
  2. 定义时行数可以省略但是列数不能省略。
  3. 数组名代表的是第一行的首地址。

数组元素的个数和二维数组的大小

元素个数=行数*列数

计算二维数组的大小:

  1. 数据类型的大小*行数*列数
  2. sizeof(数组名)

二维数组的数组名

二维数组的数组名代表第一行首地址

例如:

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

a:第一行的首地址

a+1:第二行的首地址

初始化

定义时全部初始化

int a[2][3]={1,2,3,4,5,6};//顺序赋值
int a[2][3]={{1,2,3},{4,5,6}};//按行赋值

定义时部分初始化

int a[2][3]={1,2,3,4};//顺序赋值 1 2 3 4 0 0
int a[2][3]={{1,2},{3,4}};//按行赋值 1 2 0 3 4 0

未初始化

随机值,需要对每个元素都进行赋值。

遍历二维数组

for循环嵌套遍历,外层循环行数,内层循环列数。

int a[2][3]={};
for(int i=0;i<2;i++)
{
    for(int j=0;j<3;j++)
    {
        printf()/scanf()
    }
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc,char const *argv[])
{
    int a[3][3]={};
    for(int i=0;i<3;i++)
    {
        for(int j=0;j<3;j++)
            scanf("%d",&a[i][j]);
    }
for(int i=0;i<3;i++)
    {
        for(int j=0;j<3;j++)
            printf("%d",a[i][j]);
        printf("\n");
    }
    return 0;
}

练习:设一个二维数组,每个数组元素的值都为行下标和列下标的乘积

 

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

int main(int argc,char const *argv[])
{
    int arr[4][4]={};
    for(int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            arr[i][j]=i*j;
            printf("arr[%d][%d]=%d ",i,j,arr[i][j]);
        }
        printf("\n");
    }
    return 0;
}

内存分配

行地址

在二维数组中,数组名的本质是第一行的首地址,其数值还是第一行第一列的地址,即&array[0][0]。

array+1的本质是第二行的首地址,其数值还是第二行第一列的地址,即&array[1][0]。

列地址 

在二维数组中array[0]的本质是第一行第一列,即&array[0][0]。

array[0]+1是第一行第二列的地址,即&array[0][1]。

列地址:&array[i][j] a[i]+j

验证:

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

int main(int argc,char const *argv[])
{
    int a[2][3]={1,2,3,4,5,6};
    printf("%p %p\n",a,a+1);
    printf("%p %p\n",a[0],a[1]);
    printf("%p %p\n",&a[0][0],&a[1][0]);
    printf("%p %p\n",a[0]+1,a[1]+1);
    printf("%p %p\n",&a[0][1],&a[1][1]);
    return 0;
}

打印结果如下:

练习:

在执行语句: int a[][3]={1,2,3,4,5,6}; 后,a[1][0]的值为(A

A. 4                B. 1                C. 2                D. 5

在定义 int a[5][6]; 后,数组a中的第十个元素是(C)(设 a[0][0] 为第一个元素)

A. a[2][5]                B. a[2][4]                C. a[1][3]                D.a[1][5]

下列程序执行后的输出结果为(B

main()
{
    int i,j,a[2][3];
    for(i=0;i<3;i++)
        for(j=0;j<=i;j++)
            a[i][j]=i*j;
    printf("%d,%d\n",a[1][2],a[2][1]);
}

A. 2,2                B. 不定值,2                C. 2                D. 2,0

有一个3*4的矩阵(元素值不同),要求输出其中最大值以及它的行号和列号。

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

int main(int argc,char const *argv[])
{
    int a[3][4]={{12,3,56,2},{7,8,89,9},{100,890,567,1}};
    int max=a[0][0],h=0,l=0;
    for(int i=0;i<3;i++)
    {
        for(int j=0;j<4;j++)
        {
            if(max<a[i][j])
            {
                max=a[i][j];
                h=i;
                l=j;
            }
        }
    }
    printf("max:a[%d][%d]=%d\n",h,l,max);
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1701615.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AHB与APB总线介绍

1 什么是AHB、APB? AHB&#xff08;Advanced High-performance Bus&#xff09;高速总线&#xff0c;接高速master&#xff0c;APB&#xff08;Advanced Peripheral Bus&#xff09;外设总线&#xff0c;用来接低速slave&#xff0c;一个master可以有多个slave&#xff0c;AH…

若依微服务实现分布式事务

一、基本介绍 1、什么是分布式事务 指一次大的操作由不同的小操作组成的&#xff0c;这些小的操作分布在不同的服务器上&#xff0c;分布式事务需要保证这些小操作要么全部成功&#xff0c;要么全部失败。从本质上来说&#xff0c;分布式事务就是为了保证不同数据库的数据一致…

2.1 数据类型-常量-变量(整型-浮点-字符)

目录 1 数据类型 1.1 关键字 2 常量 3 变量 3.1 命名规则 4 整形数据 4.1 符号常量 4.2 整型变量 5 浮点型数据 5.1 浮点型常量 5.2 浮点型变量 6 字符型数据 6.1 字符型常量 转义字符 6.2 字符数据在内存中的存储形式及其使用方法 6.3 ASCII码表 7 字符串型常…

homebrew安装mysql的一些问题

本文目录 一、Homebrew镜像安装二、mac安装mysql2.1、修改mysql密码 本文基于mac环境下进行的安装 一、Homebrew镜像安装 Homebrew国内如何自动安装&#xff0c;运行命令/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" 会…

2024年,游戏行业还值得进入吗?

来自知乎问题“2024年&#xff0c;游戏行业还值得进入吗&#xff1f;”的回答。 ——原问题描述&#xff1a;从超小厂执行策划做起&#xff0c;未来有前途吗&#xff1f; 展望2024年&#xff0c;国内外的游戏市场环境或将变得更加复杂&#xff0c;曾经那个水大鱼大的时代过去了…

ArduPilot开源飞控之MAVProxy深入研读系列 - 2蜂群链路

ArduPilot开源飞控之MAVProxy深入研读系列 - 2蜂群链路 1. 源由2. 蜂群链路2.1 拓扑结构2.2 设备标识2.3 命令列表 3. 蜂群应用4. 总结技术进步未来挑战 5. 参考资料 1. 源由 MAVProxy的一个关键功能是它能够通过UDP将来自无人机的消息转发到网络上的多个其他设备上的地面站软…

AI绘画图生图有什么用?

随着AI渗透到我们生活中的各个角落&#xff0c;AI绘画图生图的出现&#xff0c;更是在艺术领域引起了广泛的关注和讨论。那么&#xff0c;AI绘画图生图究竟有什么作用呢? 首先&#xff0c;AI绘画图生图能够极大地提高创作效率。传统的绘画过程需要艺术家们花费大量的时间和精力…

uni-app实现页面之间的跳转传参(八)

界面之间的参数传递在 开发中经常会用到,这节主要将一下uni-app开发应用是的传参情况。如下图所示,我的一级界面将点检分成三类:日点检、周点检和年保养;在点击相应的会导航到相应的功能。 在uni-app中常用的方法有uni.navigateTo(OBJECT)、uni.redirectTo(OBJECT);简单的…

一文带你学会如何部署个人博客到云服务器,并进行域名备案与解析!

哈喽&#xff0c;大家好呀&#xff01;这里是码农后端。之前我给大家介绍了如何快速注册一个自己的域名&#xff0c;并创建一台自己的阿里云ECS云服务器。本篇将介绍如何将个人博客部署到云服务器&#xff0c;并进行域名备案与解析。 1、域名备案 注册了域名并购买了云服务器之…

牛客循环5.27

1006 错误代码 不知道原因&#xff0c;有大佬解答一下吗 ac代码 1007 错误代码 ac代码

AI音乐神器Suno V3.5进化全解析:功能升级吊炸天,让音乐创作更简单!

前言 目前&#xff0c;suno的v3.5版本已经向Pro和Premier会员开放&#xff0c;从更新当天到现在我已经使用了近2000积分&#xff0c;接下来我将v3.5的使用体验和与旧版本v3进行比较&#xff0c;让大家更直观的感受到v3.5的强大。 其中一个最屌的功能&#xff0c;我放在最后介绍…

linux下cp和mv命令显示进度条

1.查看当前系统下coreutils工具包的版本号&#xff1a; [rootk8s-master ~]# rpm -qa | grep -w coreutils coreutils-8.22-24.el7_9.2.x86_64当前版本为8.22。 因为cp 和 mv 命令由 coreutils 软件包提供&#xff0c;所以需要重新下载 coreutils 软件包配置补丁 2.下载core…

创意学习剪辑利器:一键添加动图水印,轻松提升视频专业度与创意新境界!

在数字化时代&#xff0c;视频已成为我们生活中不可或缺的一部分。无论是学习分享、工作展示还是生活记录&#xff0c;视频都以其直观、生动的形式&#xff0c;赢得了广大用户的喜爱。然而&#xff0c;如何在众多的视频中脱颖而出&#xff0c;展现出自己的专业度和创意&#xf…

CI/CD:持续集成/持续部署

1. 安装docker、docker-compose # 安装Docker yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo sed -i sdownload.docker.commirrors.aliyun.com/docker-ce /…

【AD21】原理图PDF文件的输出

原理图PDF文件可以共享给团队成员&#xff0c;用于设计审核、讨论和协同工作。 菜单栏中点击文件->智能PDF。 在弹出的界面点击Next&#xff0c;勾选当前项目&#xff0c;修改文件名&#xff0c;避免与制造装备图PDF文件重名将其覆盖&#xff0c;点击Next。 只输出原理图…

谷歌AI搜索功能“翻车”,用户体验引担忧

近期&#xff0c;谷歌对其搜索引擎进行重大更新&#xff0c;推出了全新AI搜索功能“AI Overview”&#xff0c;试图通过人工智能技术提供更智能便捷的搜索体验&#xff0c;并追赶微软和OpenAI等竞争对手。然而事与愿违&#xff0c;这项备受期待的功能上线后却频频出错&#xff…

实现一个自定义 hook,用于强制刷新当前组件

写在前面 在 react 中&#xff0c;如果 state 数据发生变化&#xff0c;我们知道&#xff0c;会重新渲染该组件。 但是这个前提是我们需要依赖 state 数据的变化&#xff0c;那比如我们并不想定义 state&#xff0c;又或者说我们的操作不能引起 state 的变化&#xff0c;此时…

如何把学浪的视频保存到手机

你是不是还在为无法将学浪的视频保存到手机而烦恼&#xff1f;别担心&#xff0c;接下来我将为大家分享一个非常实用的方法&#xff0c;让你轻松实现这一目标&#xff01; 下载学浪的工具我已经打包好了&#xff0c;有需要的自己下载一下 学浪下载工具打包链接&#xff1a;百…

【408真题】2009-18

“接”是针对题目进行必要的分析&#xff0c;比较简略&#xff1b; “化”是对题目中所涉及到的知识点进行详细解释&#xff1b; “发”是对此题型的解题套路总结&#xff0c;并结合历年真题或者典型例题进行运用。 涉及到的知识全部来源于王道各科教材&#xff08;2025版&…

为什么我们会固执己见、为什么我们总认为自己是对的?

人为什么固执己见&#xff0c;是其所是&#xff0c;而非其所非&#xff1f;我们要有什么样的思维模式才能使自己有良好的判断力&#xff0c;才能作出恰当的预测和良好的决定呢&#xff1f;作者Julia Galef对TED发表演讲时提出自己的观点。以下是演讲的文字实录。 我想让你们想象…