【C语言】数组使用注意点

数组的初始化

  1. 一维数组
  • 初始化部分元素
	int buff[5] = {10, 8, 1};
    for(int i = 0; i < 5; i++)
        printf("%3d", buff[i]);
//输出结果为: 10  8  1  0  0

表示只给buff[0] ~ buff[2]3个元素赋值,而后面2个元素自动初始化为 0。

当赋值的元素少于数组总体元素的时候,不同类型剩余的元素自动初始化值说明如下:

对于 short、int、long,就是整数 0;
对于 char,就是字符 ‘\0’;
对于 float、double,就是小数0.0;
对于指针类型,就是NULL。

  • 全部初始化为0
	int buff[5] = {0};
    for(int i = 0; i < 5; i++)
        printf("%3d", buff[i]);
//输出结果为:  0  0  0  0  0
  • 逐个赋值,不能给数组整体赋值
  	int buff[5] = {5, 8, 6, 1, 74};
    for(int i = 0; i < 5; i++)
        printf("%3d", buff[i]);
//输出结果为:  5  8  6  1 74
  1. 二维数组
    定义二维数组时,必须给出第二维,第一维可省略。
  • 初始化部分元素
    int buff[3][4] = {
    {1, 2},
    {5, },
    {9, 10, 11, 12}
    };
    for(int i = 0; i < 3; i++)
    {
        for(int j = 0; j < 4; j++)
        {
            printf("%3d", buff[i][j]);
        }
        printf("\n");
    }
/*输出结果为:
  1  2  0  0
  5  0  0  0
  9 10 11 12
*/
  • 全部初始化为0
    int buff[3][4] = {0};
    for(int i = 0; i < 3; i++)
    {
        for(int j = 0; j < 4; j++)
        {
            printf("%3d", buff[i][j]);
        }
        printf("\n");
    }
/*输出结果为:
  0  0  0  0
  0  0  0  0
  0  0  0  0
*/
  • 逐个赋值
    int buff[3][4] = {
    {1, 2, 3, 4},
    {5, 6, 7, 8},
    {9, 10, 11, 12}
    };
    for(int i = 0; i < 3; i++)
    {
        for(int j = 0; j < 4; j++)
        {
            printf("%3d", buff[i][j]);
        }
        printf("\n");
    }
/*输出结果为:
  1  2  3  4
  5  6  7  8
  9 10 11 12
*/

求取数组的元素个数

  1. 一维数组
#include <stdio.h>


int main(void)
{
    int buff[5] = {0};
    printf("数组元素个数:%u\n", sizeof(buff) / sizeof(buff[0]));
    //printf("数组元素个数:%u\n", sizeof(buff) / sizeof(*buff));
}
  1. 二维数组
#include <stdio.h>


int main(void)
{
    int buff[4][5] = {0};
    printf("数组行数:%u\n", sizeof(buff) / sizeof(buff[0]));
    //printf("数组行数:%u\n", sizeof(buff) / sizeof(*buff));
    printf("数组列数:%u\n", sizeof(buff[0]) / sizeof(buff[0][0]));
    //printf("数组列数:%u\n", sizeof(*buff) / sizeof(**buff));
}

传递数组给函数

  1. 一维数组

方式一

#include <stdio.h>


int getSum(int buff[], int count)
{
    int sum = 0;
    while(count--)
    {
        sum += buff[count];
    }
    return sum;
}


int main(void)
{
    int buff[] = {1,2,3,4,5};
    int sum = getSum(buff, 5);
    printf("%d\n", sum);
}

方式二

#include <stdio.h>


int getSum(int *buff, int count)
{
    int sum = 0;
    while(count--)
    {
        sum += *buff++;
    }
    return sum;
}


int main(void)
{
    int buff[] = {1,2,3,4,5};
    int sum = getSum(buff, 5);
    printf("%d\n", sum);
}

函数的参数中,数组类型参数 int buff[]本质是指针 可以直接换成 int *buff;

  1. 二维数组

方式一
第一维的长度可以不指定,但必须指定第二维的长度

#include <stdio.h>


int getSum(int buff[][4], int m, int n)
{
    int sum = 0;
    int temp = n;
    while(m--)
    {
        while(n--)
        {
            sum += buff[m][n];
        }
        n = temp;
    }
    return sum;
}


int main(void)
{
    int buff[3][4] = {
    {1, 2, 3, 4},
    {5, 6, 7, 8},
    {9, 10, 11, 12}
    };
    int sum = getSum(buff, 3, 4);
    printf("%d\n", sum);
}

方式二
指向一个有5个int类型的元素一维数组的指针

