数组一直是编程语言学习中需要重点掌握的部分,它是最基本的数据结构类型,是构成字符串及其他许多重要构造结构的基础。相对许多其他高级语言来说,C语言对数组本身提供的支持并不太多,尤其是不支持动态的数组定义

     本文总结了几种常见的数组使用中的错误用法,并通过分析原理解释错误原因,从而为掌握正确的数组用法提供帮助。同时提供了几个相对有代表性的数组的使用方式及源码,以方便学习。

指引

  • 数组定义方法及使用示例
  • 常见数组定义错误
  • 数组原理及坑
  • 矩阵乘积计算
  • 杨辉三角
  • 数组宏

数组定义方法

在C语言中,数组按如下的方法定义:

 ① 类型 数组名[数组大小];
         int array[10];char str[15];
  ② 类型 数组名[]={元素1,元素2,元素3,...};1
         int a={1,2,3,4,5};char ch[]={'a','b','c'};
  ③ 类型 数组名[数组大小]={元素1,元素2,元素3,...};2
         float x[4]={1.5, 3.2, 6.0, 23};int y[5]={1,2,3,4};

数组使用方法示例

/*在下述代码代码片段中展示了几种常见的错误
*/#define N 5int main(){/*错误形式 01: 声明数组时没有确定长度 */int array1[];/*错误形式 02:数组长度必须在进行编译初期就能确定,而不能是在运算处理中才能计算出来的结果,如宏定义 */int m=5;int array[m];/*错误形式 03: 先声明了数组,再赋值*/int array2[N];array2={1,2,3,4,5};/*错误形式 04: 赋值范围超出了开辟的空间*/int array3[N]={1,2,3,4,5,6};/*错误形式 05: 试图进行对数组的整体赋值*/int a[N]={1,2,3,4,5},b[N];b=a;return 0;
}

数组原理及“坑”

     1. 数组在定义的时候,在内存空间中为其开辟了一块连续的空间,其大小为单个数组元素类型所占大小 sizeof(type) 与元素个数N的积,即:

         size = sizeof(type) * N

    2. 同一数组内的数据元素必须一样,即即便如下述定义:

        float  x[]={1, 2, 3, 4.0, 3, 44, 27, 8};

其结果也是使得所有的元素都被强制转换为float类型!

    3. 数组一旦定义之后,数组名就表示数组的第一个元素的地址,很大程度上等同于指向该数组的指针,即:

        x==&(x[0]);//以下是关于该向量名称经常等同于指针来使用的情况的说明float *p;p = x; //或者 p = (float*)malloc(4)memset(x, 10, 4);  //将 x[0]到 x[3] 共4个位置赋值为10memset(p, 10, 4);  //将 float类型的地址从p开始到相邻的共4个位置全部赋值为10,和上一句效果相同memset(x+2, 10, 4); //将 x[2]到 x[5] 共4个位置赋值为10//数组名和指针,在以下表达式中不一样:sizeof(x) //等于数组元素的个数,即8 ,其中x的定义是 float  x[]={1, 2, 3, 4.0, 3, 44, 27, 8};sizeof(p) //等于p的类型(float类型的指针)所占空间字节数,为4;//题外话:// 在32位系统中,所有类型的指针变量都存放的是该指针在内存中的地址,所以所占用的都是4个字节; 而64位系统中,则是8个字节!

如果试图按照这样的方式进行赋值:

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

就会报错,因为这一句话相当于:

        &(y[0])=&(x[0]);

错误原因在于,左边的表达式 &(y[0]) 是一个内存中既定的地址而非一个变量符号,它不可被用于左值!3故是一种错误。

     4.正是由于上述原因,因此如果按以下方式进行数组的声明4:

        int x[5];//或者:#define N 5int x[N];

    则必须对元素分别进行赋值,且只能通过下标的方式进行5,如:

        int a[5];{a[i]=i;}   //当所有元素赋值都相同时,也可以用 memset(a, 100, 5)的方式,比较简便

     5.数组在进行函数调用时,传递给形参的值为该数组的名称 / 第一个元素的地址,因此不是值传递,在被调用函数中对数组的处理,都会导致原数组的值被改变,这一点尤其需要注意。如:

        f(int x[])   // 定义函数f(){x[2] = -1;} int array[10] = {0};f(array);    // 调用 f()处理该向量array[2] = ? // 结果是 -1, 这就是地址传递调用函数时产生的所谓的 “副作用”//  你肯定接触过的另一个例子是://  排序函数,比如 sort(array),经过sort()排序函数处理后,array向量中的各个元素被改写了

     6.数组在进行函数调用时,传递给形参的值为该数组的第一个元素的地址,在进行处理时计算机不知道该连续的数组地址到哪里结束,因此必须同时再传入一个指定的大小参数:length,见上例。

     7.二维数组的使用同一维数组完全类似,只不过每一个一维数组的元素又是一个数组而已;多维数组完全类似,只要细心处理,就不会出现错误。

