fgets,优先级问题导致Segmentation fault

首先,看段代码

 

 1 #include <stdio.h>

  2 
  3 int main()
  4 {
  5     char buffer[BUFSIZ+1];
  6     FILE *fpin;
  7 
  8     if((fpin = fopen("test","r") == NULL))
  9     {
 10         printf("can't open test.\n");
 11         return 1;
 12     }
 13 
 14     while(fgets(buffer,BUFSIZ,fpin) != NULL)
 15     {
 16         if(fputs(buffer,stdout) == EOF)
 17         {
 18             printf("fputs error to pipe.\n");
 19             return 1;
 20         }
 21     }

 22 }

这段代码运行会产生段错误:Segmentation fault

经过调试gdb调试发现段错误是第14行代码处 fgets(buffer,BUFSIZ,fpin) 产生的。

这里的fpin 是 NULL。

在编程中以下几类做法容易导致段错误,基本是是错误地使用指针引起的 
1)访问系统数据区,尤其是往 系统保护的内存地址写数据最常见就是给一个指针以0地址 
2)内存越界(数组越界,变量类型不一致等) 访问到不属于你的内存区域 

所以再查找fpin 是 NULL的原因

仔细看第8行代码

if((fpin = fopen("test","r") == NULL))

因为 == 的优先级高于 = 且  ==号是左结合,=是右结合,所以这句话等价于

fpin = ( fopen("test","r") == NULL )  

即 fopen的返回值 与 NULL做 逻辑比较运算,将返回的NULL 复制给fpin,

所以这句话并没有起到检查fpin指针的作用

故第8行代码应该为

if((fpin = fopen("test","r"))== NULL)


运行结果正常:

zyx@zyx-Lenovo:~/Desktop/pipe$ cat test 
hello,aa!
the second line!
i know i can!
you can too!
zyx@zyx-Lenovo:~/Desktop/pipe$ ./segment 
hello,aa!
the second line!
i know i can!
you can too!


另附C运算符优先级表:

C语言运算符分类
  1级优先级(左结合) 
  () 圆括号;[]下标运算符;->指向结构体成员运算符;. 结构体成员运算符。 
  2级优先级(右结合) 
  !逻辑非运算符;~按位取反运算符;++前缀增量运算符;--前缀减量运算符;+正号运算符;-负号运算符;(类型)类型转换运算符;*指针运算符;&地址运算符;sizeof长度运算符。 
  3级优先级(左结合) 
  *乘法运算符;/除法运算符;%取余运算符。 
  4级优先级(左结合) 
  +加法运算符;-减法运算符。 
  5级优先级(左结合) 
  <<左移运算符;>>右移运算符。 
  6级优先级(左结合) 
  <、<=、>、>=关系运算符。 
  7级优先级(左结合) 
  ==等于运算符;!=不等于运算符。 
  8级优先级(左结合) 
  &按位与运算符。 
  9级优先级(左结合) 
  ^按位异或运算符。 
  10级优先级(左结合) 
  |按位或运算符。 
  11级优先级(左结合) 
  &&逻辑与运算符。 
  12级优先级(左结合) 
  ||逻辑或运算符。 
  13级优先级(右结合) 
  ? :条件运算符。 
  14级优先级(右结合) 
  =、 +=、 -=、 *=、 /=、 %=、 &=、 ^=、 |=、 <<=、 >>=赋值运算符。 
  15级优先级(左结合) 
  ,逗号运算符。


你可能感兴趣的:(fgets,优先级问题导致Segmentation fault)