如果不为空,则为指针赋值

Posted

技术标签:

【中文标题】如果不为空,则为指针赋值【英文标题】:Assign value to pointer if not null 【发布时间】:2014-07-31 18:57:12 【问题描述】:

我有一个整数指针作为默认函数参数。如果它不为空,我想分配一些值,也许每 200 行中的第 10 行。通过在每次分配之前进行标准检查,我的代码很容易变得庞大且难以阅读。 (我指的是源文件长度和可读性,而不是二进制大小。)

替换这个是好习惯吗:

// Previous statement
// Use to put empty line here
if(ptr)
    *ptr = val;
// Empty line also here
// Next statement

用这个:

// Previous statement
assignIfNotNull(ptr, val);
// Next statement

并把 if 放入函数中?

inline void assignIfNotNull(int *ptr, int val)

    if(ptr)
        *ptr = val;

现在,我似乎很细致,但这每次使用会节省 3 行。也许不是我编程风格中最糟糕的事情,这是我独自学习时即兴创作的。我想压制它,询问并跟上标准。 (我在任何地方都找不到这个。)

提前致谢。

【问题讨论】:

第二版错误。您正在通过值传递指针,您需要一个双指针或通过引用传递指针。 @40two 赋值为 *ptr = ...,没关系 @DieterLücking 道歉没有注意到 :( 请忽略我的评论 Dieter 是对的。 我个人不会这样做,因为 API 不会得到太多使用。我宁愿编写更严格的代码,当我输入一段我知道指针应该有效的代码时跳过任何检查,而不是使用 API 来设置不断进行不必要检查的值。 如果不支持某些编辑工具,assignIfNotNull 需要比 if 版本更多的输入。除此之外,它是一个纯粹的便利功能。即使有一个好名字,你也必须在使用它之前查找(知道)函数(我不会这样做,除非它在某些源文件中本地使用) 【参考方案1】:

你可以去:

T dummy;
if ( !ptr ) 
    ptr = &dummy;

一开始;然后你就可以放心地写*ptr = whatever;,而不需要空检查。

如果ptr 的原始值很重要,你可以调用参数orig_ptr 之类的。

【讨论】:

【参考方案2】:

C# null coalescing operator equivalent for c++ 几乎准确地提出了您的问题,但不要指望找到一些突破性的解决方案 - 三元运算符、模板和宏只有一些变化:

ptr = (ptr != null ? ptr : MY_DEFAULT)

//------------------- or as function
template<class T>
GetValueOrDefault(T* value, T* defaultValue) // or put your own types

    return value != null ? value : defaultValue;


ptr = GetValueOrDefault(ptr, MY_DEFAULT);

//------------------- or as macro

#define GET_VALUE_OR_DEFAULT(value, defaultValue) (value != null ? value : defaultValue)

ptr = GET_VALUE_OR_DEFAULT(ptr, MY_DEFAULT);

//------------------- or like this macro

#define VALUE_OR_DEFAULT(value, defaultValue) value = (value != null ? value : defaultValue)

VALUE_OR_DEFAULT(ptr, MY_DEFAULT);

但有几点你应该考虑:

    当问题不存在时不要想像 - 很多检查和重新初始化对于某些 API 是完全可行的 - 看看 WINAPI 您确定要覆盖该变量吗?可能是你 可以重写您的函数或 API 以不覆盖它。

    您也可以考虑使用一些临时变量来代替 ptr - 解决不了问题,把它倒过来,但是 这可能会提高您的整体可理解性 功能和删除检查:

      char* tempPtr = ptr;
      retCode = RandomlyNullifyThePtr(&tempPtr); // RandomlyNullifyThePtr can nullify the ptr it gets ,
      // but it won't nullify the ptr in calling function.
    

    如果您在保存整个函数时遇到问题 良心那么直接的迹象表明它应该被重构 - 分成更小的部分,这样的检查可能会变成 不必要的:

      retCode = CompletePart1(ptr); // CompletePart1 can nullify the ptr it gets, 
      // but it won't nullify the ptr in calling function.
      ...
      retCode = CompletePart2(ptr);
    

【讨论】:

另一个考虑是使用引用而不是指针。通过引用,可以保证对象存在。一个指针可以指向一个无效的位置并且仍然是非零或非空的。

以上是关于如果不为空,则为指针赋值的主要内容,如果未能解决你的问题,请参考以下文章

c语言char和int可以互相赋值,但指针不能赋值,char *和int *不能直接赋值,为啥呢?谢谢

C语言 将整型变量赋值为空

C语言指针的初始化和赋值

第十二次课堂总结

C 语言多级指针 ( 在函数中生成 二级指针 | 通过传入的 三级指针 进行间接赋值 )

C 语言指针间接赋值 ( 间接赋值三要素 | 间接赋值 使用的三种场景 )