【问题标题】:Newbie question. How to pass pointers in to a function in C?新手问题。如何将指针传递给C中的函数?
【发布时间】:2011-01-31 10:48:00
【问题描述】:

我刚刚开始学习 C(来自 C# 背景。)对于我的第一个程序,我决定创建一个程序来计算因子。我需要将一个指针传递给一个函数,然后更新相应的变量。

我收到错误“findFactors 的类型冲突”,我认为这是因为我没有表明我希望在声明 findFactors 函数时将指针作为参数传递。任何帮助将不胜感激!

#include <stdio.h>
#include <stdlib.h>

int *findFactors(int, int);

int main (int argc, const char * argv[]) 
{
    int numToFind;

do {
    printf("Enter a number to find the factors of: ");
    scanf("%d", &numToFind);    
} while (numToFind > 100);

    int factorCount;
findFactors(numToFind, &factorCount);

return 0;
}

int *findFactors(int input, int *numberOfFactors)
{
int *results = malloc(input);
int count = 0;
for (int counter = 2; counter < input; counter++) {
    if (input % counter == 0){
        results[count] = counter;
        count++;
        printf("%d is factor number %d\n", counter, count);
    }
}

return results;
}

【问题讨论】:

  • 想通了。 int ** 然后 int **numberOfFactors

标签: c pointers


【解决方案1】:

更改声明以匹配定义:

int *findFactors(int, int *);

【讨论】:

    【解决方案2】:

    对于添加另一个答案,我深表歉意,但我认为没有人涵盖您问题中需要涵盖的所有要点。

    1) 每当您使用malloc() 动态分配一些内存时,您也必须在完成后free() 它。操作系统通常会在您之后进行整理,但请考虑您在可执行文件期间有一个使用一些内存的进程。当所述过程完成时,如果您 free() 那个内存,您的进程就有更多可用内存。这是关于效率的。

    正确使用free:

    int* somememory = malloc(sizeyouwant * sizeof(int));
    // do something
    free(somememory);
    

    简单。

    2) 每当您使用malloc 时,正如其他人所指出的,实际分配以字节为单位,因此您必须使用malloc(numofelements*sizeof(type));。还有另一个不太广泛使用的函数calloc,看起来像calloc(num, sizeof(type));,它可能更容易理解。 calloc 还将你的内存初始化为零

    3) 您不需要转换malloc 的返回类型。我知道很多编程书籍都建议你这样做,并且 C++ 要求你必须这样做(但在 C++ 中你应该使用 new/delete)。见this question

    4) 您的函数签名确实不正确 - 函数签名必须与其函数匹配。

    5) 在从函数返回指针时,我不鼓励这样做,但它本身并没有错。需要提及的两点:始终牢记 1)。我asked 正是问题所在,它基本上归结为跟踪那些free() 电话。作为更高级的用户,还需要担心分配器类型。

    这里还有一点,考虑一下这个函数:

    int* badfunction()
    {
        int x = 42;
        int *y = &x;
        return y;
    }
    

    这很糟糕,很糟糕,很糟糕。这里发生的是我们创建并返回一个指向x 的指针,只要你在badfunction 中它就存在。当您返回时,您将获得一个不再存在的变量地址,因为x 通常是在堆栈上创建的。随着时间的推移,您将了解更多相关信息;现在,只要认为该变量在其功能之外不存在。

    请注意,int* y = malloc(... 是一种不同的情况 - 由于 malloc 内存是在堆上创建的,因此在所述函数结束后仍然存在。

    我会推荐什么作为函数签名?我实际上会使用shybovycha 的函数稍作修改:

    int findFactors(int* factors, const int N);
    

    我的更改只是个人喜好。我使用const 以便我知道某些东西是函数输入的一部分。仅使用 int 并不是绝对必要的,但是如果您要传递指针,请记住可以修改源内存,除非您在它之前使用 const,如果您尝试修改它,编译器应该警告您。所以在这种情况下它只是习惯。

    第二个变化是我更喜欢左边的输出参数,因为我总是这样想,即output = func(input)

    为什么在使用指针时可以修改函数参数?因为你已经传递了一个指向变量的指针。这只是一个内存地址——当我们“取消引用”它(访问该地址的值)时,我们可以修改它。从技术上讲,C 是严格按值传递的。指针本身就是包含内存地址的变量,这些变量的内容被复制到您的函数中。所以一个普通变量(比如int)只是你传入的任何内容的副本。int* factors 是你传入的指针变量中地址的副本。根据设计,原始和这个副本都指向同一个内存,因此当我们取消引用它们时,我们可以在调用者和原始函数中编辑该内存。

    我希望这能解决一些问题。

    【讨论】:

    • + 用于提及 free()。由于原始海报是 C# 程序员,他们可能对手动内存清理一无所知;它们用于垃圾收集。
    • 来自 8 年实时系统开发人员的 +1 非常值得称赞。谢谢。我不敢相信没有其他人发现它或觉得它不值得一提。
    【解决方案3】:

    编辑:C 中没有引用(C++ 特性)

    不要忘记修改方法中的 numberOfFactors (如果没有用,或者删除这个参数)。文件开头的签名还必须与结尾的实现签名匹配(这是您收到的错误)。

    最后,您的 malloc 结果不正确。你需要这样做:

    int *results = malloc(input * sizeof(int));
    

    【讨论】:

    • C 中不存在引用;它们是 C++ 功能。
    【解决方案4】:
    int* ip   <- pointer to a an int
    int** ipp <- pointer to a pointer to an int.
    

    【讨论】:

    • 感谢大家的帮助。
    【解决方案5】:

    int *findFactors(int, int); 行说你想从这个函数返回指针(最好使用更接近类型名称的星号:int* moo(); - 我认为这样可以防止误解)。

    如果你想动态改变函数参数(这比返回指针更好),你应该使用参数,就好像你已经有了这个变量一样。

    最后一个你的错误:malloc(X) allocates X bytes,所以如果你想为某个数组分配内存,你应该使用malloc(N * sizeof(T));,其中N 是大小你的数组和T 是它的类型。例如:如果你想拥有int *a,你应该这样做:int *a = (int*) malloc(10 * sizeof(int));

    现在这是您的代码,已修复(对我而言):

    #include <stdio.h>
    #include <stdlib.h>
    
    int findFactors(int, int*);
    
    int main(int argc, char **argv) 
    {
      int numToFind, *factors = 0, cnt = 0;
    
      do 
      {
        printf("Enter a number to find the factors of: ");
        scanf("%d", &numToFind);    
      } while (numToFind > 100);
    
      cnt = findFactors(numToFind, factors);
    
      printf("%d has %d factors.\n", numToFind, cnt);
    
      return 0;
    }
    
    int findFactors(int N, int* factors)
    {
      if (!factors)
        factors = (int*) malloc(N * sizeof(int));
    
      int count = 0;
    
      for (int i = 2; i < N; i++) 
      {
        if (N % i == 0)
        {
          factors[count++] = i;
          printf("%d is factor number #%d\n", i, count);
        }
      }
    
      return count;
    }
    

    注意:不要忘记在任何时候初始化你的指针(就像我一样)。如果你确实想调用函数,传递一个指针作为它的参数,你必须至少在函数调用之前确保它的值是0。否则会出现运行时错误。

    【讨论】:

    • malloc 返回的内存不是零初始化的。您应该添加 memset(factors, 0, sizeof(int) * N); 否则这些值将是未定义的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-25
    • 2019-03-12
    • 2011-05-19
    • 1970-01-01
    相关资源
    最近更新 更多