进程时,子进程会先在父进程的地址空间运行(这跟fork不一样),如果子进程调用了exit就会把父进程的IO给关掉。
?
7 void*与C结构体
Q:能够设计一个方法接受任意类型的参数然后返回整数?同时,是否有办法传递多个这样的参数?
A:一个能接受任意类型参数的方法像下面这个样子:
int func(void *ptr)
如果需要传递多个参数,那么我们可以传递包含这些参数的结构体。
?
8 *与++运算符
Q:以下代码将输出什么?为什么?
?
#include
int main(void)
{
? ? char *ptr = "Linux";
? ? printf("\n [%c] \n", *ptr++);
? ? printf("\n [%c] \n", *ptr);
? ? return 0;
}
?
A:程序的输出结果如下:
?[L]
?[i]
因为++与 * 的优先级一样,所以 *ptr++ 将会从右向左操作。按照这个逻辑,ptr++ 会先执行然后执行*ptr。所以第一个结果是'L'。也因为 ++ 被执行了,所以下一个printf() 结果是'i'。
?
9 Making changes in code segment
Q:以下代码运行时一定会崩溃,你能说出原因吗?
?
1 #include
2 int main(void)
3 {
4? ? char *ptr = "Linux";
5? ? *ptr = 'T';
6? ? printf("\n [%s] \n", ptr);
7
8? ? return 0;
9 }
?
A:这是因为字符串常量“Linux”是以只读的形式存储的,而通过*ptr='T'语句,此代码尝试更改只读内存存储的字符串内容,此操作当然行不通,所以才会导致崩溃。
?
10 Process that changes its own name
Q:你能否写一个程序,在它运行时修改它的名称?
A:以下的代码可以:
?
?1 #include
?2 #include
?3
?4 int main(int argc, char *argv[])
?5 {
?6? ? int i = 0;
?7? ? char buff[100];
?8
?9? ? memset(buff, 0, sizeof(buff));
10? ? strncpy(buff, argv[0], sizeof(buff));
11
12? ? memset(argv[0], 0, strlen(buff));
13? ? strncpy(argv[0], "NewName", 7);
14? ? //Simulate a wait. Check the process name at this point
15? ? for (; i < 0xFFFFFFFF; i++);
16
17? ? return 0;
18 }
?
可以通过下面的方法测试
$ gcc chname.c -o chname
$ ./chname &
[1] 4677
$ ps 4677
? PID TTY? ? ? STAT? TIME COMMAND
?4677 pts/11? R? ? ? 0:08 NewName
?
11 局部变量的返回地址
Q:下面的代码有问题吗?如果有,如何修改?
?
?1 #include
?2 int* inc(int val)
?3 {
?4? ? int a = val;
?5? ? a++;
?6? ? return &a;
?7 }
?8
?9 int main(void)
10 {
11? ? int a = 10;
12? ? int *val = inc(a);
13? ? printf("\n Increamented value is equal to [%d] \n", *val);
14
15? ? return 0;
16 }
?
A:虽然上面的代码有时运行会很好,但是在方法 inc() 中有很严重的隐患,因为它返回了局部变量的地址。当inc()方法执行后,再次使用局部变量的地址就会造成不可估量的结果。解决之道就是传递变量a的地址给main()。PS:我觉得最后一句的说法有问题。
?
12 处理printf()参数
Q:请问以下代码的输出是什么?
?
#include
?
int? main( void )
{
? ? int? a = 10, b = 20, c = 30;
? ?
? ? printf ("\n %d..%d..%d \n", a+b+c, (b = b*2), (c = c*2));
? ? return? 0;?
}
?
A:程序的输出如下:
?110..40..60
这是因为参数都是从右向左处理的,然后打印出来却是从左向右。