矩阵计算C语言源码:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>void showYanghui(int );#ifndef MM
#define MM 5
#endif
#ifndef NN
#define NN 5
#endif
#ifndef KK
#define KK 7
#endifint main() {srand((unsigned)time(NULL));int a[MM][NN], b[NN][KK],C[MM][KK];for (int i = 0; i < MM; i++) {for (int j = 0; j < NN;j++) {a[i][j] = (int)((rand()-RAND_MAX/2)%9);}}for (int i = 0; i < NN; i++) {for (int j = 0; j < KK; j++) {b[i][j] = (int)((rand() - RAND_MAX / 2) % 9);}}/*显示a,b矩阵*/printf("matrix A=\n\n");for (int i = 0; i < MM; i++) {for (int j = 0; j < NN; j++) {printf("%3d\t",a[i][j]);}printf("\n");}printf("\n"); printf("\n");printf("matirx B=\n\n");for (int i = 0; i < NN; i++) {for (int j = 0; j < KK; j++) {printf("%3d\t", b[i][j]);}printf("\n");}/*矩阵求积*/for (int i = 0; i < MM; i++) {for (int j = 0; j < KK; j++) {int sum = 0;for (int k = 0; k < NN; k++) {sum += a[i][k] * b[k][j];}C[i][j] = sum;}}printf("\n"); printf("\n");printf("C=A*B=\n\n");for (int i = 0; i < MM; i++) {for (int j = 0; j < KK; j++) {printf("%3d\t",C[i][j]);}printf("\n");}getchar();
}

     上述代码的运行结果为:
       

     8.杨辉三角的完整实现:

#include<stdio.h>
#include<stdlib.h>#define N 20
void showYanghui(int );int main() {showYanghui(13);return 0;
}/*打印杨辉三角*/
void showYanghui(int n) {/*产生杨辉三角的存储矩阵*/int x[N][N];for (int i = 0; i < N; i++) {for (int j = 0; j < N; j++) {if (j == 0 || i == j) {x[i][j] = 1;}else {x[i][j] = x[i - 1][j - 1] + x[i - 1][j];}}}/*按照杨辉三角的显示形式显示*/for (int i = 0; i < n; i++) {for (int k = 0; k <( n-(i+1)); k++) {printf("  ");}for (int j = 0; j <= i; j++) {if (x[i][j] < 10) {printf("%4d", x[i][j]);}else if (x[i][j] < 100) {printf("%4d", x[i][j]);}else {printf("%4d", x[i][j]);}}printf("\n");}
}

     上述代码的运行结果为:
       

在宏定义中使用数组

     C语言中定义函数宏,实际上是在编译预处理时在被调用处将宏展开。通过宏定义的形式大大减少了工作量,而且有时候会使得程序运行时栈空间深度更浅,直接贴代码如下

#include<stdio.h>
#include<stdlib.h>#define SHOW_ARRAY(array){\int lengthOfArray=sizeof(array)/sizeof(array[0]);\for(int i=0;i<lengthOfArray;i++){\printf("%d\t",array[i]);\if((i+1)%5==0){\printf("\n");\}\}\printf("\n");\
}#define DISPLAY_ARRAY(str,array){\int lengthOfArray=sizeof(array)/sizeof(array[0]);\for(int i=0;i<lengthOfArray;i++){\printf("%s[%2d]=%d\t",str,i,array[i]);\if(i!=0&&(i+1)%4==0){\printf("\n");\}\}\printf("\n");\
}int main() {int vectory[] = { 53,78,35,89,23,62,22,12,62,95,27,28,8,86,32 };DISPLAY_ARRAY("vectory",vectory);printf("\n");SHOW_ARRAY(vectory);return 0;
}

     上述代码的运行结果为:
       
     其中,自定义字段“vectory”是可以随意替换的,例如换成“arr”:
       




注:


  1. 字符数组的定义 比较灵活且更加容易出错,后续专门整理. ↩
  2. 在赋值前指定大小: 这种情况也是合法的,但是绝不可以超过定义的大小,见:错误示例代码中的错误形式:04. ↩
  3. 左值/右值:在编程语言中处于赋值符号左右两边的变量值,要注意左值一般是要被赋值的。 ↩
  4. 这是C语言中唯一正确的不在定义时就赋值的数组定义方法! ↩
  5. 也叫直接寻址或直接访问方式,在访问 a[k] 时计算机内部存储器中对PC指针进行了如下运算: pc = sizeof(type)*k + &(a[0]) ↩

