我有这个基本代码,用于询问用户输入多少个整数,让用户输入每个整数的指定数字,然后重新打印用户输入的整数,除了打印它刚打印的整数0' S
int getInts(int * integersArray, int numInput);
int main() {
int * integersArray;
int numInput;
int i;
numInput = getInts(integersArray, numInput);
for (i = 0; i < numInput; i++) {
printf("%d ",integersArray[i]);
}
return 0;
}
int getInts(int * integersArray, int numInput) {
int i;
printf("Please enter the number of integers you want to input\n");
scanf("%d", &numInput);
integersArray = (int *) malloc(sizeof(int) * numInput);
for (i = 0; i < numInput; i++) {
printf("please enter integer %d: ", i+1);
scanf("%d", &(integersArray[i]));
}
return numInput;
}
答案 0 :(得分:0)
移动以下行:
printf("Please enter the number of integers you want to input\n");
scanf("%d", &numInput);
integersArray = (int *) malloc(sizeof(int) * numInput);
在致电main
之前到getInts
。
您需要这样做的原因是getInts
收到integersArray
的副本(即指针的副本),而getInts
中的分配仅修改副本,并且主要integersArray
保持不变。
答案 1 :(得分:0)
首先,您需要了解通过值传递的内容以及通过引用传递的内容。
在示例中观察我here,如何在函数中传递参数。第一个是按值传递的,第二个是通过引用传递的。
该函数拥有自己的变量,因为它有一个内部世界,它的所有变量都存在于其中。一旦函数终止,它的世界也将如此。
第一个参数被复制到第一个参数,当函数终止时,函数内部所做的更改将被遗忘。
但是,第二个是通过引用传递的。结果,函数内部的变量“指向”生活在main中的变量。因此,当函数终止时,所有的更改都将在main的世界中被记住。
现在,在您的情况下,您希望传递一个数组,以动态分配并填充它。 您需要通过引用传递数组,以便在函数终止时记住更改。
以下是如何做到这一点:
#include <stdlib.h>
#include <stdio.h>
int getInts(int** integersArray, int numInput);
int main() {
int * integersArray;
int numInput;
int i;
numInput = getInts(&integersArray, numInput);
for (i = 0; i < numInput; i++) {
printf("%d ",integersArray[i]);
}
return 0;
}
// do I really need to pass numInput, since I return it? No.
int getInts(int** integersArray, int numInput) {
int i;
printf("Please enter the number of integers you want to input\n");
scanf("%d", &numInput);
*integersArray = malloc(sizeof(int) * numInput);
for (i = 0; i < numInput; i++) {
printf("please enter integer %d: ", i+1);
scanf("%d", &((*integersArray)[i]));
}
return numInput;
}
这里,当我们malloc某事时,这意味着当函数终止时,分配的内存不会被解除分配。它将永远存在 ,当我们不再需要时,我们应该取消分配,例如在主要结束时。如果我们不这样做,这将产生memory leak
,这是一个常见的逻辑错误。
因此,应该修改main以使用free()
。
int main() {
int * integersArray;
int numInput;
int i;
numInput = getInts(&integersArray, numInput);
for (i = 0; i < numInput; i++) {
printf("%d ",integersArray[i]);
}
free(integersArray); // FREE
return 0;
}
下面是一个版本,它不返回numInput
,但会修改getInts()
中的第二个参数。
// changed the prototype
void getInts(int** integersArray, int* numInput);
int main() {
int * integersArray;
int numInput;
int i;
getInts(&integersArray, &numInput); // pass the numInput by reference!!
for (i = 0; i < numInput; i++) {
printf("%d ",integersArray[i]);
}
free(integersArray);
return 0;
}
void getInts(int** integersArray, int* numInput) {
int i;
printf("Please enter the number of integers you want to input\n");
scanf("%d", numInput);
*integersArray = malloc(sizeof(int) * (*numInput));
for (i = 0; i < *numInput; i++) {
printf("please enter integer %d: ", i+1);
scanf("%d", &((*integersArray)[i]));
}
}
注意如何在函数体内处理numInput
。
另请注意,我写了scanf
作为此
scanf("%d", numInput);
但真正发生的是:
scanf("%d", &(*numInput));
但是,运营商&
和*
取消了其他内容,您可能已经知道了。
[编辑]
如 alk 所述,这提供了学习使用debugger
的绝佳机会。在互联网上有很多关于它的信息和好的教程。
另一种调试技术是在代码中使用打印消息,并按照你的想法看看事情没有发生的地方(记住计算机的好处是它们完全按照我们告诉他们的方式而做的事情是坏的。计算机是他们完全按照我们告诉他们的方式完成的。
以下是为此目的修改功能的示例:
int getInts(int * integersArray, int numInput) {
int i;
printf("Please enter the number of integers you want to input\n");
scanf("%d", &numInput);
// first step would be to check that you get the numInput right
printf("numInput is %d\n", numInput);
integersArray = malloc(sizeof(int) * numInput);
for (i = 0; i < numInput; i++) {
printf("please enter integer %d: ", i+1);
scanf("%d", &(integersArray[i]));
}
// check if you read the numbers correctly
for (i = 0; i < numInput; i++) {
printf("%d ",integersArray[i]);
}
printf("\ngetInts() terminating...\n");
return numInput;
}
可能的输出是:
Please enter the number of integers you want to input
1
numInput is 1
please enter integer 1: 2
2
getInts() terminating...
441172865
从输出中我们可以看到数组正确接收了输入值,因为我们在函数内部打印了数组。
然而在主要的,数组包含垃圾......嗯,有什么可错的?你已经从我之前写的东西中知道了。你的头脑应该想一想,这个功能在她的身体里做得很好,但与主人的'沟通'有一些问题。问题是数组没有通过引用传递。
另请注意,您不应该转换malloc返回的内容。谷歌更多(谷歌搜索的一个结果是here)。