有一个头文件esUtil.h,它带有一个名为ESContext的结构的定义,其成员之一是userData。 userData是指向void的指针。
使用它的程序的主体就是这样,简要说明:
#include "esUtil.h"
typedef struct {
GLuint programObject;
} UserData;
int DoSomething(ESContext *esContext) {
UserData *userData = esContext->userData;
...
}
int main(int argc, char *argv[]) {
ESContext esContext;
UserData userData;
esStart(&esContext);
esContext.userData = &userData;
...
if(!DoSomething(&esContext))
return 0;
...
}
我对语句中的“* userData”感到困惑:UserData * userData = esContext-> userData;
如果它是一个指针,它是如何在没有被声明的情况下产生的。谢谢你的任何解释。
答案 0 :(得分:6)
是的,它是一个指针。这条线
UserData *userData = esContext->userData;
声明一个名为userData
的变量,其类型为UserData *
(指向UserData
的指针),并使用值esContext->userData
对其进行初始化。
答案 1 :(得分:1)
代码中某些位置可能会使用结构UserData初始化ESContext的成员userData,这也就是为什么它被分配给DoSomething函数中的UserData指针。
它可能是一个void指针,但它仍然可以保存UserData对象的地址
答案 2 :(得分:1)
userData
确实是一个指针。它被声明为指针类型(类型名称中的星号是一个提示),并且此代码可能是编译的,因此它必须是指针类型。除非您未使用userData
(主要)发布任何代码,否则userData
尚未初始化。
你问“它是如何在没有被初始化的情况下产生的。”好吧,在主流的C / C ++实现中,指针实际上只是整数,其大小等于系统上的字大小(32位系统为32位,64位系统为64位)。如果取消引用指针,CPU将转到指针所代表的地址,并获取相关数据。如果数据不存在,你的程序会变成kaboom(在* nix,segfaults上),如果你很幸运,如果你没有,那就很奇怪。在这种情况下,声明了main userData
,因此实际上存在数据。但是,它没有初始化,因此userData
的内容可能是任何内容。只要DoSomething
不使用userData
的内容,就可以,因为它只是操纵该地址。但是如果它试图取消引用userData
,CPU就会出现内存并引入垃圾,此时程序可能会做各种奇怪的事情,因为在userData
内可能有任何位模式,所以userData
上的任何计算都可能会产生各种不同的结果。
C / C ++语言规范说使用未初始化的值会给出未定义的行为,实际上是未定义的,这意味着编译器可以插入代码来擦除硬盘,或者向Kernighan发送威胁消息Ritchie,或者在你使用未初始化的值时做任何喜欢的事情。但实际编译器生成的代码只是给出了垃圾位模式(通常是先前函数调用的剩余堆栈数据)。因此,虽然使用未初始化的值错误,但它不会杀死你。
关于未初始化值和错误指针的所有这些奇怪之处是C和C ++是不安全语言的最明显的方式之一。 Eric Lippert解释了C和C ++不安全的另一种方式here。
答案 3 :(得分:1)
它是一个指针,它由这一行初始化:
esContext.userData = &userData;