2.出现异常的原因
main()函数将数组a[10]的地址存放在main()的栈底,作为test()的实参。test()函数确实改变了存放在该栈底的4个字节的内容,并使其成功指向”123\0”,但main()程序在test(a)之后,并没有使用存放在栈底的结果,因此数组a[10]的内容保持其初始值不变,导致打印时出现乱码(也可能显示其它字符)。
C语言中的函数,只要它有形参,则父函数在调用该子函数之前,必须在父函数的栈中保存调用子函数所需要的参数。子函数执行完成后的结果,要么通过寄存器返回,要么通过栈返回。父函数将字符指针赋给子函数,子函数将该字符指针指向正确的位置,有2种方式:
1.子函数将执行的结果存放在寄存器中,父函数读取寄存器中的结果。举例如下:
#include
char *test(void)
{
char *tmp;
tmp = "123akdsf\0";
return tmp;
}
int main()
{
char *addr;
addr = test();
printf("addr = %s\n", addr);
return 1;
}
2.子函数将最终结果存放在栈中,父函数调用子函数时,必须传递地址。举例如下:
#include
void test(char *b)
{
*b = '1';
*(b + 1) = '2';
*(b + 2) = '3';
*(b + 3) = '\0';
}
int main()
{
char a[10];
test(a);
printf("a[] = %s\n", a);
return 1;
}
此时test()已经通过引用栈上存放的数组a的地址,修改了main()栈中的a[10]的内容,故从test()返回后,已经得到了正确的结果。
如果想知道上述例子的具体执行情况,只能看汇编代码。下面提供Ubuntu系统下shell中的对应指令:
gcc code.c -O0 -o code(-O0的意思是不进行代码优化)
objdump -d code(查看code的反汇编代码)
上述例子的运行环境:
Ubuntu 10.10
Pentium(R)Dual-Core CPU E5400 @ 2.70GHz
gcc version 4.4.5