#include <stdio.h>


int getSum(int (*buff)[4], int m, int n)
{
    int sum = 0;
    int temp = n;
    while(m--)
    {
        while(n--)
        {
            sum += *(*(buff + m) + n);
        }
        n = temp;
    }
    return sum;
}


int main(void)
{
    int buff[3][4] = {
    {1, 2, 3, 4},
    {5, 6, 7, 8},
    {9, 10, 11, 12}
    };
    int sum = getSum(buff, 3, 4);
    printf("%d\n", sum);

}

方式三
利用数组是顺序存储的特性,通过降维来访问原数组!

#include <stdio.h>


int getSum(int *buff, int m, int n)
{
    int sum = 0;
    int temp = n;
    while(m--)
    {
        while(n--)
        {
            sum += *(buff + m * temp + n);
        }
        n = temp;
    }
    return sum;
}


int main(void)
{
    int buff[3][4] = {
    {1, 2, 3, 4},
    {5, 6, 7, 8},
    {9, 10, 11, 12}
    };
    int sum = getSum(*buff, 3, 4);
    printf("%d\n", sum);
}

将二维数组当作参数的时候,必须指明所有维数大小或者省略第一维的,但是不能省略第二维或者更高维的大小,这是由编译器原理限制的。
事实上,编译器是这样处理数组的:设有二维数组 int buff[m][n],如果要访问 buff[i][j]的值,编译器的寻址方式为:
&buff[i][j] = &buff[0][0] + i * n + j;

从函数返回数组

C 语言不允许返回一个完整的数组作为函数的参数。但是,您可以通过指定不带索引的数组名来返回一个指向数组的指针。
如果您想要从函数返回一个一维数组,您必须声明一个返回指针的函数。

  1. 一维数组
#include <stdio.h>


int* func(int num)
{
    static int buff[10] = {0};

    for(int i = 0; i < 10; i++)
    {
        buff[i] += num;
    }
    return buff;
}


int main(void)
{
    int *p = NULL;
    p = func(10);
    for(int i = 0; i < 10; i++)
    {
        printf("%5d", p[i]);
    }
}
/*
输出结果
   10   10   10   10   10   10   10   10   10   10
*/
  1. 二维数组

方式1
将buff作为函数参数

#include <stdio.h>


void func(int (*buff)[4], int m, int num)
{
    for(int i = 0, j = 0; i < m; i++)
        for(j = 0; j < 4; j++)
            *(*(buff + i) + j) += num;
}


int main(void)
{
    int buff[3][4] = {0};
    func(buff, 3, 11);
    for(int i = 0, j = 0; i < 3; i++)
    {
        for(j = 0; j < 4; j++)
        {
            printf("%4d", buff[i][j]);
        }
        printf("\n");
    }
}
/*
输出结果
  11  11  11  11
  11  11  11  11
  11  11  11  11
*/

方式2
返回二维数组

 int (*func(int num))[4]
{
    static int buff[3][4] = {0};
    for(int i = 0, j = 0; i < 3; i++)
        for(j = 0; j < 4; j++)
            *(*(buff + i) + j) += num;
    return buff;
}

一般用typedef来定义一种新类型,这样便于理解。

typedef int (*arr)[4];

arr func(int num)
{
    static int buff[3][4] = {0};
    for(int i = 0, j = 0; i < 3; i++)
        for(j = 0; j < 4; j++)
            *(*(buff + i) + j) += num;
    return buff;
}

指向数组的指针

记住这句话:数组名是一个指向数组中第一个元素的常量指针。

  1. 一维数组

实例

#include <stdio.h>


int main(void)
{
    int buff[] = {1, 2, 3, 4, 5, 6};
    int *p = buff;

    printf("buff:%p\n", buff);
    printf("p:%p\n", p);
    printf("&buff:%p\n", &buff);
    printf("&buff[0][0]:%p\n", &buff[0]);
}
/*
输出结果
buff:000000000061FE00
p:000000000061FE00
&buff:000000000061FE00
&buff[0][0]:000000000061FE00
*/

虽然输出结果的数值是一样的,但是这四个还是有区别的。

buffbuff是数组名,所以buff是一个指向第一个元素的常量指针,即&buff[0];buff是一个指向int类型的常量指针,即int * const buff;
pp是指向int类型的指针,与buff的区别是:p是变量,而buff是常量。实例中p指向了数组第一个元素。
&buff对数组名进行取地址操作,得到的应该是整个数组的地址。数组的元素个数为6,(&buff + 1)得到的是增大整个数组内存大小的地址:增大4 x 6 = 24。另外(*(&buff + 1)) - buff = 6; &buff是指向6个int类型数据的指针。
&buff[0]对数组第一个元素取地址,得到就是第一个元素的地址值。

