C语言数组(一维数组和二维数组)

一维数组

1.作用

需要保存大量的类型相同的数据

比如:保存全班同学的成绩

2.定义数组

类型名 数组名[数组元素个数]

任何合法的C语言类型,都可以定义成数组

char array[10];  	//最多可以存放10个字符
int  array[50]; 	//最多可以存放50个整数

3.数组的初始化以及赋值

(1)初始化以及赋值
写法一:

int a[5]={45,85,74,96,63};   //列表初始化 
char b[10]="hello";

写法二:

int a[5]={45,25};               //部分初始化,其它没有初始化的都是0 
char b[10]={'h','e','l','l','o'};

写法三:

int a[]={85,96};            //[]不写元素个数,只能在定义数组的时候立马初始化才可以
char b[]="world";

写法四:

int a[];                    //错误写法
a[0]=78;

写法五:

int a[3];    //定义了数组,但是没有初始化
a[3]=88;     //数组越界了,下标0--2

写法六: 把数组前面50个元素初始化为100,后面50个初始化为200

int b[100]={[0 ... 49]=100, [50 ... 99]=200};

注意:…左右两边必须要有空格
下面是具体实例:

  • int类型数组
#include <stdio.h>

int main()
{
    int i;
    //写法1:定义数组,不初始化  结论:里面是随机数
    // int buf[5];
    
    //写法2:定义数组马上完全初始化  结论:里面的值就是初始化的值
    // int buf[5] = {11,22,33,44,55};
    
    //写法3:定义数组部分初始化  结论:没有初始化的默认都是0
    // int buf[5] = {11,22};
    
    //写法4:定义数组没有初始化,后面通过下标来赋值  结论:没有赋值的为随机数
    // int buf[5];        //定义时数组中为随机数
    // buf[2] = 11;    //11把原来的随机数覆盖了
    // buf[3] = 22;    //22把原来的随机数覆盖了
    
    //写法5:定义数组,省略括号中的元素个数(编译器根据右值确定数组元素个数) 结论:没有赋值的为随机数
    // int buf[] = {11,22}; //正确的
    
    // int buf[];  //错误的  error: array size missing in ‘buf’ :数组大小丢失
    // buf[0] = 11;
    // buf[1] = 22;
    
    //访问数组中的元素:通过下标(从0开始)来访问
    // for(i=0;i<5;i++)
    // {
    //     printf("buf[%d]数组中的元素值是:%d\n",i,buf[i]);
    // }
    
    // 写法6:笔试题中会出
    // 把数组前面50个元素初始化为100,后面50个初始化为200 
    // 结论:buf[0]-buf[49] 为100,buf[50]-buf[99] 为200
    // 注意:...左右两边必须要有空格
    int buf[100] = {[0 ... 49] = 100,[50 ... 99] = 200};
    for(i=0;i<100;i++)
    {
        printf("buf[%d]数组中的元素值是:%d\n",i,buf[i]);
    }
}

/*
执行结果:
写法1:
    buf[0]数组中的元素值是:0
    buf[1]数组中的元素值是:0
    buf[2]数组中的元素值是:-1373101952
    buf[3]数组中的元素值是:21909
    buf[4]数组中的元素值是:1211320880
写法2:
    buf[0]数组中的元素值是:11
    buf[1]数组中的元素值是:22
    buf[2]数组中的元素值是:33
    buf[3]数组中的元素值是:44
    buf[4]数组中的元素值是:55
写法3:
    buf[0]数组中的元素值是:11
    buf[1]数组中的元素值是:22
    buf[2]数组中的元素值是:0
    buf[3]数组中的元素值是:0
    buf[4]数组中的元素值是:0
写法4:
    buf[0]数组中的元素值是:0
    buf[1]数组中的元素值是:0
    buf[2]数组中的元素值是:11
    buf[3]数组中的元素值是:22
    buf[4]数组中的元素值是:-500139952
写法5:
    buf[0]数组中的元素值是:11
    buf[1]数组中的元素值是:22
    buf[2]数组中的元素值是:-1912202240
    buf[3]数组中的元素值是:-1254381533
    buf[4]数组中的元素值是:0


*/
  • char类型数组初始化—赋值
#include <stdio.h>

int main()
{
    int i;
    char buf[5] = "hello";
    
    //打印数组中的元素(%c与%s的区别)
    //第一种:与int类型的数组一样,一个一个元素打印
    for(i=0;i<5;i++)
    {
        printf("buf[%d] = %c\n",i,buf[i]);
    }
    
    //第二种,整个字符串一起打印
    printf("数组中存放的字符串是:%s\n",buf);
}


/*
执行结果:
    buf[0] = h
    buf[1] = e
    buf[2] = l
    buf[3] = l
    buf[4] = o
    数组中存放的字符串是:hello

*/
  • char数组存放键盘输入的字符串
