前言:
这篇文章记录的是我在学习Linux C编程一站式学习是关于函数返回指针这节时遇到的问题,由于是新手,下面的小程序让我费解了半天,最终用gdb调试情况下分析明白了代码的原理。
正文:
下面是关于函数返回指针的一个小示例:
/* ret_ptr.h */ #ifndef RET_PTR_H #define RET_PTR_H extern char *get_a_day(int idx); #endif
/* ret_ptr.c */ #include <string.h> #include "ret_ptr.h" static const char *msg[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; char *get_a_day(int idx) { static char buf[20]; strcpy(buf, msg[idx]); return buf; }
/* main.c */ #include <stdio.h> #include "ret_ptr.h" int main(void) { printf("%s %s/n", get_a_day(0), get_a_day(1)); return 0; }
本以为程序的运行结果是Sunday Monday,但却相差甚远。
运行结果为:Sunday Sunday
用GDB进行分析
-
gcc -g ret_ptr.c main.c -o main 生成可用于调试的可执行文件main
-
gdb main 调试main
-
start 开始执行,到程序的第一条语句停止
-
s(step) 进入get_a_day 屏幕显示
get_a_day (idx=1) at ret_ptr.c:10,从上面代码可以看出,首先执行的是
get_a_day (idx=1),而不是按照get_a_day (0),get_a_day (1)的顺序执行,这时buf的内容为Monday
-
接下来一直输入n,程序执行流程重新返回main
-
s(step) 进入get_a_day(0) 这时buf的内容为Sunday
当两次调用get_a_day后才开始执行printf函数,相当于printf("%s %s/n",buf,buf),可以看出,输出应该是相同的buf内的内容,
而此时buf的内容为get_a_day(0)执行后的结果,内容为Sunday,故输出Sunday Sunday
总结:通过这个小程序的分析可以学到几点知识
1、调用一个函数时,在所有准备工作做完之后、函数调用开始之前是Sequence Point。比如调用foo(f(), g())
时,foo
、f()
、g()
这三个表达式哪个先求值哪个后求值是Unspecified,但是必须都求值完了才能做最后的函数调用,所以f()
和g()
的Side Effect按什么顺
序发生不一定,
但必定在这些Side Effect全部作用完之后才开始调用
foo
函数。
2、要注意函数的返回值,若两个函数返回的是同一个地址指针,那指的是同一块内存,内容相同。