首先,看段代码
1 #include <stdio.h>
222 }
这段代码运行会产生段错误: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级优先级(左结合) ,逗号运算符。