#include <stdio.h>

int main()
{
    int i;
    char buf[5];
    
    printf("输入一个字符串:\n");
    //写法1:
    scanf("%s",buf);
    //写法2:(正常不这样写)
    // for(i=0;i<5;i++)
    // {
    // scanf("%c",&buf[i]);
    // }
    
    printf("输入的字符串是:%s\n",buf);
    return 0;
}


/*
执行结果:
写法1:
    输入一个字符串:
    nihao 
    输入的字符串是:nihao
    
写法2:
    输入一个字符串:
    h 
    l
    l
    输入的字符串是:h
    l
    l
结论:键盘输入的字符是存放在输入输出缓冲区的,当输入字符后回车(\n)也算为一个字符,
        所以输入输入的顺序为h\nl\nl,循环读取5个字符的结果为hll。
*/

4.数组元素的下标

从0开始,使用的时候不要越界
数组越界的危害(容易引起段错误)

int a[10]; //下标范围0--9之间

第一种:往前越界

a[-2];  //访问a[0]前面8个字节的地址里面的数据

第二种:往后越界

a[11];  //访问a[9]后面8个字节的地址里面的数据

段错误:segment fault
由于程序员在代码中访问了非法地址导致的(经常见于指针没有初始化,数组越界)

示例:

#include <stdio.h>

int main()
{
    int i;
    int buf[5] = {11,22,33,44,55};
    
    //段错误:访问了非法内存地址
    //for(i=0;i<10000;i++)   //往后越界
    // for(i=0;i>-10000;i--)   //往前越界
    for(i=0;i<10;i++)
    {
        printf("buf[%d] = %d\n",i,buf[i]);
    }
    
    return 0;
}

/*
执行结果:
    buf[0] = 11
    buf[1] = 22
    buf[2] = 33
    buf[3] = 44
    buf[4] = 55
    buf[5] = 32766
    buf[6] = -1878191872
    buf[7] = -155369220
    buf[8] = 0
    buf[9] = 0
    
结论:因为只定义了buf[0]-buf[4]的内存,如果buf[5]之后的内存被其它程序所占用的话,程序员在使用这块内存,
    就会引发段错误。(现在这个程序没引发段错误是因为buf[5]-buf[10]这块
    内存没被其它程序使用,把i<10改为10000就会引发段错误了)


*/

5.数组的存储

数组在计算机中是连续存储(数组元素的地址是紧挨着的)

在这里插入图片描述

6.数组的大小

sizeof(); //求任何类型数据的大小

示例:

#include <stdio.h>

int main()
{
    int a[5];
    float b[5];
    double c[5];
    char d[50] = "hello world";
    //求sizeof大小公式:元素个数*sizeof(类型)
    //1、
    printf("数组的大小:a:%ld,b:%ld,c:%ld,d:%ld\n",sizeof(a),sizeof(b),sizeof(c),sizeof(d));
    
    //2、
    char buf1[] = "hello";
    int buf2[] = {11,22};
    printf("数组大小:buf1:%ld,buf2:%ld\n",sizeof(buf1),sizeof(buf2));
    
    return 0;
}

/*
执行结果:
1、
    数组的大小:a:20,b:20,c:40,d:50
2、
    数组大小:buf1:6,buf2:8
*/

strlen(); //专门用来求字符串的实际长度
#include <string.h>
size_t strlen(const char *s);
返回值:字符串的实际长度
参数:s --》你要计算长度的字符串
原理:计算字符串实际长度,遇到\0认为字符串结束了

示例:

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

int main()
{
    char array[64] = "hello world";  //11个字符,空格也算一个字符
    
    //求字符串的实际长度
    printf("数组array中存放的字符串长度是:%ld\n",strlen(array));
    
    return 0;
}

/*
执行结果:
    数组array中存放的字符串长度是:11
*/

总结:
第一:sizeof是运算符 strlen是个函数
第二:sizeof适用范围广 strlen只能求字符串的实际长度
第三:sizeof求字符串的长度会把\0算上
strlen求字符串的长度不计算\0

字符串在计算机中的存储方式

字符串默认有一个结束标记\0(ASCII码值就是0)

char buf[10]="hello"; //编译器会自动给字符串的末尾添加\0,
char buf1[5]="hello"; //本来编译器想自动添加\0,但后面没内存了

在这里插入图片描述

要注意的特例

char buf[]={'h','e','l','l','o'}; //sizeof求出是5,没有加\0  ;strlen求出是5
char buf[]="hello";   //sizeof求出是6(加上了\0) ;strlen求出是5
  • 特别说明:

scanf读取字符串保存到数组会自动添加反斜杠0

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

