c - 在 C 中声明指针的方法
问题描述
我学习 C 语言才不到一个星期(借助我对 C++ 和其他语言的了解),我对指针及其声明方式感到困惑。
下面,我使用了一个名为Object的简单结构:
struct Object { int id; };
以下用于创建指针的方法是否以不同的方式做同样的事情,或者没有?
struct Object obj1 = { .id = 1 };
struct Object* obj1_p = &obj1; // method 1 of getting a pointer
// The same, just in a compound literal?
struct Object* obj2_p = &(struct Object){ .id = 1 }; // method 2 of getting a pointer
// Is this the same, other than being uninitialized?
struct Object* obj3_p = malloc(sizeof(struct Object)); // method 2 of getting a pointer
有没有只能使用一种方法的时候?
另外,作为旁注,为什么有些人会使用 malloc,这样做更好吗?
// malloc is casted to object:
struct Object* obj3_p = (Object*)malloc(sizeof(struct Object));
解决方案
我写了这段代码,希望它能帮助你更好地理解指针的一些特性:
#include <stdio.h>
#include <stdlib.h>
struct Object { int id; };
struct Object *getObjectBold() {
struct Object* obj2_p = &(struct Object) { .id = 2 };
return obj2_p; // UB: Returns the address of a local object (the compound literal).
}
struct Object *getObject() {
struct Object* obj3_p = malloc(sizeof(*obj3_p)); // Better way of calling malloc than using sizeof(struct Object).
obj3_p->id = 3; // You don't need to do this.
return obj3_p; // This needs to be freed later on!
}
int main(void) {
struct Object obj1 = { .id = 1 };
struct Object* obj1_p = &obj1;
printf("obj1.id = %d\n", obj1_p->id);
obj1_p->id = 10; // You can change values using the pointer
printf("obj1.id = %d\n", obj1_p->id);
// The only different thing with this case is that you don't
// "lose" your object when setting the pointer to NULL
// (although you can only access it through the object, not through the pointer).
obj1_p = NULL;
printf("obj1.id = %d\n", obj1_p->id); // This won't work (undefined behaviour).
printf("obj1.id = %d\n", obj1.id); // This will.
struct Object* obj2_p = &(struct Object) { .id = 1 };
obj2_p->id = 2; // You can change the id
printf("obj2.id = %d\n", obj2_p->id);
// If you make this pointer point to another address, you "lose" your object.
obj2_p = NULL;
printf("obj2.id = %d", obj2_p->id); // This won't work at all (undefined behaviour).
// Both of these pointers point to objects in the stack, so, for example,
// they don't work when returning from a function.
obj2_p = getObjectBold();
obj2_p->id = 20; // This won't work (undefined behaviour).
printf("obj2.id = %d\n", obj2_p->id); // This works if you don't dereference the pointer.
// The third case is not the same as the other two, since you are allocating memory on the heap.
// THIS is a time where you can only use one of these three methods.
struct Object *obj3_p = getObject(); // This works!
printf("obj3.id = %d\n", obj3_p->id);
obj3_p->id = 30; // This works now.
printf("obj3.id = %d\n", obj3_p->id);
free(obj3_p); // You need to do this if you don't want memory leaks.
return 0;
}
这是注释掉未定义行为时的输出:
obj1.id = 1
obj1.id = 10
obj1.id = 10
obj2.id = 2
obj2.id = 2
obj3.id = 3
obj3.id = 30
我建议您查看这些链接,事实证明它们对我很有帮助:
推荐阅读
- php - WooCommerce - 购物车验证的自定义功能
- java - 将长数字添加到 INTEGER SQLite
- python - 多个脚本在python中使用相同的数据访问同一个模块?
- python - 将列添加到过滤数据集
- java - 从远程设备上的 Jar 中读取文本文件
- conv-neural-network - 尝试打印图像计数
- android - FirebaseRecyclerOptions 中的错误 setQuery
- python - 如何 grep 获取由于“-”(破折号)字符而导致误报的确切字符串
- javascript - 缺少道具,编译器不抱怨
- timer - STM32F4 Timer6寄存器未设置