简体   繁体   English

基本功能打印0而不是指定的数字C

[英]basic function printing 0's rather than specified numbers C

I have this basic code that is meant to ask the user how many integers to input, get the user to input specified numbers for each integer and then reprint the integers the user typed in, except instead of printing the integers it just prints 0's 我有这个基本代码,用来询问用户要输入多少个整数,让用户为每个整数输入指定的数字,然后重新打印用户键入的整数,除了不打印整数外,它只打印0的整数。

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;
}

Move these lines: 移动这些行:

printf("Please enter the number of integers you want to input\n");
scanf("%d", &numInput);
integersArray = (int *) malloc(sizeof(int) * numInput);

to main , before you call getInts . main之前,先调用getInts

The reason why you need this is that getInts receives a copy of integersArray (ie a copy of the pointer), and an assignment within getInts modifies only the copy, and the integersArray in main remains intact. 之所以需getInts是因为getInts接收了integersArray的副本(即指针的副本),并且getInts的赋值getInts修改了该副本,而main中的integersArray保持不变。

First you need to understand what passing by value and what passing by reference is. 首先,您需要了解什么是按值传递,什么是按引用传递。

Observe in the example I have here , how the arguments are passed in the function. 在我这里的示例中观察,如何在函数中传递参数。 The first one is passed by value and the second by reference. 第一个通过值传递,第二个通过引用传递。

The function holds its own variables, since it has an internal world, that all of its variables live inside. 该函数拥有自己的变量,因为它具有内部世界,因此其所有变量都位于内部。 Once the function is terminated, so does its world. 功能终止后,其功能也会终止。

The first argument is copied to the first argument and when the function terminates, the changes made inside the function are forgotten. 第一个参数将被复制到第一个参数,并且当函数终止时,将忽略函数内部所做的更改。

However, the second one is passed by reference. 但是,第二个通过引用传递。 As a result the variable inside the function 'points' to the variable that lives in main. 结果,函数内部的变量“指向”驻留在main中的变量。 So, when the function terminates, all the changes will be remembered in the world of main too. 因此,当函数终止时,所有更改也会在main的世界中被记住。

Now, in your case, you want to pass an array, to dynamically allocate it and fill it. 现在,根据您的情况,您想传递一个数组,以动态分配它并填充它。 You need to pass the array by reference, so that the changes shall be remembered when the function terminates. 您需要按引用传递数组,以便在函数终止时记住更改。

Here is how one could do it: 这是一种方法:

#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;
}

Here, when we malloc something, this means that the memory allocated will not be de-allocated when the function terminates. 在这里,当我们分配一些东西时,这意味着当函数终止时,分配的内存不会被取消分配。 It will live forever and we ought to de-allocate when we no longer need it, eg at the end of main. 它会永远存在 ,我们应该在不再需要它时(例如在main末尾)取消分配。 If we do not do so, this will produce a memory leak , which is a common logical error. 如果我们不这样做,则会产生memory leak ,这是一个常见的逻辑错误。

So, the main should be modified in order to use free() . 因此,应修改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;
}

Below is a version, which doesn't return the numInput , but modifies a bit the second argument you have in getInts() . 下面是一个版本,该版本不返回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]));
    }
}

Notice how numInput is treated inside the body of your function. 注意在函数体内如何处理numInput Also note that I wrote scanf as this 另请注意,我这样写scanf

scanf("%d", numInput);

but what really happens is this: 但是真正发生的是:

scanf("%d", &(*numInput));

However, operators & and * cancel its other out, as you might already know. 但是,您可能已经知道,运算符&*取消其他运算符。

[EDIT] [编辑]

As alk stated, this provides an excellent chance to learn to use a debugger . alk所述,这为学习使用debugger提供了绝佳的机会。 There is plenty of info and good tutorials about that in the internet. 互联网上有很多有关此的信息和好的教程。

Another debugging technique would be using printing messages in the code and see where things don't go as you think they are (remember the good thing with the computers is that they do exactly what we tell them and the bad thing with the computers is that they do exactly what we tell them). 另一种调试技术是在代码中使用打印消息,并按照您认为的样子查看行不通的地方(记住,计算机的好处是它们完全按照我们的指示行事,而计算机的坏处是他们完全按照我们告诉他们的方式做)。

Here is an example of modifying your function for that purpose: 这是为此目的修改功能的示例:

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;
}

and a possible output would be: 可能的输出为:

Please enter the number of integers you want to input
1
numInput is 1
please enter integer 1: 2
2 
getInts() terminating...
441172865 

From the output we can see that input value was correctly received by our array, because we print the array inside the function. 从输出中我们可以看到数组正确接收了输入值,因为我们在函数内部打印了数组。

However in the main, the array contains garbage..Hmm, what can be wrong? 但是在主要情况下,数组包含垃圾..嗯,什么是错的? Well you already know from what I wrote before. 好吧,您已经从我之前写的书中知道了。 Your mind should think, the function does it's job good inside her body, but the 'communication' with main has some problem. 您的思想应该认为,功能在她的身体内部发挥了很好的作用,但是与主体的“沟通”存在一些问题。 The problem was that the array wasn't passed by reference. 问题在于该数组未通过引用传递。

Also notice, that you should not cast what malloc returns. 还要注意,您不应该转换malloc返回的内容。 Google for more (one result of googling is here ). Google提供的更多信息( 在这里可以进行谷歌搜索)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM