3-数组

61 阅读8分钟

任何数组的数组名代表数组首元素地址

知识点一:一维数组

1、数组概述

一维数组名 代表的是 数组第0个元素的地址

数组的概述

2、一维数组定义

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

//需求:请定义一个数组,该数组有10个元素每个元素为int
int arr[10];

注意(int arr[10]):

  1. 数组名arr不能和其他变量名同名

  2. 数组的元素小标是从0开始: 0~9

  3. 数组的元素分别是: arr[0]、 arr[1] ~ arr[9],如果访问arr[10]数组越界

  4. 数组的元素等价于普通变量

  5. 在定义数组的时候,[]里面的值不能变量(C89标准)

3、数组遍历

#include<stdio.h>
void test7()
{
    //局部变量,如果不初始化内容不确定 
    int arr[10];
    int i = 0;
    
    //遍历数组 
    for(i = 0;i<10;i++)
    {
        printf("%d",arr[i]);  //输出的都是不确定的值 
    }
    printf("\n");
} 

4、数组初始化

初始化:定义的时候 给 变量 或 数组元素 赋值 的动作叫 初始化

(1)全部初始化

int arr[5] = {10, 20,30, 40, 50};

//如果是全部初始化数组 元素的个数 可以省略 实际的元素个数 由初始化个数决定
int arr[] = {10,20,30, 40,50};       //少用

//错误显示
int arr[];//错误无法确定数组的大小

(2)部分初始化

//部分初始化 未被初始化 部分自动补0
int arr[5] = {10,20, 30};

//初始化数组 常见的操作 (将数组的所有元素清零)
int arr[5] = {0};	//只初始化arr[0]=0,未被初始化部分 自动补0,则全部都为0
int arr[5] = {2};//2 0 0 0 0

(3)扩展:初始化

int arr[5] = {[2] = 3, [4] = 7};//0 030 7
//[2]=3将数组的第2个元素,初始化为3
//[4]=7将数组的第4个元素,初始化为7

5、数组空间大小

  1. arr数组名作为数组类型时,代表的是数组空间的总大小

  2. 数组的总大小 = 元素的个数 * 每个元素的大小

  3. 数组元素的个数 = 数组总大小 / 每个元素的大小

#include<stdio.h>
void test1()
{
    //arr数组名作为数组类型代表的是数组空间的总大小 
    int arr [5] = {10,20,30,40,50};
    int n = 0;
    
    //数组的总大小 = 元素的个数 * 每个元素的大小 
    printf("数组的总大小:%d\n",sizeof(arr));	//数组的总大小20
    
    //数组:元素的大小    arr[0] 是数组的第0个元素
    printf("数组元素的大小=%d\n",sizeof(arr[0]));	//数组元素大小=4
    
    //数组元素的个数 = 数组总大小/每个元素的大小
    n = sizeof(arr)/sizeof(arr[0]);
    printf("数组元素的个数=%d\n",n);	//数组元素的个数=5
}
int main(int argc,char *argv[])
{
    test1();
    return 0;
}

6、数组元素的操作

数组的元素等价于普通变量

void test07()
{
    int arr[5]={1,2,3,4,5};4 int n = sizeof(arr)/sizeof(arr[0]);
    int i=0;

    //给数组元素 赋值
    arr[0] = 100;

    //num++
    arr[1]++;//arr[1]=arr[1]+1;

    //scanf("%d",&num)
    scanf("%d",&arr[2]);

    for(i=0;i<n;i++)
    {
    	printf("%d ",arr[i]);
    }
    printf("\n");
}

7、键盘获取一维数组

int arr [5] = {0};
int i = 0;
    
for(i=0;i<n;i++)
{
    scanf("%d",&arr[i]);
}

知识点二:二维数组

1、二维数组定义

a 的地址 == &a[0] 地址 == a[0]的地址 == &a[0][0]的地址

二维数组地址分析
//格式:
	数据类型 数组名[行数][列数];

//定义一个数组,该数组有3个元素,每个元素又是一个数组,此数组有4个元素,每个元素为 int 类型
    int arr [3][4];

2、二维数组的遍历

int i=0;
int j = 0;
//遍历第i列
for(i=0;i<3;i++)
{
    //遍历第j行    
    for(j = 0;j<4; j++)
    {
        printf("%d ",arr[i][j] )
    }
}

3、二维数组初始化

不管是数值还是字符的二维数组,在初始化的时候是可以省略行标的,行数由具体初始化元素个数和列数决定出所需要的行数

分段初始化:用{}里面的{}明确的表示一行

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

连续初始化:放满一行才能放下一行

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

4、键盘获取二维数组

int i,j = 0;
int arr [3][4] = {0};
for(i=0;i<3;i++)
{
    for(j=0;j<4;j++)
    {
        scanf("%d",&arr[i][j]);
    }
}

知识点三:一维字符数组

