如何将 NULL 分配给 float/double 变量?
How can I assign the NULL to a float/double variable?
我在使用 JNI 时遇到问题。
jboolean z = (jboolean) NULL; // ok
jbyte b = (jbyte) NULL; // ok
jchar c = (jchar) NULL; // ok
jshort s = (jshort) NULL; // ok
jint i = (jint) NULL; // ok
jlong j = (jlong) NULL; // ok
jobject l = (jobjec) NULL; // ok
jfloat f = (jlong) NULL; // NOT OK
jdouble d = (jdouble) NULL; // NOT OK
编译器抱怨
[ERROR] /....c:112:28: error: pointer cannot be cast to type 'jfloat' (aka 'float')
[ERROR] jfloat result = (jfloat) NULL;
[ERROR] ^~~~
[ERROR] /usr/include/sys/_types/_null.h:29:15: note: expanded from macro 'NULL'
[ERROR] #define NULL __DARWIN_NULL
[ERROR] ^~~~~~~~~~~~~
[ERROR] /usr/include/sys/_types.h:52:23: note: expanded from macro '__DARWIN_NULL'
[ERROR] #define __DARWIN_NULL ((void *)0)
[ERROR] ^~~~~~~~~~~
[ERROR] 1 error generated.
我该如何解决这个问题?
我正在为每个值编写方法。
jboolean doSome() {
jboolean result = (jboolean) NULL;
/*
* at here result may be initialized or remain as NULL
*/
return result;
}
我打算写一个函数结合以下三种方法。
(*env)->GetObjecClass(JNIEnv *, jobject);
(*env)->GetMethodID(JNIEnv *, jclass, char *, char *);
(*env)->CallBooleanMethodA(JNIEnv *, jclass, jmethodID, jvalue *);
像这样。
jboolean CallBooleanMethodAMmMs(JNIEnv * env, jobject obj, char * mname,
char * msig, jvalue * args) {
jboolean result = (jboolean) NULL;
jclass clazz = (*env)->GetObjectClass(env, obj);
jmethodID methodID = (*env)->GetMethodID(env, clazz, mname, msig);
if (methodID != NULL) {
result = (*env)->CallBooleanMethodA(env, obj, methodID, args);
}
(*env)->DeleteLocalRef(env, clazz);
return result;
}
我想我可以使用NULL
来处理任何不成功的情况,例如methodID == NULL
。
我想我应该使用 jobject
而不是基元,对吗?
您不能(也不应该)将指针分配给普通变量。
我真的不知道为什么它允许其他一些正常的数据类型,正如您所提到的。对于从指针到其他非指针数据类型
的所有赋值,编译器应该同样产生相同的警告
NULL
是stdio.h中定义的void指针,用于初始化指针类型变量。如果您想初始化非指针变量,请使用简单的 0
而不是 NULL
。
NULL
应该用作指针的特殊值,如果您没有要指向的实际对象。这是 Option Types 的替代方法(在其他语言中使用,通常被认为是更好的解决方案)并且仅适用于指针类型(因为对于其他类型,只选择一个值作为 [= 的值更容易22=]).
因此 NULL
的处理方式与任何其他指针相同。虽然指针转换为整数类型在某些特殊情况下仍然有意义(尽管它很危险,因为根据类型您可能会截断指针),但将其转换为浮点数绝对没有任何意义(它们用于对内存地址没有意义的数字计算。
你到底想达到什么目的?如果只是将这些变量初始化为定义明确的初始值,请尝试 0.0f
和 0.0
而不是 NULL
.
How can I assign the NULL to a float/double variable?
使用intptr_t/uintptr_t
,它是整数类型,可以保存void *
的信息。
这将保留再次制作与 NULL
相当的 void *
所需的信息。
intptr_t iptr = (intptr_t) NULL;
void *ptr = (void *) iptr;
assert(ptr == NULL);
这会将整数转换为 double
,但信息(例如精度)可能会丢失。如果代码尝试转换回 intptr_t
,然后 void *
,然后尝试与 NULL
进行相等比较,它可能会失败。
intptr_t iptr = (intptr_t) NULL;
double fp = (double) iptr;
intptr_t iptr2 = (intptr_t) fp;
void *ptr = (void *) iptr2;
// May not succeed
assert(ptr == NULL);
我在使用 JNI 时遇到问题。
jboolean z = (jboolean) NULL; // ok
jbyte b = (jbyte) NULL; // ok
jchar c = (jchar) NULL; // ok
jshort s = (jshort) NULL; // ok
jint i = (jint) NULL; // ok
jlong j = (jlong) NULL; // ok
jobject l = (jobjec) NULL; // ok
jfloat f = (jlong) NULL; // NOT OK
jdouble d = (jdouble) NULL; // NOT OK
编译器抱怨
[ERROR] /....c:112:28: error: pointer cannot be cast to type 'jfloat' (aka 'float')
[ERROR] jfloat result = (jfloat) NULL;
[ERROR] ^~~~
[ERROR] /usr/include/sys/_types/_null.h:29:15: note: expanded from macro 'NULL'
[ERROR] #define NULL __DARWIN_NULL
[ERROR] ^~~~~~~~~~~~~
[ERROR] /usr/include/sys/_types.h:52:23: note: expanded from macro '__DARWIN_NULL'
[ERROR] #define __DARWIN_NULL ((void *)0)
[ERROR] ^~~~~~~~~~~
[ERROR] 1 error generated.
我该如何解决这个问题?
我正在为每个值编写方法。
jboolean doSome() {
jboolean result = (jboolean) NULL;
/*
* at here result may be initialized or remain as NULL
*/
return result;
}
我打算写一个函数结合以下三种方法。
(*env)->GetObjecClass(JNIEnv *, jobject);
(*env)->GetMethodID(JNIEnv *, jclass, char *, char *);
(*env)->CallBooleanMethodA(JNIEnv *, jclass, jmethodID, jvalue *);
像这样。
jboolean CallBooleanMethodAMmMs(JNIEnv * env, jobject obj, char * mname,
char * msig, jvalue * args) {
jboolean result = (jboolean) NULL;
jclass clazz = (*env)->GetObjectClass(env, obj);
jmethodID methodID = (*env)->GetMethodID(env, clazz, mname, msig);
if (methodID != NULL) {
result = (*env)->CallBooleanMethodA(env, obj, methodID, args);
}
(*env)->DeleteLocalRef(env, clazz);
return result;
}
我想我可以使用NULL
来处理任何不成功的情况,例如methodID == NULL
。
我想我应该使用 jobject
而不是基元,对吗?
您不能(也不应该)将指针分配给普通变量。
我真的不知道为什么它允许其他一些正常的数据类型,正如您所提到的。对于从指针到其他非指针数据类型
的所有赋值,编译器应该同样产生相同的警告NULL
是stdio.h中定义的void指针,用于初始化指针类型变量。如果您想初始化非指针变量,请使用简单的 0
而不是 NULL
。
NULL
应该用作指针的特殊值,如果您没有要指向的实际对象。这是 Option Types 的替代方法(在其他语言中使用,通常被认为是更好的解决方案)并且仅适用于指针类型(因为对于其他类型,只选择一个值作为 [= 的值更容易22=]).
因此 NULL
的处理方式与任何其他指针相同。虽然指针转换为整数类型在某些特殊情况下仍然有意义(尽管它很危险,因为根据类型您可能会截断指针),但将其转换为浮点数绝对没有任何意义(它们用于对内存地址没有意义的数字计算。
你到底想达到什么目的?如果只是将这些变量初始化为定义明确的初始值,请尝试 0.0f
和 0.0
而不是 NULL
.
How can I assign the NULL to a float/double variable?
使用intptr_t/uintptr_t
,它是整数类型,可以保存void *
的信息。
这将保留再次制作与 NULL
相当的 void *
所需的信息。
intptr_t iptr = (intptr_t) NULL;
void *ptr = (void *) iptr;
assert(ptr == NULL);
这会将整数转换为 double
,但信息(例如精度)可能会丢失。如果代码尝试转换回 intptr_t
,然后 void *
,然后尝试与 NULL
进行相等比较,它可能会失败。
intptr_t iptr = (intptr_t) NULL;
double fp = (double) iptr;
intptr_t iptr2 = (intptr_t) fp;
void *ptr = (void *) iptr2;
// May not succeed
assert(ptr == NULL);