int main()
{
    int i;
    char array[64];  //11个字符,空格也算一个字符
    
    //求字符串的实际长度
    printf("输入任意字符串:");
    scanf("%s",array);
    
    //证明输入的字符串后面是否自动添加了\0
    for(i=0;i<10;i++)
    {
        printf("输出字符:%c ,  ASCII值:%d\n", array[i],array[i] );
    }

    return 0;
}

/*
执行结果:
    输入任意字符串:dfgdfdff
    输出字符:d ,  ASCII值:100
    输出字符:f ,  ASCII值:102
    输出字符:g ,  ASCII值:103
    输出字符:d ,  ASCII值:100
    输出字符:f ,  ASCII值:102
    输出字符:d ,  ASCII值:100
    输出字符:f ,  ASCII值:102
    输出字符:f ,  ASCII值:102
    输出字符: ,  ASCII值:0
    输出字符:� ,  ASCII值:-25

结论:在字符串后的一个数的ASCII值必定是0,即对应的字符为'\0',
    是编译器自动帮程序员加上去的
*/

ps:%s打印字符串遇到 \0 就结束

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

int main()
{
    //1、%s打印字符串时遇到 \0 就结束打印
    char array[20] = {'h','e','l','l','\n','o','\0','o','o',};
    printf("打印array的值为: %s,大小为:%ld\n",array,sizeof(array));
    
    //2、strlen求字符串的实际长度,遇到\0就结束,不会把\0计算进去
    printf("array实际长度:%ld\n",strlen(array));
    return 0;
}

/*
执行结果:
1、
    打印array的值为: hell
    o,大小为:20
2、
    array实际长度:6
*/

7.空字符串,'A’和"A"的区别

char buf[10]="";  //空字符串
'a';  //字符a      单个字符
"a";  //字符串a    a和\0

8.char类型数组重复使用,清空数组

1)char类型数组重复使用

char buf[10];
while(1)
{
    scanf("%s",buf);  //假如第一次输入的字符串长一点,下一次输入的字符串短一点,scanf都会自动帮你在字符串后面添加\0保存到buf中,短一点的字符串覆盖长字符串的前面部分,并且有个\0在后面(容易忽略)
}

示例:

#include <stdio.h>

int main()
{
    char array[64];
    
    while(1)
    {
        printf("输入一个字符串:");
        scanf("%s",array);
        printf("输入的字符串是:%s\n",array);
    }
        
    return 0;
}

/*
执行结果:
    输入一个字符串:helloworld
    输入的字符串是:helloworld
    输入一个字符串:nihao
    输入的字符串是:nihao
*/

2)清空数组

数组先清空后使用(数组不清空,里面是随机数)

写法一:

#include <strings.h>
void bzero(void *s, size_t n); //把数组元素全部填充为0
参数: s --》数组名
n --》数组的大小

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

int main()
{
    int i;
    char array[8] = {0};
    printf("输入字符串:");
    scanf("%s",array);
    printf("输入的字符串是:%s\n",array);
    
    //把数组清零:任何类型的数组都可以使用bzero清零  ,如int,double(使用方法一样)
    bzero(array,sizeof(array));
    // printf("清空后的字符串为:%s\n",array); //清空后无任何输出
    printf("清空后的字符串为:\n");
    for(i=0;i<8;i++)
    {
        printf("arrray[%d]ASCII值:%d\n",i,array[i]);
    }
    
    return 0;
}

/*
执行结果:
    输入字符串:nihao
    输入的字符串是:nihao
    清空后的字符串为:
    arrray[0]ASCII值:0
    arrray[1]ASCII值:0
    arrray[2]ASCII值:0
    arrray[3]ASCII值:0
    arrray[4]ASCII值:0
    arrray[5]ASCII值:0
    arrray[6]ASCII值:0
    arrray[7]ASCII值:0

*/

写法二:

初始化的时候就把数组清零

int buf[10]={0}; //部分初始化的原理,其他没有初始化的默认都是0,把数组清零
char buf[5]={0}; //部分初始化的原理,其他没有初始化的默认都是0,把数组清零

9.数组怪异的写法

int buf[10];
buf[0]=11; //等价于0[buf]=11;

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

int main()
{
    int i;
    char array[8] = {0};
    array[0] = 'h';
    1[array] = 'e';
    2[array] = 'l';
    array[3] = 'l';
    4[array] = 'o';
    printf("array中存放的是:%s\n",array);
    
    return 0;
}

/*
执行结果:
    array中存放的是:hello
*/

二维数组

1.作用

int a[5][6];   //行列存放整数,有5行,每一行最多可以存放6个整数,总共可以存放30个整数

char b[5][10]; //可以存放5个字符串,每个字符串的最大长度不能超过10个字节,用来保存多个字符串

2.定义二维数组

类型名 数组名[行数][列数]

任何合法的C语言类型,都可以定义成二维数组

char buf[10][20];  //最多存放10个字符串,每个字符串的长度不能超过20个字符

