如何使指针工作?

时间:2018-05-06 02:35:12

标签: c arrays function pointers printf

我有2个功能。第一个函数名为" chooser"它将10个数字扫描成一个数组,并打印出该数组中的3个数字。第二个函数名为" calculator"确定应打印3个数字。但是,我认为我的指针做错了什么?

void chooser() {
    int cool_array[10] = {'\0'};

    int i = 0;
    while(i < 10) {
        scanf("%d", &cool_array[i]);
        i++;
    }

    int first_num = 0;
    int second_num = 0;
    int third_num = 0;
    calculator(cool_array, first_num, second_num, third_num);

    printf("%d %d %d\n", first_num, second_num, third_num);
}

void calculator(int cool_array[],
            int *first_num, int *second_num, int *third_num) {

    int one = cool_array[0];
    int two = cool_array[1];
    int _three = cool_array[2];

    // I want the code below to change the number of first_num,
    // second_num and third_num in the chooser function, so it
    // can print the new numbers determined by the calculator function
    first_num = &one;
    second_num = &two;
    third_num = &three;
}

2 个答案:

答案 0 :(得分:0)

您要做的是在“计算器”功能中引用3个变量来更改它们 你可以将函数定义为:

void calculator(int cool_array[], int &first_num, int &second_num, int &third_num)

然后你当然不需要在计算器函数中使用dereference运算符,只需说 first_num = one ,你就会改变原始变量。

答案 1 :(得分:0)

正如我在上面的评论中所表达的那样,calculator指向int,如下所示:

void chooser() {
    <snip>

    int first_num = 0;
    int second_num = 0;
    int third_num = 0;

    // calculator(cool_array, first_num, second_num, third_num);
    /* the above is incorrect because calculator expacts a pointer to
     * int as its 2nd, 3rd, and 4th values. It must be called as:
     */
    calculator(cool_array, &first_num, &second_num, &third_num);

    printf("%d %d %d\n", first_num, second_num, third_num);
}

上面是一个简单的语法问题,可以被任何编译器捕获并抛出错误,但现在我们处理问题的核心。 one, two, threecalculator声明为calculator,并且在SegFault 返回之后,值和(和地址)不可用,并且任何尝试在他们离开之后都无法访问范围是未定义的行为。 (您的代码可能看似按预期运行,或void calculator(int cool_array[], int *first_num, int *second_num, int *third_num) { int one = cool_array[0]; /* so far so good, you assign values from */ int two = cool_array[1]; /* cool_array to one, two and three */ int three = cool_array[2]; /* ('_names' are generally reserved) */ // I want the code below to change the number of first_num, // second_num and third_num in the chooser function, so it // can print the new numbers determined by the calculator function /* BIG PROBLEM, one, two, and three are decalred local to calculator, when calculator returns, the function stack memory (where local variables are stored) is released for reuse by your program and any attempt to access addresses within the function stack after the function returns is Undefined Behavior -- (really bad) first_num = &one; second_num = &two; third_num = &three; */ /* assign the value to the address 'pointed to' (held) by each */ *first_num = one; *second_num = two; *third_num = three; } 或其间的任何内容)请查看以下注释:

first_num = &one;

此外,看看你试图做什么。 one first_num地址分配给one。我们已经使用 first_num地址讨论了这个问题,但还有另一个基本问题。 calculator中的first_num是<{1}}中指针chooser副本calculator中的副本有自己的(和非常不同的)地址。如果one的存储时间在calculator返回后仍然存在,那么您仍然不会在first_num中看到对chooser的任何更改。为什么?因为在calculator中你只是从chooser更改了指针的副本。

但是,虽然first_num中的calculator是副本,但它保存的地址chooser中的指针非常相同。因此,如果您将地址指向设置为first_num(通过取消引用并指定值),则该更改将反映在chooser中。这就是指针的工作方式(以及按值传递 C函数参数的工作方式)。

现在让我们做你正在尝试的事情。

#include <stdio.h>

/* let's put the functions in the right order (or use prototypes) */

void calculator(int cool_array[],
            int *first_num, int *second_num, int *third_num) {

    int one = cool_array[0];
    int two = cool_array[1];
    int three = cool_array[2];

    /* set the value at the address held by each poiter to wanted values */
    *first_num = one;
    *second_num = two;
    *third_num = three;
}

void chooser() {
    int cool_array[10] = {0};

    int i = 0;
    while(i < 10) {
        scanf("%d", &cool_array[i]);
        i++;
    }

    int first_num = 0;
    int second_num = 0;
    int third_num = 0;
    /* a proper call to calculator */
    calculator(cool_array, &first_num, &second_num, &third_num);

    printf("%d %d %d\n", first_num, second_num, third_num);
}

int main (void) {

    chooser();
    return 0;
}

(提示输入也是一个好主意,所以你的用户不只是坐在那里盯着闪烁的光标,想知道你的程序是否已经挂起......)

示例使用输出

$ ./bin/choose
10 20 30 40 50 60 70 80 90 100
10 20 30

如果你喜欢一个生成相同数字并自动将其提供给你的程序的管道示例:

$ printf "%s\n" {10..100..10} | ./bin/choose
10 20 30

仔细看看,如果您有其他问题,请告诉我。