c - 为什么从函数返回时不能使用方括号语法访问指针的值?
问题描述
我正在学习基本的 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;
}
解决方案
代码中有两个错误:
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;
}
推荐阅读
- c# - System.FormatException:输入字符串的格式不正确,来自 int.Parse
- python - 打印两个多行字符串,end='' 不会并排放置
- laravel - 带有 Laravel 和 Vue.JS 的 Axios GET 方法在 javascript 控制台中返回 404 错误
- php - 随机 URL 文件获取内容 PHP
- jsviews - 无法触发事件(arrayChange)
- javascript - 将对象数组转换为分层数据结构
- slurm - sacct 输出的解释:ex+ 的含义
- request - 如何防止Fiddler之类的软件拦截请求,拦截electron发出的请求
- javascript - 将保存在文件中的 BSON 数据转换为 Javascript 对象
- android - 动态创建下一个元素比上一个元素大一定数量的 ArrayList