int  buf1[50][50]; //50行整数,每一行最多50个整数

3.二维数组的初始化以及赋值

写法一:

int a[5][6]={45,78,96};    //部分初始化,正确 
char b[3][10]={"hello","world","gec"};
	[0][0] [0][1] [0][2] ....[0][5]
	[1][0] [1][1] [1][2] ....[1][5] 
	......
 	[4][0] [4][1] [4][2] ....[4][5] 

写法二:

int a[][6]={89,9};          //正确
char b[][10]={"hello","world","nihao"};

写法三:

int a[][]={89,9};           //错误`

写法四:

int a[5][]={89,9};          //错误

写法五:

int a[5][6]={{5},{8,9},{89,63}};  //正确,分组初始化 
//分组初始化必须从左到右连续(花括号不要跳跃)
int a[5][6]={{5},8,9,{89,63}};  //错误的写法,不满足从左到右连续(花括号中间跳跃了)
char b[3][10]={{'h','e','l','l','o'},{'n','i','h','a','o'}}

写法六:

int a[5][6]={{5},{8,9},89,63};    //正确

写法七:

int a[5][6];  //分别赋值
	a[0][0]=99;
	a[1][2]=67;
char b[3][10];
	b[0][1]='h';

4.数组元素的下标

行和列都是从0开始,使用的时候不要越界

5.二维数组的存储

二维数组在计算机中是连续存储(数组元素的地址是紧挨着的)

二维数组:你可以把它看作是特殊的"一维数组"
可以把二维数组拆分成多个一维数组

在这里插入图片描述

6.二维数组的大小

情况一:两个下标都有

int a[5][6];  //公式 行*列*sizeof(类型)

情况二:少了行下标,笔试题常考

int a[][6]={78,96};  //依据初始化列表中值的个数,确定有几行
  • int类型二维数组的写法
#include <stdio.h>

int main()
{
    int i,j;
    //写法1:部分初始化(任何数组部分初始化,其它的都是0)
    //int array[3][3] = {12,34,56,78,666};
    
    //写法2:省略中括号里面的下标
    // int array[][3] = {342,346,346,47,25,66};  //正确
    // int array[5][] = {342,346,346,47,25,25};  //错误
    // int array[][] = {342,346,346,47,25,25};  //错误
    
    //写法3:分组初始化(只能从左往右连续分组,不可以间断)
    // int array[3][3] = {{12,34},{56,78},{90,88}};//正确
    // int array[3][3] = {{12,34},{56,78},666};    //正确
    // int array[3][3] = {{12,34},666,{90,88}};//错误
    // int array[3][3] = {666,{56,78},{90,88}};//错误
    
    //分组初始化跟省略中括号结合
    int array[][5] = {{12,34},{56,78},{123},234,46,57,23,23,11};
    printf("sizeof(array)==%ld\n",sizeof(array));  //100
    //访问数组元素
    for(i=0;i<5;i++)  //行
    {
        for(j=0;j<5;j++)   //列
        {
            printf("array[%d][%d] = %d\n",i,j,array[i][j]);
        }
    }
    
    return 0;
}



/*
执行结果:
写法1:
    array[0][0] = 12
    array[0][1] = 34
    array[0][2] = 56
    array[1][0] = 78
    array[1][1] = 666
    array[1][2] = 0
    array[2][0] = 0
    array[2][1] = 0
    array[2][2] = 0

*/
  • char类型二维数组的写法
#include <stdio.h>

int main()
{
    int i,j;
    //写法1:部分初始化(任何数组部分初始化,其它的都是0)
    char  array[5][10] = {"hello","nihao","wohenhao"};
    
    //写法2:分组初始化(只能从左往右连续分组,不可以间断)
    // int array[5][10] = {{'h','i'},{'n','i'},'w'};//正确
    
    //访问数组元素
    for(i=0;i<5;i++)  //行
    {
        for(j=0;j<10;j++)   //列
        {
            printf("array[%d][%d] = %c  ACSII值:%d\n",i,j,array[i][j],array[i][j]);
        }
    }
    
    //char类型二维数组跟int类型二维数组,输入输出不一样的写法
    //读取键盘输入不同的写法
    
    // scanf("%d",&array[i][j]);  //int类型二维数组 唯一写法
    // scanf("%c",&array[i][j]);  //char类型二维数组  一个个字符输入,敲回车也是一个字符
    
    char array1[5][10];
    printf("输入5个字符串:\n");
    for(i=0;i<5;i++)
    {
        scanf("%s",array1[i]);        //char类型二维数组,只需要使用行下标 
    }
    //打印结果
    printf("输入的字符串保存到二维数组中\n");
    for(i=0;i<5;i++)
    {
        printf("array1[%d] = %s\n",i,array1[i]);
    }
    
    return 0;
}
  • 23
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值