C语言数组的使用复习

文章详细介绍了C语言中一维数组和二维数组的定义、初始化方法,以及它们与指针的关系。在函数参数中,数组通常以指针形式传递,允许在函数内部修改数组内容。二维数组按行优先存储,可以被视为数组的数组。此外,文章还讨论了动态数组的概念,强调了初始化时需注意的数组大小问题。
摘要由CSDN通过智能技术生成

一、一维数组

1.1定义

一维数组的定义需要指定数组长度,方法有两种,一种是通过数组标号指定,另一种是数组标号留空,使用初始化值得个数指定长度。如下:

char a[5];
char a[] = {1,1,1,1,1}; 
1.2初始化

一维数组得初始化没什么好说得。需要知道的是,局部变量的值是随机值,对于局部数组变量来说,只要指定一个元素值进行初始化,那么其他未指定得元素值都会被初始化未0。

1.3 一维数组与指针

一维数组的数组名指向数组元素首地址,也是数组首元素的地址。即:char a[3];则a = &a[0]。

换句话说一个指向一维数组的指针p:char *p = a。就类似于char p[3],有p + i = a + i,p[i] = a[i] , *(p + i) = p[i] 。

注意点:

①是p++是可以的,= p + sizeof(数组元素类型),但a不可以进行++操作。

②指向数组的指针在移动的时候,是以数组元素类型为单位的,比如char型数组,指向它的指针每加1,就是走1byte,int型数组,指向它的指针每加1,指针地址就走4byte。容易犯错。

1.4 一维数组作为函数参数

(1)使用数组名做函数参数,那么也就类似是指针做参数,如果在函数中修改了数组的内容。在上层函数中实参数组的内容也就被修改了。

(2)函数的形式参数可以是数组名,也可以是指针: void test(char c[])或void test(char *p)

二、二维数组

2.1定义

二维数组的元素在内存中的存放是行优先,先顺序存放行的所有数据,再接着存放下一行的所有数据。

①不带初始化的定义:必须指定两个维度的长度。

②带初始化的定义:[]中必须指定列维度的长度,这样编译器能计算行数。

如下:

char a[3][2];
char a[][2] = {1,1,1,1,1};  
2.2初始化

二维数组得初始化也没什么好说得。需要知道的是,局部变量的值是随机值,对于局部数组变量来说,只要指定一个元素值进行初始化,那么其他未指定得元素值都会被初始化未0。

2.3 二维数组与指针

(1)二维数组可以看作数组的数组,a为数组名,有三个元素分别是a[0],a[1],a[2],这三个元素有都是一维数组的数组名(或者地址)。因此二维数组的数组a也可以看作是指针数组。写出如下形式

char *p[3] = {a[0],a[1],a[2]};

(2)a指向数组名a指向数组元素首地址,也是数组首行地址,也就是首行首列元素地址。即:

 a = a[0] = &a[0][0]

(3)二维数组行地址:a+i 或者a[i]就是第i行首地址。二维数组列元素地址a[i]+j表示第i行第j列元素地址。

a[i] <==> a +i <==> *(a + i),都表示的第i行的地址。

(4)指向元素的指针和指向一维数组的指针

char *p = a[0];//表示p指向首行地址,p+1表示a[0][1]地址
char (*p)[2] = a;//p是指向一个有2个元素的一维数组的指针,这里就表示p指向二维数组a的第0行。自然p+1或p[1]表示第1行地址。

2.4 二维数组作为函数参数

有以下几种方式:

(1)形参以二维数组的形式

形参中至少必须要指定第二维的大小:因为有第二维长度就可以计算第一维长度了。另外编译器不会检查形参的第一维长度,所以形参第一维长度无所谓。

函数形参:void func(char array[][2])
传递实参:func(a)
在函数func中对二维数组的使用:可直接使用array[i][j]

(2)形参使用指向一维数组的指针,实参采用二维数组名

函数形参:void func(char (*array)[2])
传递实参:func(a)
在函数func中对二维数组的使用:可直接使用array[i][j]

(3)形参采用指向指针的指针,实参采用指针数组

函数形参:void func(char **array)
传递实参:实参不能直接用二维数组名这些,需要转换以下: 
        char *p[3] = {a[0],a[1],a[2]};
        func(p,3,5);
在函数func中对二维数组的使用:可直接使用array[i][j]

2.5 例题

/*题目:对数组元素为0的元素,则将其所在行和列所有元素都设置为0,clear_array的空间复杂度要小于O(m*n)
 *思路就是:遍历每个元素,记录为0时候的坐标,遍历完以后把所有i代表的行清0,j代表的列清0
 *涉及知识点:多维数组的使用:作为函数参数的用法 
*/
#include <stdio.h>
typedef char elemType;
​
elemType a[3][5] ={
    0,2,1,3,4, 
    2,6,0,1,5,
    1,1,1,0,9
};
​
void clear_array(elemType **array, int x, int y);
​
int main(void)
{
    /* 对多维数组求行、列的方式 */
    int row,column;
    row = sizeof(a)/sizeof(a[0]) ;
    printf("row = %d\n",row);
    
    column = sizeof(a[0])/sizeof(elemType);
    printf("column = %d\n",column);
​
    elemType *p[3] = {a[0],a[1],a[2]};
    
    clear_array(p,row,column); 
    
#if 1   //打印查看结果 
    int i,j;
    for(i=0; i < row; i++)
    {
        for(j=0; j < column; j++)
        {
            printf("%d,",a[i][j]);
        }
        printf("\n");
    }
#endif
​
    return 0;
}
​
void clear_array(elemType **array, int x, int y)
{
    int i,j;
    elemType column[y];
    memset(column,0,y*sizeof(elemType)); 
    
    for(i=0; i < x; i++)
    {
        for(j=0; j < y; j++)
        {
            if(array[i][j] == 0)
            {
                column[j] = 1;//记录下为0的列号 
                memset(&array[i][0],0,y*sizeof(elemType));//该行清0
                break;//某行有0,那么就不用再检查该行剩下的数据了 
            }           
        }    
    }
    
    //现在来处理列
    for(j=0; j < y; j++)
    {   
        if(column[j] != 0)
        {
            for(i=0; i < x; i++)
            {
                array[i][j] = 0;
            }           
        }
​
    }
}

三、动态数组的定义和初始化

动态数组,指的是数组的大小,依赖于程序运行过程中的结果变量的值。

如:

动态数组定义:
    scanf("%d",&array_len);
    char b[array_len];

定义是可以的,但初始化不能在定义的时候给其赋值,因为此时arrray_len还未知,编译器编译的时候不知道要给该数组b分配多少内存空间。

错误的初始化方式:
    scanf("%d",&array_len);
    char b[array_len] = {0};

两种正确的初始化方式:

方式1:使用for循环进行初始化清0

    scanf("%d",&array_len);
    char b[array_len];  
    for(j=0; j < array_len; j++)
    {
        b[j]=0;
    }

方式2:使用memset进行初始化清0

    scanf("%d",&array_len);
    char b[array_len];  
    memset(b,0,array_len);
注意:这种方式需要注意,memset函数参数3表示byte数,所以这里需要根据数组数据类型,乘上相应的数据size。如:数组是int型,那么这里要memset的参数3,要修改为array_len * sizeof(int)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值