字符数组:本质是数组,只是数组的每个元素是字符

1、字符数组初始化

//初始化:逐个字符初始化 不推荐
char str[6] = {'h','e','l','l','o'};	//str[0] == 'h'的ASCII值

//初始化:以字符串的形式 初始化 推荐
char str[6] = "hello";

2、逐个字符初始化和字符串初始化区别

在没有确定 数组个数 的前提下,逐个字符初始化系统不会添加'\0' ,以字符串初始化系统会给字符串添加  '\0'

%s:输出的内容从数组的第0个元素开始逐个元素输出直到遇到 '\0' 结束,逐个字符初始化用 %s 输出由于没有 '\0' 所以后面会导致出现乱码等情况,而用字符串初始化输出则不会

int main(int argc,char *argv[])
{
    char str1[] = {'h','e','h','e'};	//逐个字符初始化 系统不会添加'\0'
    char str2[] = "hehe";	//以字符串初始化 系统会给字符串添加'\0'

    //空间大小
    printf("sizeof(str1)=%d\n", sizeof(str1));	//4
    printf("sizeof(str2)=%d\n", sizeof(str2));	//5

    //%s输出的内容 从数组的第0个元素开始逐个元素输出 直到遇到'\0'结束
    printf("str1 = ##%s##\n", str1);	//##hehe0  ##,出现乱码
    printf("str2 = ##%s##\n", str2);	//##hehe##
    return 0;
}

3、字符数组遍历

void test02( )
{
    char str[6]="hello";
    
    //方法一:逐个字符遍历
    int i=0;
    for(i=0;i<6;i++)
    {
        printf("%c",str[i]);
    }
    printf("\n---------------\n");
    
    //方法二:字符数组可以整体遍历推荐
    printf("%s\n",str);
    
    //方法三:使用puts输出
    puts(str);
}

4、获取键盘字符串

scanf 和 %s 使用缺点:遇到空格会结束输入

gets缺点:获取键盘输入的时候不会管buf的大小容易造成内存污染

void mian()
{
    char buf[128] = "";	//定义一个字符数组有足够大的空间
    char buf1[10] = "";	
    printf("请输入两个个字符串\n");
    
    //第一种方式
    scanf("%s", buf);	//不能获取带空格的字符串
    //第二种方式
    gets(buf1);	//输入超出字符数组空间

    printf("buf = %s\n", buf);
    printf("buf = %s\n", buf1);	//照样获取打印
}

fgets:既可以获取带空格的字符串也可以保证buf的不越界

#include<stdio. h> 
/*
* s:表示存放字符串的空间地址
* size 能够提取字符中的最大长度 size-1
* stream写成stdin(标准输入设备) 表示标准输入设备
*/
char *fgets(char *S,int size, FILE *stream )
//返回值:就是获取到的字符串的首元素地址
void main()
{
    char buf[10] = "";
    printf("请输入一个字符串\n");

    fgets(buf, sizeof(buf), stdin);	//推荐,12345 12345 12345

    printf("buf=%s\n", buf);	//12345 123
}

知识点四:二维字符数组

1、字符数组初始化

一维字符数组是存放 多个字符

二维字符数组是存放 多个字符串,每个字符串占一行

//不管是数值还是字符 的二维数组 在初始化的时候 是可以省略行标的 行数由具体初始化决定
char str[3][16] = {"hehe","haha","heihei"};

//str[0]就是第一行存放hehe的首地址,输出整个字符str[0],输出字符串里的某个字符str[0][3]
二维字符数组解析
#include<stdio.h>
int main(int argc,char *argv[])
{
    char arr [3][16] = {"hehe","haha","heihei"};
    
    //输出一个字符串  仅仅使用行标
    printf("%s\n",arr[0]);		//hehe
    printf("%s\n",arr[1]);		//haha
    printf("%s\n",arr[2]);		//heihei
    
    //输出的是 字符串中的某个字符 必须用行标和列标 
    printf("%s\n",arr[1][3]);	//a
}

2、获取键盘字符串

应用场景:

  • 将键盘需要输入 多个独立的字符串 用户必须单独存储好

  • 输入的字符串个数决定了二维数组的行数输入

  • 字符串中的最大长度决定了二维字符数组的列数

#include<stdio.h>
void test01()
{
    / /hehe haha xixi heihei
    char buf[4][16] = {""};
    int i = 0;
    //获取键盘字符串 
    for(i=0;i<4;i++)
    {
        scanf("%s",buf[i]);         //buf[i]已经代表是第i行的首元素地址
        //scanf("%s",&buf[i][0]);  
        //&buf[i][O] == & *(buf[i]+0) == buf[i] + 0 == buf[i]
    } 
    for(i=0;i<4;i++)
    {
        printf("buf[%d]=%s\n",i,buf[i]);
    }
}
int main(int argc,char *agrv[])
{
    test01();
}