C语言数组使用、数组相关的宏定义剖析,及矩阵乘积、杨辉三角实例相关推荐

  1. 杨辉三角c语言用矩阵,C语言中杨氏矩阵与杨辉三角的实现方法

    一.杨氏矩阵 1.杨氏矩阵的概念 在数学中,杨表(英语:young tableau),又称杨氏矩阵.是对组合表示理论和舒伯特演算很有用的工具.它提供了一种方便的方式来描述对称和一般线性群的群表示,并研 ...

  2. c语言编程规律数阵输出,趣味C程序100.9 绘制杨辉三角

    说明:1.本问题来源于,所有程序为本人自己编写.与原程序不同之处作有标记. 2.本系列所有程序均使用codeblocks编译,操作系统为Windows XP. 问题:在屏幕上显示杨辉三角 1 1  1 ...

  3. C语言中的杨氏矩阵和杨辉三角

    系列文章目录 文章目录 系列文章目录 前言 一.杨氏矩阵 1.杨氏矩阵的概念 2.杨氏矩阵的图解 3.杨氏矩阵的实现 二.杨辉三角 1.杨辉三角的概念 2.杨辉三角的图解 3.杨辉三角的实现 总结 前 ...

  4. 【C语言练习】杨氏矩阵、杨辉三角

    目录 一:杨氏矩阵

  5. C语言每日一练——第72天:打印杨辉三角(使用两种方法)

    C语言每日一练 2022年1月5日 文章目录 题目描述 问题分析 1. 使用数组法(打印直角三角) 2. 使用数组法(打印等腰三角) 3. 使用公式法(打印等腰三角) 网上参考 题目描述 打印杨辉三角 ...

  6. C语言实例第3期:在控制台打印出著名的杨辉三角

    C语言文章更新目录 C语言学习资源汇总,史上最全面总结,没有之一 C/C++学习资源(百度云盘链接) 计算机二级资料(过级专用) C语言学习路线(从入门到实战) 编写C语言程序的7个步骤和编程机制 C ...

  7. 每日一题(42)—— 已知一个数组table,用一个宏定义,求出数据的元素个数

    已知一个数组table,用一个宏定义,求出数据的元素个数. // 总大小除以第一个元素的大小 #define TNTBL (sizeof(table)/sizeof(table[0]))

  8. 杨辉三角 c语言 二维数组

    杨辉三角的规律 c语言实现 思路:从第三行起,就要开始计算第n行的第二列到第n-1列的元素--其中每一个元素的值都是:前一行前一列元素+前一行该列元素 int main() {int arr[10][ ...

  9. 杨辉三角 C语言实现【一维数组】

    杨辉三角 C语言[一维数组] 说明 写<C语言程序设计>作业的时候想到的一个算法,只用一维数组就可以实现杨辉三角的输出(不过肯定没用存储的功能了),自己感觉挺妙的,在答案和其他地方也没看到 ...

最新文章

  1. 区块链人才月均薪酬1.6万元?
  2. U-Mail邮件系统的管理权限分配
  3. c++ thread 内存泄漏_深入剖析ThreadLocal原理、内存泄漏及应用场景
  4. 白话Elasticsearch68-ES生产集群部署重要的操作系统设置
  5. linux系统下的mysqlgt;aborted_MySQL令人头疼的Aborted告警案例分析
  6. VTK:可视化之DistanceToCamera
  7. web前端面试问答_Web服务面试问答
  8. 【牛客 - 330I】Applese 的回文串(结论题,类似编辑距离,dp)
  9. ubuntu下安装mssql(sqlserver)客户端及使用
  10. 使用函数进行邮件发送的示例
  11. 网上的很多Android项目源码有用吗?Android开发注意的地方。
  12. 工作开不开心,都在钱上
  13. 本科三级专业目录计算机类,大学本科专业目录
  14. 全国计算机自动化办公专业人才证书,办公自动化证书有什么用
  15. Altium20版本快速批量修改Comment使之与Value相同
  16. 提升文学素养【文章解读】
  17. 【华为机试真题 Python实现】一个正整数到 Excel 编号之间的转换
  18. 二、Excel大纲—基础篇
  19. 滴滴云 远程访问jupyter
  20. 适合装u盘的linux系统下载软件,ghost xp系统镜像安装win7系统下载地址适合装u盘的linux...

热门文章

  1. PG数据库版本查看方法,sql语句查pg数据库版本方法
  2. java计算机毕业设计台球收费管理系统设计与实现(附源码、数据库)
  3. 如何区别python的主程序和子程序_主程序和子程序的区别
  4. vmware17虚拟机windows超详细安装教程(详细附图)
  5. Message的使用
  6. 品果php框架_【品果科技/Camera360php后端面试】我有很认真准备这次面试的,面试我的是技术牛人-看准网...
  7. isEmpty和isBlank的区别
  8. 软件构造—ADT的理解
  9. Android color大全
  10. 1053 习题4-9-1 判断正整数位数