首页 > 解决方案 > 为什么从函数返回时不能使用方括号语法访问指针的值?

问题描述

我正在学习基本的 C,但我仍在尝试理解数组和指针。我正在尝试编写一个push函数来模仿 Javascript 中数组的行为,但有一个解决方法,因为数组不能在 C 中返回。

当我使用 访问返回的指针时(*p+3),它会产生正确的值,但p[3]不会。但是,我仍然可以在push()with中访问正确的值p[3]。为什么是这样?

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

void br() {
    putchar('\n');
}

int *push(int *arr, size_t size, int val) { 
    int *arr2 = calloc(size + 1, sizeof(int));
    for (int i = 0; i < size; i++) {
        arr2[i] = arr[i];
    }
    arr2[size] = val;
    return arr2;
}

int main(int argc, char *argv[]) {
    int myNums[] = { 1, 2, 3 };

    int *p = push(myNums, sizeof(myNums), 4);
    printf("%i", (*p + 3));
    br();
    printf("%i", p[3]);
    br();

    return 0;
}

编辑:我认为使用结构有更好的解决方案。

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


typedef struct{
    int*values;
    int length;
} intArray;

void printInts(intArray * arr){
    for(int i = 0; i < arr->length; i++){
        printf("Value %i: %i\n",i,arr->values[i]);
    }
}

intArray push(intArray * arr, int value){
    arr->length++;
    arr->values = realloc(arr->values, sizeof(int)*arr->length);
    arr->values[arr->length-1] = value;
    return *arr;
}

intArray pop(intArray * arr){
    arr->length--;
    arr->values = realloc(arr->values, sizeof(int)*arr->length);
    return *arr;
}

int main(int argc, char *argv[]) {
    intArray myNums;
    myNums = push(&myNums,15);
    myNums = push(&myNums,30);
    myNums = push(&myNums,45);
    myNums = push(&myNums,60);
    myNums = pop(&myNums);

    printInts(&myNums);

    /* expected output:
    Value 0: 15
    Value 1: 30
    Value 2: 45
    */

    return 0;
}

标签: c

解决方案


代码中有两个错误:

  • int *p = push(myNums, sizeof(myNums), 4);

    sizeof(myNums)不是数组的长度(即:元素的数量),而是它的大小(以字节为单位)。

    您可以sizeof(myNums) / sizeof(myNums[0])在编译时使用它来计算元素的数量。

  • printf("%i", (*p + 3));

    你先打印*p + 3,这不等于*(p + 3):你得到预期的输出只是巧合因为*p,这相当于p[0]碰巧有值1。相反,p[3]访问重新分配数组的第四个元素,其值未定义,因为它是从传递给的原始数组末尾之外的数据复制而来的push()

这是修改后的版本:

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

int *push(int *arr, size_t count, int val) { 
    int *arr2 = calloc(count + 1, sizeof(int));
    for (int i = 0; i < count; i++) {
        arr2[i] = arr[i];
    }
    arr2[count] = val;
    return arr2;
}

int main(int argc, char *argv[]) {
    int myNums[] = { 1, 2, 3 };
    int *p = push(myNums, sizeof(myNums) / sizeof(myNums[0]), 4);
    printf("%i\n", *(p + 3));
    printf("%i\n", p[3]);
    free(p);
    return 0;
}

推荐阅读