【问题标题】:Share variables between functions in C99在 C99 中的函数之间共享变量
【发布时间】:2020-04-29 11:59:56
【问题描述】:
  1. 接收来自主matrix_1 的输入,我需要创建一个新的并仅打印奇数。现在我从函数打印它,但我需要从main() 打印它;我该怎么做?
#include <stdio.h>
#define len 4

void copiaDispari();

int main () {

    int i, j, matrix_1[len][len];

    for (i=0; i < len; i++){
        for (j=0; j < len; j++) {
            printf ("Inserisci il numero della matrice %d %d:", i, j);
            scanf ("%d", &matrix_1[i][j]);
        }
    }

    copiaDispari(matrix_1);

    for (i=0; i < len; i++){
        for (j=0; j < len; j++) {
            printf ("%d", matrix_2[i][j]);
        }
        printf("\n");
    }

    return 0;
}

void copiaDispari(int matrix_1[len][len]) {

    int matrix_2[len][len]= {{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}, i, j, l=0, m=0;


    for (i=0; i < len; i++){
        for (j=0; j < len; j++){
            if (matrix_1[i][j]%2!=0){
                if (l==4) {
                    l=0; m++;
                }
                matrix_2[m][l] = matrix_1[i][j];
                l++;
            }
        }
    }

    for (i=0; i < len; i++){
        for (j=0; j < len; j++) {
            printf ("%d", matrix_2[i][j]);
        }
        printf("\n");
    }

    return;
}
  1. 假设我必须将 5 或 6 个变量从函数 void yeah() 传递给另一个函数 void yessss();我怎样才能实现它?
  2. 什么时候应该使用 void 函数,什么时候应该使用 int 函数?

【问题讨论】:

  • 传统上使用大写的常量——例如#define LEN 4——留下小写的用于变量。看到int matrix_1[len][len] 的人认为len 是一个变量,而不是一个常数。 C99 及更高版本允许使用可变长度数组。
  • 感谢您的建议,您能帮我完成这个程序吗? [在这个练习中,我从主矩阵中获取输入,我需要使用名为 copiaDispari 的函数创建一个新矩阵,并仅使用赔率数字打印它......现在我从函数 copiaDispari 打印它,但我需要从 main() 打印它,我该怎么做?,为了做到这一点,我认为我应该以某种方式将 matrix_2 传递给 main,然后使用 2 个 for 循环我应该打印它。]跨度>
  • stackoverflow.com/questions/14088804/…查看调用者预先创建结果矩阵和被调用者动态分配结果矩阵的示例

标签: c function c99


【解决方案1】:
  1. 最简单的方法是在main() 中分配第二个数组并将其作为参数传递给函数(以及第一个数组)。

    int i, j, matrix_1[len][len], matrix_2[len][len] = { { 0 } };
    …
    copiaDispari(matrix_1, matrix_2);
    …
    void copiaDispari(int matrix_1[len][len], matrix_2[len][len])
    {
        …
    }
    

    其他技术使用动态内存管理(malloc() 等),或将数组封装在结构中并传递结构类型(您可以返回包含数组的结构;您不能从函数返回数组),或者(有时,但不经常)在函数中使用 static 数组并返回指向它的指针(不要这样做),或者使用全局变量(也不要这样做!)。

  2. 函数可以有半无限多的参数。 C11 §5.2.4.1 Translation limits 要求编译器接受至少有 127 个参数的函数定义和调用。仅仅 5 或 6 不会引起编译器的任何焦虑。但是,减少参数的数量是个好主意。

    如果你想从一个函数返回多个值,你可以将多个指针传递给函数并让它通过指针修改变量。或者你可以把这组变量包装成一个结构并传递一个指向合适结构的指针,或者你可以返回一个合适的结构给调用函数。

  3. 当函数产生一个将由调用代码使用的值时,您通常不应该使用void 函数。您可以将指针传递给变量,该函数可能会修改这些指针以返回其答案。如果函数可能失败,你可能让它在成功时返回 0,在失败时返回一些其他值;当然,这排除了它具有返回类型void。错误处理是 C 编程的主要部分。如果函数没有返回值来指示成功或失败,则很难知道是否存在问题。


顺便说一句,函数的前向声明不应该是:

void copiaDispari();

在您的原始代码中,应该是:

void copiaDispari(int m1[len][len]);

在修改后的代码中,应该是;

void copiaDispari(int m1[len][len], int m2[len][len]);

这将有助于防止错误,例如使用错误数量的参数调用函数。

您永远不应该为参数列表编写带有() 的函数声明。这表示该函数采用不确定数量的参数(但它不是像printf() 这样的可变参数列表函数)。如果函数不接受参数,请在声明中写入int function(void);,为保持一致性,在定义中写入int function(void) { … }。虽然你可以在定义中写int function() { … },但这并没有为函数提供原型,并且在同一个源文件中可能会被错误调用。请注意,C++ 在这方面与 C 不同。旧的 C 代码(在产生 C89/C90 标准之前)使用() 表示法;它别无选择。在这个千年编写的代码不应使用() 表示法。

【讨论】:

  • 嗨乔纳森,我只是不明白,当你说“最简单的方法是在 main() 中分配第二个数组并将其作为参数传递给函数(以及第一个数组)。”我知道它有效,因为我已经测试过,但功能完成后更改不应该消失吗?我的意思是我不是通过指针修改原始矩阵,而只是修改函数中的矩阵。为了清除我的想法,我尝试在 main 中声明一个变量“int a=0”,并将其传递给函数并在函数中将其修改为 a=10。然后,如果我去打印它,我会得到 0。
  • 我该如何解释?
  • 当你将数组传递给函数时,它是通过指针传递的,这意味着函数对数组内容所做的更改对调用函数是可见的——它是被修改的调用函数。所以不,当被调用的函数返回时,更改不会消失。这与整数等简单值不同,在这种情况下,被调用函数获取调用函数中值的副本,并且不会影响被调用函数中的值。
  • 因此,如果我传递一个数组或矩阵,我不必传递指针,但我可以只传递数组/矩阵本身,而如果我使用的是 int、char、string i必须使用指针吗?
  • 哦,天哪——这很快就变得复杂了。大部分是对的——我主要关心的是你在列表中放置“字符串”的位置。如果你有一个数组SomeType array[SIZE]; 并将它传递给像function(array) 这样的函数,那么类型会自动从SomeType [] 转换为SomeType *。如果你写function(&amp;array),那么你传递一个Sometype (*)[]——一个指向数组的指针——这是一个完全不同的类型。如果您使用function(simple); 传递非数组类型SomeType simple;,则传递变量的副本;你必须使用function(&amp;simple) 来传递一个指针。 [...继续...]
【解决方案2】:
  1. [改写] 如何将数据发送回调用函数?

基本上你有两个选择

创建对象来保存调用函数中的数据,传递一个指针并让被调用函数使用它

int main(void) {
    int src1[10][10] = {0};
    int src2[10][10] = {0};
    fx(src1, src2);
}

或在被调用函数中使用malloc()(和朋友),然后将其返回给调用者,调用者将负责free资源。

typedef int m2[10][10];

int main(void) {
    int src[10][10] = {0};
    m2 *dst = fx(src);
    // use dst
    free(dst);
}

m2 *fx(int m[10][10]) {
    m2 *x = malloc(10 * 10 * sizeof (int));
    // work with m to change x values
    return x;
}

第三个​​不受欢迎的选项(没有示例代码)是使用全局变量。

  1. 如何在函数之间传递 5 或 6 个变量?

基本上,只要在调用代码中指定它们,比如

printf("%s bought %d %s for %.2f\n", name, quantity, "apples", quantity * price);

或者,如果变量是相关的,您可以尝试将它们分组到 struct 中并传递一个指针

struct GroupData {
    char name[100];
    int quantity;
    char item[100];
    double price;
};
struct GroupData x = {"John", 42, "apple", 0.31};
workwithdata(&x); // can also pass a copy of the struct
                  // workwithcopy(x);
  1. 何时使用 void 函数或 int 函数?

当不需要使用函数中的值时使用void

void beep(void); // sounds the bell

当你想使用函数中的值时使用int

int currenttemp(void); // returns the temperature

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-09
    • 1970-01-01
    • 2017-03-27
    • 2016-03-25
    • 2017-11-19
    • 1970-01-01
    • 2016-04-29
    相关资源
    最近更新 更多