精华内容
下载资源
问答
  • C语言多维数组初始化

    千次阅读 2019-05-28 13:41:00
    由于剧情,需要C语言实现图像算法。但作为一名MATLAB老用户,根本不知“指针”“内存”为何物。开始自信满满,结果连初始化一个二维全零矩阵都不会(尴尬)。 顾从零学起,在此总结,供跟我一样的选手学习交流。


    by HPC_ZY


    由于剧情,需要纯C(不用三方库)实现图像算法。但作为一名MATLAB老用户,根本不知“指针”“内存”为何物。开始自信满满,结果连初始化一个二维全零矩阵都不会(尴尬),顾从零学起,在此总结。
    今后会持续更新MATLAB函数的C实现,欢迎交流,共同学习。

    .
    注:C语言博大精深,实现方法众多。由于本文主题是M2C,所以在方法和格式上会尽量贴近MATLAB。还望各大C佬请勿吐槽。
    .


    一、常用数据类型对照

    MATLAB C 字节数
    char char 1
    uint8 unsigned char 1
    uint16 unsigned short int 2
    int32 int 4
    single float 4
    double double 8

    利用sizeof(type)函数可返回类型的字节数

    /*关于数据类型*/
    printf("  MATLAB - C - Byte\n");
    printf("( char = char ) %d\n", sizeof(char));
    printf("( uint8 = unsigned char ) %d\n", sizeof(unsigned char));
    printf("( uint16 = unsigned short int) %d\n", sizeof(unsigned short int));
    printf("( int32 = int) %d\n", sizeof(int));
    printf("( single = float ) %d\n", sizeof(float));
    printf("( double = double ) %d\n", sizeof(double));
    

    在这里插入图片描述


    二、一维数组初始化

    MATLAB

    Num = 10;
    mat1d1 = zeros(1,Num);  % 默认为double
    mat1d2 = zeros(1,Num,'uint8');
    

    C

    // 内存分配
    int Num = 10;
    double mat1d1[10];  // 数组法
    unsigned char *mat1d2 = (unsigned char*)malloc(Num * sizeof(unsigned char));  // 指针法
    // 值初始化
    memset(mat1d1, 0, Num * sizeof(double));
    memset(mat1d2, 0, Num * sizeof(unsigned char));
    // 查看
    printf("mat1d1:");
    for (int k = 0; k < Num; k++)
    	printf("%.0f ", mat1d1[k]);
    printf("\nmat1d2:");
    for (int k = 0; k < Num; k++)
    	printf("%d ", mat1d2[k]);
    

    在这里插入图片描述

    1. 两种方法写法的区别
      (写法)
      使用数组法时,数组大小只能使用常量,不能填入变量,如:
      double mat[Num]; (此为错误)
      但数组法可在定义时,赋初始值,如:
      int mat[5] = {1,2,3,4,5};
      (大小)
      数组法内存在栈中,空间小,能支持的数组尺寸小;
      指针法内存在堆中,空间大,能支持大尺寸数组。
      因此对于尺寸固定的小数组可使用数组法,其他推荐使用指针法

    2. 关于memset()函数
      三个参数分别为(变量指针,初值,字节数);
      对于uint8类型,初值可设为0~255
      其他类型建议仅在初始值为0时使用menset(),如需赋其他值,可使用for循环。
      (具体原因感兴趣可自行学习menset()的原理)

    3. 关于sizeof()
      如果熟悉类型的字节数,可直接写入,如:
      int* mat = (int*)malloc( 10 * sizeof(int) );
      int* mat = (int*)malloc( 10 * 4 );


    三、多维数组初始化

    特别注意指针法内存分配与赋初值的方式

    1、二维

    MATLAB

    Rows = 2, Cols = 3;
    mat2d1 = zeros(Rows,Cols,'int32');
    mat2d2 = zeros(Rows,Cols);
    

    C

    int Rows = 2, Cols = 3;
    // 数组法
    int mat2d1[2][3];
    memset(mat2d1, 0, Rows * Cols * sizeof(int));
    // 指针法
    double **mat2d2 = NULL;  
    mat2d2 = (double**)malloc(Rows * sizeof(double*));  
    for (int r = 0; r < Rows; r++){
    	mat2d2[r] = (double*)malloc(Cols * sizeof(double));
    	memset(mat2d2[r], 0, Cols * sizeof(double));
    }
    // 查看略
    

    在这里插入图片描述

    2、三维

    MATLAB

    Rows = 2, Cols = 2, Dims = 3;
    mat2d1 = zeros(Rows,Cols,Dims,'int32');
    mat2d2 = zeros(Rows,Cols,Dims);
    

    C

    int Rows = 2, Cols = 2, Dims = 3;
    // 数组法
    int mat3d1[3][2][2];
    memset(mat3d1, 0, Rows * Cols * Dims * sizeof(int));
    // 指针法
    double ***mat3d2 = NULL;
    mat3d2 = (double***)malloc(Dims * sizeof(double**));
    for (int d = 0; d < Dims; d++)
    	mat3d2[d] = (double**)malloc(Rows * sizeof(double*));
    for (int d = 0; d < Dims; d++)
    for (int r = 0; r < Rows; r++){
    	mat3d2[d][r] = (double*)malloc(Cols * sizeof(double));	
    	memset(mat3d2[d][r], 0, Cols * sizeof(double));
    }
    // 查看略
    

    在这里插入图片描述

    1. 指针法赋初值时,不可直接使用如下格式:
      memset(mat2d2 0, Rows * Cols * sizeof(double));
      memset(mat3d2 0, Rows * Cols * Dims * sizeof(double));
    2. 定义三维数组,建议将Dims放第一维。因为做三维图像处理时,经常需要提取某一帧图像。如一个尺寸为**V(512, 512, 100)**的体数据,提取第10帧图像,则
      MATLAB: frame10 = V(:, :, 10);
      C: double ** frame10 = V[9];

    其他

    以上仅为使用方案,关于原理不做讲述。想深入研究的选手,可自行百度以下内容:

    1. 数据类型
    2. 数组
    3. 指针
    4. malloc
    5. memset
    6. 堆栈
    展开全文
  • 原标题:单片机C语言多维数组多维数组对于二维数组a[4][6];由于数组名代表数组的起始地址,所以a(第一层)和第一个元素a[0][0]地址的数字是相同的,但是意义却是不同的。 对于该数组我们可以理解为:a的一维数组(第一...

    原标题:单片机C语言多维数组

    多维数组

    对于二维数组a[4][6];由于数组名代表数组的起始地址,所以a(第一层)和第一个元素a[0][0]地址的数字是相同的,但是意义却是不同的。 对于该数组我们可以理解为:a的一维数组(第一层),它有四个元素a[0]、a[1]、a[2]、a[3](第二层),而每个元素又含有6个元素a[0] [0],a[0][1],a[0][2],a[0][3],a[0][4],a[0][5](第三层),…到此我们终于访问到了每个元素了,这个过程我们 经历了:a->a[0]->a[0][0];

    整体来讲:a是一个4行5列的二维数组,a表示它指向的数组的首地址(第一个元素地址&a[0]),同时a[0]指向一行,它是这个行的名字 (和该行的第一个元素的首地址相同(第一个元素为地址&a[0][0]))。所以从数字角度说:a、a[0]、&a[0][0]是相同 的,但是他们所处的层次是不同的。

    既然a代表二维数组,那么a+i就表示它的第i+1个元素*(a+i)的地址,而在二维数组中

    *(a+i)又指向一个数组,*(a+i)+j表示这个数组的第j+1个元素的地址,所以要访问这个元素可以使用 *(*(a+i)+j)(也就是a[i][j])。

    他们的示意图为(虚线代表不是实际存在的):

    ebcc41e5f3ca160ccb4215e2e8738dec.png

    对照这个图,如下的一些说法都是正确的(对于a[4][6]):

    a是一个数组类型,*a指向一个数组;

    a+i指向一个数组;

    a、*a和&a[0][0]数值相同;

    a[i]+j和*(a+i)+j是同一个概念;

    总结一下就是:我们对于二维指针a,他指向数组a[0,1,2,3],使用*,可以使他降级到第二层次,这样*a就指向了第一个真正的数组。对于其他的情况我们也可以采用相同的方式,对于其他维数和类型的数组我们可以采用相类似的思想。

    说到指向数组的指针,我们还可以声明一个指针变量让它指向一个数组。例如:

    int (*p)[5];

    这时p就是一个指针,要指向一个含有5个int类型元素的数组,指向其他的就会出现问题。这个时候我们可以使用上面的什么东西来初始化呢?我们可以使用*a,*(a+1),a[2]等。原因很简单:我们在一个二维的数组中,那么表达方式有上面的相互类似的意义呢?只有 *a,*(a+1),a[2]等。

    本文章来源网络,如果原作者不支持咱们转发,请联系删除,谢谢!

    技术源于积累,成功来自执着返回搜狐,查看更多

    责任编辑:

    展开全文
  • c语言 多维数组c语言 多维数组一、高维数组有时,数组的维数并不止一维,例如一个记录消费中心在第一季度里各个月的收入数据就可以用二维数组来表示。定义二维数组的方法是在一维数组定义的后面再加上一个用方括号括...

    c语言 多维数组

    c语言 多维数组

    一、高维数组

    有时,数组的维数并不止一维,例如一个记录消费中心在第一季度里各个月的收入数据就可以用二维数组来表示。定义二维数组的方法是在一维数组定义的后面再加上一个用方括号括起来的维数说明。例如:

    float array[3][8];

    实际上,这个数组可以看成3个连续的一维数组,每个一维数组具有8个元素。该数组在内存中的存储格式为最左边的维数相同的元素连续存储,也即按行存储的。首先存储第一行8个元素,其次是第二行,最后是第三行。

    main()

    {

    int array[3][3]={1,2,3,4,5,6,7,8,9};

    int i,j;

    for(i=0;i<3;i++)

    {

    for(j=0;j<3;j++) printf(%3d);

    printf(\n);

    }

    }

    它的输出结果为:

    1 2 3

    4 5 6

    7 8 9

    可以看出,二维数组元素是按行存储的。

    我们也可以对数组进行赋值,而不是初始化。

    main()

    {

    int array[3][3];

    int i,j;

    for(j=0;j<3;j++)

    for(i=0;i<3;i++) scanf(%d,&array[i][j]);

    for(i=0;i<3;i++)

    {

    for(j=0;j<3;j++) printf(%3d);

    printf(\n);

    }

    }

    当输入1 2 3 4 5 6 7 8 9

    输出为:

    1 4 7

    2 5 8

    3 6 9

    数组可以是二维、三维甚至是更高维数的,虽然C语言对维数的处理没有上限,但是处理高维数组是很头疼的事。一般尽量避免处理四维和四维以上的数组。下面看一个三维数组的例子:

    main()

    {

    int array[2][3][4];

    int i,j,k;

    for(i=0;i<2;i++)

    for(j=0;j<3;j++)

    for(k=0;k<4;k++) array[i][j][k]=i*12+j*4+k;

    }

    这个三维数组可以看成2个二维数组,每个二维数组又可以看成3个一维数组。可以在头脑里想象成两个平行平面,每个平面内有3*4个点。所以共有24个元素。

    二、字符串数组

    上面讲的都是存放数值的,有一类数组,用来处理字符串的,我们叫字符串数组。其实字符串数组也是二维数组,只是它的特殊性,才单独拿出来说的。

    main()

    {

    char s[10][10];

    int i;

    for(i=0;i<10;i++) scanf(%s,s[i]);

    }

    先看它的输入特性,前面在说输入语句的时候说过,遇到字符串输入,可以不加'&',现在只要记住这个特性就可以,以后说指针的时候再讲为什么。但是这儿为什么用s[i],可能很多人不太明白。我们定义的是二维数组,而输入的时候,却使用一维数组的形式。这是因为字符串在内存里地址可以用它的名字表示,就好象这种形式:

    main()

    {

    char s[10];

    scanf(%s,s);

    }

    定义的是一维数组,输入语句用变量形式表示一样。通过前面的'%s'形式可以看出,s[i]是一个数组,所以s就是二维数组了。

    这里要注意一点,scanf()函数在输入字符串时候不能支持空格,看下面的例子:

    main()

    {

    char s[3][10];

    int i;

    for(i=0;i<10;i++)

    scanf(%s,s[i]);

    for(i=0;i<3;i++)

    printf(%s\n,s[i]);

    }

    我们输入:1111

    2222 3333

    4444

    我们是想把1111赋值给s[0],2222 3333赋值给s[1],4444赋值给s[2]。可实际上编译器是这样做的,把1111赋值给s[0],把2222赋值给[1],把3333赋值给s[2]。

    实际输出:1111

    2222

    3333

    在输入字符串的时候,如果使用scanf(),就把空格当作下一个输入了。那么我们怎么解决这个问题呢?毕竟很多情况下,一行字符串肯定有空格出现的。我们使用新的函数gets()。这个函数是专门接受字符串输入的,它跳过了空格的影响。把上面的输入语言修改为gets(s[i])即可。

    我们定义了char s[3][10],超过10个字符肯定不行,如果少于10个字符,电脑怎么处理呢?电脑是在每个字符串的后面自动补上'\0',作为字符串的结束标志。

    我们经常在填写一些可选择的内容时经常发现,待选的字符串都是按字母排列好的,我们怎么用C语言实现这个功能?在C语言里,字符串的排序是按照字符的ASCII码来的,如果第一个字符一样,则比较第二个,依次类推。

    main()

    {

    char s1[6]=addfgh,s2[5]=asdlg;

    int i;

    for(i=0;s1[i]!='\0'&&s2[i]!='\0';i++)

    {

    if(s1[i] {

    printf

    展开全文
  • C语言基础第7章多维数组7.2 二维数组及多维数组二维数组的定义定义方式: 数据类型 数组名[常量表达式][常量表达式];;二维数组理解;二维数组元素的引用形式: 数组名[下标][下标]二维数组元素的初始化分行初始化...

    C语言基础第7章多维数组

    7.2 二维数组及多维数组二维数组的定义定义方式:  数据类型 数组名[常量表达式][常量表达式];;二维数组理解;二维数组元素的引用形式: 数组名[下标][下标]二维数组元素的初始化分行初始化:;程序举例;例 求二维数组中最大元素值及其行列号;例 读入下表中值到数组,分别求各行、各列及表中所有数之和;7.3 字符数组和字符串字符数组定义 ; 例 char diamond[][5]={{'.', '.','*'},{'.','*','.','*'}, {'*', '.', '.', '.' ,'*'},{'.','*', '.','*'},{'.', '.','*'}};

    ;例 输出一个字符串;字符串字符串及其结束标志无字符串变量,用字符数组处理字符串字符串结束标志:‘\0’;字符串的输入输出逐个字符I/O: %c整个字符串I/O: %s;例 main( ) { char a[5]={‘H’,’e’,’l’,’l’,’o’}; printf(“%s”,a); };main(){ char a[]={'h','e','l','\0','l','o','\0'}; printf("%s",a);};main(){ int i; char a[5]; scanf("%s",a); for(i=0;i<5;i++) printf("%d,",a[i]);};例 字符串输入举例;例 若准备将字符串“This is a string.”记录下来,错误的输入语句为:(A)scanf(“%20s”,s);(B)for(k=0;k<17;k++) s[k]=getchar();(C)while((c=getchar())!=‘\n’) s[k++]=c;;常用的字符串处理函数包含在头文件 string.h;字符串连接函数strcat格式:strcat(字符数组1,字符数组2)功能:把字符数组2连到字符数组1后面返值:返回字符数组1的首地址说明:?字符数组1必须足够大 ?连接前,两串均以‘\0’结束;连接后,串1的‘\0’取消, 新串最后加‘\0’;例 strcpy与strcat举例;字符串比较函数strcmp格式:strcmp(字符串1,字符串2)功能:比较两个字符串比较规则:对两串从左向右逐个字符比较(ASCII码), 直到遇到不同字符或‘\0’为止返值:返回int型整数,a. 若字符串1< 字符串2, 返回负整数 b. 若字符串1> 字符串2, 返回正整数 c. 若字符串1== 字符串2, 返回零说明:字符串比较不能用“==”,必须用strcmp;#include #include main(){ char str1[] = ”Hello!", str2[] = ”How are you?”,str[20]; int len1,len2,len3; len1=strlen(str1); len2=strlen(str2); if(strcmp(str1, str2)>0) { strcpy(str,str1); strcat(str,str2); } else if (strcmp(str1, str2)<0) { strcpy(str,str2); strcat(str,str1); } else strcpy(str,str1); len3=strlen(str); puts(str); printf(”Len1=%d,Len2=%d,Len3=%d\n”,len1,len2,len3);};应用举例;当前字符=空格;例 有三个字符串,找出其中最大者;例 有十个学生的成绩,求平均分;例 比较 int a[2][3]={{5,6},{7,8}}; 与 int a[2][3]={5,6,7,8};

    展开全文
  • C语言多维数组遍历教程C语言for循环遍历多维数组详解语法for (i = 0; i < row; i++){for (j = 0; j < col; j++){//arr[i][j]}}参数参数描述arr数组名。row二维数组的行数。col二维数组的列数。说明我们使用 ...
  • 多维数组初始化 多维数组的遍历: 数组综合题: [------慕课网:https://www.imooc.com/learn/249] 冒泡排序: 以升序排序为例冒泡排序的思想:相邻元素两两比较,将较大的数字放在后面,直到将所有数字全部排序。 ...
  • 多维数组对于二维数组a[4][6];由于数组名代表数组的起始地址,所以a(第一层)和第一个元素a[0][0]地址的数字是相同的,但是意义却是不同的。 对于该数组我们可以理解为:a的一维数组(第一层),它有四个元素a[0]、a[1]...
  • 一、多维数组地址的表示方法设有整型二维数组a[3][4]如下:0 1 2 34 5 6 78 9 10 11设数组a的首地址为1000,各下标变量的首地址及其值如图所示。在前面曾经介绍过, /data/c/C语言允许把一个二维数组分解为多个一维...
  • 多维数组与多级指针也是初学者感觉迷糊的一个地方。超过二维的数组和超过二级的指针其实并不多用。如果能弄明白二维数组与二级指针,那二维以上的也不是什么问题了。所以本节重点讨论二维数组与二级指针。 一、二...
  • 【嵌入式开发】C语言 指针数组 多维数组

    万次阅读 热门讨论 2014-03-19 01:52:05
    ① 模拟C语言中内存分配策略 ;...④ 多维数组 作为参数的时候, 其列数 不能省略 行可以省略, 否则就找不到指针数组中的其它指针了 ; ⑤ 指针数组 和 二维数组 , 指针数组用于存储长度可变的数组, 更节省空间 ;
  • C 语言支持多维数组多维数组声明的一般形式如下:type name[size1][size2]...[sizeN];例如,下面的声明创建了一个三维 5 . 10 . 4 整型数组:int threedim[5][10][4];二维数组多维数组最简单的形式是二维数组。一...
  • 多维数组与多级指针也是初学者感觉迷糊的一个地方。超过二维的数组和超过二级的指针其实并不多用。如果能弄明白二维数组与二级指针,那二维以上的也不是什么问题了。所以本节重点讨论二维数组与二级指针。 一、...
  • C语言多维数组的存储表示和实现

    千次阅读 2016-12-25 00:21:40
    * 其实多维数组的表示与实现只要理解了那个表示每个数据位置的公式和链表的操作就很简单了 */ #include #include #include #define ElemType int #define FALSE 0 #define TRUE 1 #define ARRAY_MAX_SIZE 8 ...
  • 当我们声明数组,引用的时候。当数组索引值超出数组元素个数会怎么样?深入理解C语言数组的内存分布。
  • p 指向一个 int 数组元素, p + i 的地址时数组中第 i 个元素的地址, 即 p + i 指向 第 i 个元素; 存储分配示例函数 :  -- char *alloc(int n) 函数 : 传入分配的字符个数, 返回连续字符存储单元指
  • 多维数组5.1 声明5.2 初始化二维数组5.3 访问二维数组元素5.4 二维数组元素遍历5.5 二维数组输入5.6 简化5.7 多维数组6. `const`数组6.1 `const`数组是什么?6.2 `const`数组怎么用? 5.多维数组 5.1 声明 语法...
  • C语言字符数组应用及程序C语言字符数组的应用用来存放字符量的数组称为字符数组。7.1.1字符数组的定义形式与前面介绍的数值数组相同。...7.1.2字符数组初始化字符数组也允许在定义时作初始化赋值。例...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,491
精华内容 3,396
关键字:

c语言多维数组初始化

c语言 订阅