新手问题。如何将指针传递给C中的函数?

时间:2011-01-31 10:48:01

标签: c pointers

我刚刚开始学习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;
}

5 个答案:

答案 0 :(得分:3)

更改声明以匹配定义:

int *findFactors(int, int *);

答案 1 :(得分:2)

我为添加另一个答案而道歉,但我认为没有人涵盖您的问题中需要涵盖的每一点。

1)每当您使用malloc()动态分配一些内存时,您必须在完成后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是你传入的指针变量中地址的副本。按照设计,原始副本和副本指向相同的内存,所以当我们取消引用它们时,我们可以在调用者和原始函数中编辑该内存。

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

答案 2 :(得分:1)

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

不要忘记修改方法中的numberOfFactors(如果没用,则删除此参数)。文件开头的签名也必须与最后的实现签名相匹配(这是您收到的错误)。

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

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

答案 3 :(得分:0)

int* ip   <- pointer to a an int
int** ipp <- pointer to a pointer to an int.

答案 4 :(得分:0)

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

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

最后一个错误:malloc(X)分配X 字节,所以如果你想为某个数组分配内存,你应该使用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。否则,您将收到运行时错误。