Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用assert而不是简单的“assert”有什么好处;如果“是”的话?_C_If Statement_Assert - Fatal编程技术网

C 使用assert而不是简单的“assert”有什么好处;如果“是”的话?

C 使用assert而不是简单的“assert”有什么好处;如果“是”的话?,c,if-statement,assert,C,If Statement,Assert,鉴于此代码: #include <stdio.h> #include <assert.h> void print_number(int* somePtr) { assert (somePtr!=NULL); printf ("%d\n",*somePtr); } int main () { int a=1234; int * b = NULL; int * c = NULL; b=&a; print_number (c);

鉴于此代码:

#include <stdio.h>
#include <assert.h>

void print_number(int* somePtr) {
  assert (somePtr!=NULL);
  printf ("%d\n",*somePtr);
}

int main ()
{
  int a=1234;
  int * b = NULL;
  int * c = NULL;

  b=&a;

  print_number (c);
  print_number (b);

  return 0;
}
#包括
#包括
无效打印号(int*somePtr){
断言(somePtr!=NULL);
printf(“%d\n”,*somePtr);
}
int main()
{
INTA=1234;
int*b=NULL;
int*c=NULL;
b=&a;
打印号码(c);
打印号码(b);
返回0;
}
我可以这样做:

#include <stdio.h>
#include <assert.h>

void print_number(int* somePtr) {
  if (somePtr != NULL)
       printf ("%d\n",*somePtr);
  // else do something 
}

int main ()
{
  int a=1234;
  int * b = NULL;
  int * c = NULL;

  b=&a;

  print_number (c);
  print_number (b);

  return 0;
}
#包括
#包括
无效打印号(int*somePtr){
if(somePtr!=NULL)
printf(“%d\n”,*somePtr);
//还有别的事吗
}
int main()
{
INTA=1234;
int*b=NULL;
int*c=NULL;
b=&a;
打印号码(c);
打印号码(b);
返回0;
}
那么,通过使用assert,我得到了什么


关于

如果断言失败,您将看到包含失败断言本身的输出,以及失败断言的函数和行,类似于:

test: main.cpp:9: int main(): Assertion `0==1' failed.
因此,如果您的程序在运行时崩溃,您将看到崩溃的确切原因和位置。
中有一篇关于断言的大文章。

断言是在代码中记录您的假设。if语句用于处理不同的逻辑场景

现在,在您的具体案例中,请从print_number()函数开发人员的角度考虑

比如当你写作的时候

void print_number(int* somePtr) {
  assert (somePtr!=NULL);
  printf ("%d\n",*somePtr);
}
void print_number(int* somePtr) {
  if (somePtr != NULL)
       printf ("%d\n",*somePtr);
  // else do something 
}
你是说

在我的print_number函数中,我假设始终指针不为空。如果这是空的,我会非常惊讶。我根本不想在代码中处理这个场景

但是,如果你写

void print_number(int* somePtr) {
  assert (somePtr!=NULL);
  printf ("%d\n",*somePtr);
}
void print_number(int* somePtr) {
  if (somePtr != NULL)
       printf ("%d\n",*somePtr);
  // else do something 
}
您似乎说,在我的print_number函数中,我希望人们传递空指针。我知道如何处理这种情况,而且我确实是在另一种情况下处理的

所以,有时你会知道如何处理某些情况,你想这样做。然后,使用if。 有时候,你认为某事不会发生,你不想去处理它。您只需表达您的惊讶,并使用assert停止您的程序执行。

区别在于,仅为调试构建启用;未为发布版构建启用它(即定义了
NDEBUG
时),这意味着在发布版中不会进行检查;因此,与在发布版本中使用
if
条件的代码相比,您的代码将稍微快一点


这意味着,
assert
用于在编写代码时检查常见错误,并在开发阶段尽快捕获这些错误。

assert将通知您发生错误,可能需要修复错误。在调试模式下,它将中断并显示callstack,这将帮助您修复错误。所以这是一个很好的实践。实际上,我会使用if()和assert,因为在发布版本中,您的assert应该被关闭:

void print_number(int* somePtr) {
  assert(somePtr != NULL);
  if (somePtr != NULL)
       printf ("%d\n",*somePtr);
  // else do something 
}
在“//else do something”中,您可能会想到抛出异常或返回错误代码。

原因很多:

  • 对于发布版本,通常会删除断言
  • 断言将向客户端报告故障信息
    if()
    本身不执行任何操作
  • 由于断言通常是宏,因此还可以获取有关失败断言的代码信息
  • Assert在语义上比if()更清晰
  • 如果您的(If)语句变为True或False,请倾听,以便编译器继续执行下一个指令。 但在assert.h中,当您的语句变为false时,“程序立即终止”,并显示断言消息

    例如:*

    #include <assert.h> #include <stdio.h>
    
    int main () {
    
        int a;
        printf("Enter an integer value: "); scanf("%d", &a); assert(a >= 10);
        printf("Integer entered is %d\n", a);
        return(0); }
    
    #包括#包括
    int main(){
    INTA;
    printf(“输入整数值:”;scanf(“%d”,&a);assert(a>=10);
    printf(“输入的整数是%d\n”,a);
    返回(0);}
    
    也许你应该用C++来标记而不是C++。仅限C标题,仅限C函数。@AlexandreP.Levasseur:在C中,它应该是int main(void);)我想我错过了:D是一个轻微的暗示,如果他要使用C++,他也可以利用它的头和特征。那么,如果在生产构建过程中被移除,那么在调试之后,是否应该有一个断言违反的情况?或者需要用if来代替它吗?