下面的代码有助于理解&buff

#include <stdio.h>


int main(void)
{
    int buff[] = {1, 2, 3, 4, 5, 6};
    int *p = buff;

    printf("buff:%p\n", buff);
    printf("p:%p\n", p);
    printf("&buff:%p\n", &buff);
    printf("&buff[0][0]:%p\n", &buff[0]);

    printf("(*(&buff + 1)):%p\n", (*(&buff + 1)));
    printf("(*(&buff + 1)) - buff:%u个元素\n", (*(&buff + 1)) - buff);
    printf("(*(&buff + 1)) - buff:%u个字节\n", ((*(&buff + 1)) - buff) * sizeof(int));
}
/*
输出结果
buff:000000000061FE00
p:000000000061FE00
&buff:000000000061FE00
&buff[0][0]:000000000061FE00
(*(&buff + 1)):000000000061FE18
(*(&buff + 1)) - buff:6个元素
(*(&buff + 1)) - buff:24个字节
*/
  1. 二维数组

实例

#include <stdio.h>


int main(void)
{
    int buff[3][4] = {
    {1, 2, 3, 4},
    {5, 6, 7, 8},
    {9, 10, 11, 12},
    };
    int (*p)[4] = buff;

    printf("buff:%p\n", buff);
    printf("p:%p\n", p);
    printf("*buff:%p\n", *buff);
    printf("**buff:%d\n", **buff);
    printf("buff[0]:%p\n", buff[0]);
    printf("*buff[0]:%d\n", *buff[0]);
    printf("&buff[0]:%p\n", &buff[0]);
    printf("&buff[0][0]:%p\n", &buff[0][0]);

    printf("\n每行有4个int类型数据\n");
    printf("buff + 1:%p\n", buff + 1);
    printf("**(buff + 1):%d\n", **(buff + 1));
    printf("p + 1:%p\n", p + 1);
    printf("buff[1]:%p\n", buff[1]);
    printf("*buff[1]:%d\n", *buff[1]);
    printf("&buff[1]:%p\n", &buff[1]);
    printf("&buff[1][0]:%p\n", &buff[1][0]);

}
/*
输出结果
buff:000000000061FDE0
p:000000000061FDE0
*buff:000000000061FDE0
**buff:1
buff[0]:000000000061FDE0
*buff[0]:1
&buff[0]:000000000061FDE0
&buff[0][0]:000000000061FDE0

每行有4个int类型数据
buff + 1:000000000061FDF0
**(buff + 1):5
p + 1:000000000061FDF0
buff[1]:000000000061FDF0
*buff[1]:5
&buff[1]:000000000061FDF0
&buff[1][0]:000000000061FDF0
*/
buffbuff是数组名,数组的第一个元素是一个一维数组;&buff[0],即buff是指向4个int类型数据的常量指针,即 int (* const buff)[4];
pp是一个指向4个int类型数据的指针
*buff对buff进行取值操作,得到一个指向int类型数据的指针;等价于buff[0]
**buff对buff进行两次取值操作,得到一个第一个元素的值;等价于buff[0][0], *buff[0]
buff[0]指向int类型数据的指针
*buff[0]等价于buff[0][0], **buff
&buff[0]等价于buff
&buff[0][0]得到第一个元素的地址

问题
在仅知道数组名和维度情况下,怎么获得数组最后一个元素的值?

  1. 一维数组
#include <stdio.h>


int main(void)
{
    int buff[] = {1, 2, 3, 4, 5, 6};
    printf("数组最后一个元素的值为:%d\n", *(*(&buff + 1) - 1)) ;
}
/*
输出结果
数组最后一个元素的值为:6
*/
  1. 二维数组
#include <stdio.h>


int main(void)
{
    int buff[3][4] = {
    {1, 2, 3, 4},
    {5, 6, 7, 8},
    {9, 10, 11, 12},
    };
    printf("数组最后一个元素的值为:%d\n", *(**(&buff + 1) - 1));
}
/*
输出结果
数组最后一个元素的值为:12
*/
  1. 三维数组
#include <stdio.h>


int main(void)
{
    int buff[2][2][2] = {
    {{1, 2}, {3, 4}},
    {{5, 6}, {7, 8}}
    };
    printf("数组最后一个元素的值为:%d\n", *(***(&buff + 1) - 1)) ;
}
/*
输出结果
数组最后一个元素的值为:8
*/
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值