#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int *array;
int size;
}Array;
Array array_create(int init_size);
int* array_at(Array *,int index);
void array_free(Array *);
int main(int argc, char const *argv[])
{
Array a =array_create(100);
*array_at(&a,0)=10;
printf("%d\n",*array_at(&a,0));
array_free(&a);
return 0;
}
Array array_create(int init_size){
Array a;
a.size = init_size;
a.array=(int*)malloc(sizeof(int)*a.size);
return a;
}
void array_free(Array *a)
{
free(a->array);
a->array=NULL;
a->size=0;
}
int* array_at(Array *a,int index)
{
return &(a->array[index]);
}
为什么这段C语言代码没有报错或者警告?函数
array_at
不应该只返回指针的值吗?为什么array_at(&a,0)
是指针本身,而不是指针的值?为什么*array_at(&a,0)
甚至是可以赋值的左值?
因为代码像
#include <stdio.h>
int new(int);
int main(){
int a=3;
new(a)=4;
printf("%d\n",new(a));
}
int new(int i){
i+=3;
return i;
}
将无法成功运行。我想是因为
new(a)
只是int变量i
的一个值而且不可能是左值,所以我实在不明白上面的代码为什么能成功运行
为什么这段C语言代码没有报错或者警告?
因为代码并没有错误或特别可疑。
函数
不应该只返回指针的值吗?array_at
函数返回值。有时,就像您的情况一样,这些值具有指针类型。但函数调用表达式不是左值,因此返回值就是全部——没有底层对象存储它。我认为这就是你所说的“只返回指针的值”的意思,所以是的。
为什么 array_at(&a,0) 是指针本身,而不是指针的值?
你似乎很困惑。
array_at(&a,0)
计算为指针值,但该表达式不是左值,这意味着它确实指定具有存储或生命周期的对象。而且它不需要为了明显的目的。
为什么 *array_at(&a,0) 甚至是可以赋值的左值?
因为这就是一元
*
运算符产生的结果。它的操作数不需要是左值,而且通常也不是。另一方面,它的结果是左值。
这并没有什么不合理的。有效的非空指针值标识一个对象。一元
*
运算符中的表达式指定操作数指向的对象,就像变量的名称指定它所命名的对象一样。无论哪种方式,您都可以读取指定对象的值。无论哪种方式,如果该对象完全可以修改,您就可以写入指定对象的值。
函数
不应该只返回指针的值吗?array_at
该函数声明为返回类型
int *
,因此它应该返回一个 int *
,它是指向 int
的指针,也称为地址。
其返回语句提供了
int
的地址; return &(a->array[index]);
使用 &
获取 a->array[index]
的地址。
为什么
是指针本身,而不是指针的值?array_at(&a,0)
该函数返回一个
int *
,它是一个指向 int
的值。这是int
的地址。
为什么
甚至是可以赋值的左值?*array_at(&a,0)
一元
*
产生一个左值。将其应用于 array_at(&a, 0)
会生成 int
的左值,array_at(&a, 0)
返回指向的指针。