使用“include”使包含的任何子单元都可以访问数组;单位c;?
如何确保从main.c调用的unit.c函数需要在main.c函数中正确声明数组 有没有办法在.c文件中全局声明变量?有没有一种不使用全局变量的聪明方法 例如:使用“include”使包含的任何子单元都可以访问数组;单位c;?,c,global-variables,C,Global Variables,如何确保从main.c调用的unit.c函数需要在main.c函数中正确声明数组 有没有办法在.c文件中全局声明变量?有没有一种不使用全局变量的聪明方法 例如: #include <stdio.h> #include "sub.c" int main(void) { int matrix[5][5]; matrix[5][1] = 5; Range(); } 现在出现的问题是,现在编译时会出现这样的错误 "In file included from mai
#include <stdio.h>
#include "sub.c"
int main(void)
{
int matrix[5][5];
matrix[5][1] = 5;
Range();
}
现在出现的问题是,现在编译时会出现这样的错误
"In file included from main.c:
"sub.c:3:15: Error: Matrix not declared"
或者类似的东西。良好的编程实践要求使用它们作为参数,因此选项是:
#include <stdio.h>
#include "sub.h"
int main(void)
{
int matrix[5][5];
matrix[5][1] = 5;
Range(matrix);
}
您应该有一个头文件,其中包含您需要调用和包含的函数的原型。我认为你没有包括.c文件 您还需要将参数传递给函数 如果需要跨文件访问变量,则需要使用extern variable。因此,有几件事:
/**
* sub.h - declaration for Range function
*/
#ifndef SUB_H // include guards; prevents this file from being processed
#define SUB_H // more than once for the same translation unit
/**
* Changing the type of Range to void since you aren't returning anything, and you
* aren't using the result of the function in your main function
*/
void Range( /* parameter declarations, which we'll get into below */ );
#endif
void Range( int m[][5] )
x = m[20][1];
void Range(int m[][5], size_t rows);
void Range(int m[][5] size_t rows, size_t i, size_t j)
{
if ( i < rows && j < 5 )
printf("Your range is: %d\n", m[i][j];
}
然后您将#将此文件作为
#include <stdio.h>
#include "sub.h"
int main( void )
{
int Matrix[5][5];
Matrix[5][1] = 5; // this is an error; your array dimensions only go from 0 to 4
Range( /* parameters, including Matrix, which we'll get into below */ );
}
然后表达式矩阵
的类型是“5元素数组的5元素数组的int
”。由于此表达式不是sizeof
或一元&
运算符的操作数,因此它被转换为“指向int
的5元素数组指针”类型的表达式,并且该值是数组第一行的地址(与数组本身的地址相同)。这意味着您的范围
函数将声明为
void Range( int m[][5] )
x = m[20][1];
void Range(int m[][5], size_t rows);
void Range(int m[][5] size_t rows, size_t i, size_t j)
{
if ( i < rows && j < 5 )
printf("Your range is: %d\n", m[i][j];
}
或者(第二个声明中的括号很重要;没有它们,m
将被声明为指向int
的指针数组,这不是我们想要的)。
在函数参数声明的上下文中,ta[]
和ta[N]
都被解释为ta*a
;也就是说,a
被声明为指向T
的指针,而不是T
的数组。
注意,由于您将数组的地址传递给函数,因此函数对数组所做的任何更改都将反映在调用方中;也就是说,如果Range
更改m[4][0]
的值,您将在矩阵[4][0]
中看到更改后的值。
m
的列数,所以我们希望传递一个额外的参数来指定行数。C不会对数组访问执行任何边界检查,这意味着您可以编写类似这样的代码,而不会在编译时收到警告或保证在运行时崩溃。因此,您需要自己进行边界检查,这意味着您需要知道数组除了列数之外还有多少行。您将为行数传递一个单独的参数:
void Range( int m[][5] )
x = m[20][1];
code>Range(Matrix, 5);
void Range(int m[][5], size_t rows);
void Range(int m[][5] size_t rows, size_t i, size_t j)
{
if ( i < rows && j < 5 )
printf("Your range is: %d\n", m[i][j];
}
m
中的列数固定为5;此函数将无法处理其他大小的矩阵。如果你是
使用支持可变长度数组1的编译器时,可以使用变量来指定数组维度,而不是使用编译时常量。由于在数组声明中使用变量之前需要声明该变量,因此必须将原型编写为
void Range( size_t rows, size_t cols, int m[][cols] );
并将函数调用为
Range(5, 5, Matrix);
这将允许您在不同大小的矩阵上使用Range
函数,例如:
int M1[5][5];
int M2[9][9];
int M3[20][20];
...
Range(5, 5, M1);
Range(9, 9, M2);
Range(20, 20, M3);
你会称之为
Range(&Matrix[0][0], 5, 5);
Range(Matrix, 5, 4, 0);
矩阵[5][1]
中存在一个元素;但是,C中的数组是0原点,这意味着这两个维度的索引都是从0到4。因此,要访问第五行的第一个元素,请参考矩阵[4][0]
<代码>矩阵[5][1]超出了数组的范围。
这还带来了一个问题,即您是否希望检查除
m[4][0]
之外的元素。如果希望函数访问数组的任意元素,则需要将行数和列数作为单独的参数传递;这与将数组的维度作为参数传递相结合,为您提供了一种确保您没有试图访问数组边界之外的元素的方法。因此,您的范围
函数看起来像
void Range( int m[][5] )
x = m[20][1];
void Range(int m[][5], size_t rows);
void Range(int m[][5] size_t rows, size_t i, size_t j)
{
if ( i < rows && j < 5 )
printf("Your range is: %d\n", m[i][j];
}
5
。首先,如果您决定更改数组维度,则只需更新常量定义,而不必追踪文本5
的每次出现,并确定它是否用于检查数组访问。将以上所有因素综合起来(假设您对Range
仅处理特定大小的数组没有问题),我们得到:
/**
*sub.c-范围功能的实现
*/
#包括
#包括“sub.h”
无效范围(int m[][COLS],大小\u t行,大小\u t i,大小\u t j)
{
if(i
/**
*main.c
*/
#包括
#包括“sub.h”
内部主(空)
{
int矩阵[行][COLS];
矩阵[4][0]=5;//假设我们知道4和0在
范围(矩阵,行,4,0);//数组边界。
}
那么,你完全糊涂了吗
1.C99编译器或C2011编译器,其中宏uuu STDC_NO_VLA_uuuu未定义或为0。一些C89编译器可能支持VLA作为扩展 你能举一个例子(即使它不能编译)说明你想编译什么吗