<二>、进程-(eixt)(_exit)(atexit)(exec)

本文深入探讨了程序开发中的核心流程及关键函数,包括`exit`、`_exit`、`atexit`、`exec`等,详细解释了它们的功能、用法和应用场景。通过实际代码示例,展示了这些函数如何在程序中执行流程控制和资源清理,对于理解程序生命周期和错误处理至关重要。

《exit函数实现》

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main (void )
{
 pid_t ret;

 printf("hello!\n");
 
   printf("In parent process, pid =%d", getpid());
 exit(0); 
 return 0;
}

结果:

hello!
In parent process, pid =3342
********************************************************

《_exit函数实现》

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main (void )
{
 pid_t ret;

 printf("hello!\n");
 printf("22hello!\n");
 printf("two hello!");
   printf("In parent process, pid =%d", getpid());
 _exit(0); 
 printf(" e next hello!\n");
 printf(" e frok hello!");
 return 0;
}

结果:
hello!
22hello!

********************************************************

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
void exit_func1(void)
{
 printf("exit_func1\n");
}

void exit_func2(void)
{
        printf("exit_func2\n");
}

int main (void )
{
// pid_t ret;

 printf("hello!\n");

 atexit(exit_func1);
 atexit(exit_func2);

   printf("In parent process, pid =%d", getpid());
 exit(0); 
 printf("newver be dispalyed\n");
 return 0;
}

结果:

hello!
In parent process, pid =3554exit_func2
exit_func1

-----------

main主函数执行完毕后,是否可能会再执行一段代码?
如果需的话,可以用ateixt()函数注册一个函数:
 1 #include<stdio.h>
  2 #include<stdlib.h>
  3
  4 void fumc1()
  5 {printf("next\n");}
  6
  7 void fumc2()
  8 {printf("executed");}
  9 void fumc3()
 10 {printf("is");}
 11 void fumc4()
 12 {printf("this");}
 13
 14 void main()
 15 {
 16     char str[]="0123456789";
 17 atexit(fumc1);
 18 atexit(fumc2);
 19 atexit(fumc3);
 20 atexit(fumc4);
 21 printf("This is execued frist. \n");
 22 printf("%d\n",sizeof(str));
 23}
结果:
This is execued frist.
11
thisisexecutednext
本来到该结束程序printf("%d\n",sizeof(str));,
但是还打印thisisexecutednext
说明:该程序结束后,还运行atexit函数
而且到过来运行
****************************************************

《exec函数实现》

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main (void )
{ pid_t ret;
 printf("hello!\n");
 ret = fork();
 printf("Have forked!\n");
 if (ret < 0 ) {
  perror("fork");
  exit(1); }
 if (ret == 0 ) {  //子进程  
//printf("In child process, pid=%d, ppid=%d\n", getpid(), getppid());
  if (execl("/bin/ls", "ls", "-al", NULL) <0 ) {
   perror("execl error!");
   exit(1); 
  }
  printf("Can't run to here in normal!\n");
//     execlp("ls", "ls", "-al", NULL);
   exit(0); }
 sleep(5);
   printf("In parent process, pid =%d, child pid=%d\n", getpid(), ret);
 return 0;
}

结果:


hello!
Have forked!
Have forked!
total 108
drwxrwxrwx 2 nobody nogroup  4096 2011-12-07 18:06 .
drwxrwxrwx 9 lsb    lsb      4096 2011-12-07 18:00 ..
-rwxr--r-- 1 nobody nogroup   380 2011-07-20 23:58 atexit.c
-rwxr-xr-x 1 lsb    lsb      7861 2011-12-07 02:33 c
-rwxr--r-- 1 nobody nogroup  3527 2011-12-07 02:33 c.c
-rwxr-xr-x 1 lsb    lsb      7350 2011-12-07 18:06 exec
-rwxr--r-- 1 nobody nogroup   601 2011-07-20 23:47 exec.c
-rwxr-xr-x 1 lsb    lsb      7202 2011-12-07 18:04 exit
-rwxr--r-- 1 nobody nogroup   193 2011-07-20 23:51 _exit.c
-rwxr--r-- 1 lsb    lsb       194 2011-12-07 18:04 exit.c
-rwxrwxrwx 1 root   root     7350 2011-12-07 02:20 fork
-rwxrwxrwx 1 nobody nogroup   502 2011-07-20 23:40 fork.c
prw-r--r-- 1 lsb    lsb         0 2011-12-07 02:30 in1
prw-r--r-- 1 lsb    lsb         0 2011-12-07 02:30 in2
-rwxr-xr-x 1 lsb    lsb      7508 2011-12-07 02:26 pipe
-rwxrwxrwx 1 nobody nogroup  1378 2008-12-19 03:17 pipe.c
-rwxr-xr-x 1 lsb    lsb      7528 2011-12-07 02:30 pipe_select
-rwxr--r-- 1 nobody nogroup  3029 2008-12-19 03:17 pipe_select.c
-rwxr-xr-x 1 lsb    lsb     12180 2011-12-07 02:35 s
-rwxr--r-- 1 nobody nogroup  4865 2011-12-07 02:32 s.c
In parent process, pid =3157, child pid=3158
************************************************************************

 

 

<think>好的,用户遇到了编译警告,需要解决。首先看警告信息,第一个是关于`EXTI_PinSource`函数隐式声明,第个是`EXTI_Line`函数隐式声明。我需要检查STM32库函数的正确用法。首先,STM32的库函数中,`SYSCFG_EXTILineConfig`的第个参数应该是`EXTI_PinSource0`到`EXTI_PinSource15`这样的宏定义,而不是函数调用。用户可能错误地将`EXTI_PinSource(pin)`写成了函数,但实际上应该是宏,比如`EXTI_PinSource0`对应pin=0,`EXTI_PinSource1`对应pin=1,以此类推。所以需要用条件判断或宏替换来正确设置。然后,`EXTI_Line`同样不是函数,而是宏定义,比如`EXTI_Line0`到`EXTI_Line15`。用户代码中使用`EXTI_Line(line)`,这会被编译器认为是函数调用,但实际上应该直接使用对应的宏,比如当line=0时是`EXTI_Line0`,line=1时是`EXTI_Line1`等。所以,修改方法是将`EXTI_PinSource(pin)`替换为正确的宏,例如使用`EXTI_PinSource0+pin`或者通过条件判断。同样,`EXTI_Line(line)`应替换为`EXTI_Line0+line`,因为这些宏是连续定义的,比如`EXTI_Line0`是0x00000001,`EXTI_Line1`是0x00000002,依此类推,直到`EXTI_Line15`是0x00008000。因此,可以通过位移或直接计算来得到正确的宏值。另外,需要确认STM32F4的标准外设库中这些宏的定义是否正确。例如,`EXTI_PinSource0`到`EXTI_PinSource15`是定义在`stm32f4xx_exti.h`中的宏,值分别为0到15。而`EXTI_Line0`到`EXTI_Line15`是`EXTI_Line`的各个位,对应不同的EXTI线。因此,用户代码中的错误在于错误地调用了不存在的函数`EXTI_PinSource`和`EXTI_Line`,而应该直接使用预定义的宏。修改时,对于`SYSCFG_EXTILineConfig`的第个参数,应该根据pin的值选择对应的`EXTI_PinSourceX`宏,例如当pin=0时是`EXTI_PinSource0`,pin=1时是`EXTI_PinSource1`,以此类推。同样,`EXTI_Line`应该使用`EXTI_Line0`到`EXTI_Line8`的宏。具体修改方法可以是使用循环变量pin,然后通过`EXTI_PinSource0+pin`来得到正确的宏值,因为`EXTI_PinSource0`是0,`EXTI_PinSource1`是1,依此类推。同样,`EXTI_Line`的宏是`1<< line`,因为`EXTI_Line0`是1(0x0001),`EXTI_Line1`是2(0x0002),直到`EXTI_Line15`是32768(0x8000)。所以,`EXTI_Line(line)`可以替换为`1<< line`,或者直接使用`EXTI_Line0+(1<< line)`?需要确认库中的定义。例如,在`stm32f4xx_exti.h`中,`EXTI_Line`的定义是:#defineEXTI_Line0((uint32_t)0x00000001)/*!< Externalinterruptline0*/#defineEXTI_Line1((uint32_t)0x00000002)/*!< Externalinterruptline1*/#defineEXTI_Line2((uint32_t)0x00000004)/*!< Externalinterruptline2*/...#defineEXTI_Line15((uint32_t)0x00008000)/*!< Externalinterruptline15*/所以,`EXTI_Line(line)`应该是`1<< line`,当line从0到15时。因此,在代码中,`EXTI_InitStructure.EXTI_Line=1<< line;`或者更明确地,使用`(EXTI_Line_TypeDef)(1<< line)`,但需要确保类型正确。同样,`SYSCFG_EXTILineConfig`的第个参数是`EXTI_PinSourceTypeDef`类型,定义为:typedefenum{EXTI_PinSource0=0x00,EXTI_PinSource1=0x01,EXTI_PinSource2=0x02,EXTI_PinSource3=0x03,EXTI_PinSource4=0x04,EXTI_PinSource5=0x05,EXTI_PinSource6=0x06,EXTI_PinSource7=0x07,EXTI_PinSource8=0x08,EXTI_PinSource9=0x09,EXTI_PinSource10=0x0A,EXTI_PinSource11=0x0B,EXTI_PinSource12=0x0C,EXTI_PinSource13=0x0D,EXTI_PinSource14=0x0E,EXTI_PinSource15=0x0F}EXTI_PinSourceTypeDef;所以,当pin是0到8时,对应的`EXTI_PinSourceTypeDef`值就是pin本身。因此,`SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,(EXTI_PinSourceTypeDef)pin);`是正确的,因为`EXTI_PinSource0`到`EXTI_PinSource8`的值正好是0到8,所以将pin转换为`EXTI_PinSourceTypeDef`类型即可。因此,用户代码中的`EXTI_PinSource(pin)`应该改为`(EXTI_PinSourceTypeDef)pin`,而`EXTI_Line(line)`应该改为`(1<< line)`,或者更准确地,使用`EXTI_Line`的宏定义,例如`EXTI_Line0`对应line=0,即`1<<0`,`EXTI_Line1`是`1<<1`等。修改后的代码部分应该是:在绑定EXTI线的循环中:SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,(EXTI_PinSourceTypeDef)pin);在配置EXTI_Line时:EXTI_InitStructure.EXTI_Line=(1<< line);//或者更明确地使用(uint32_t)(1<< line)或者,更规范的方式是使用库中定义的宏,但由于宏是`EXTI_Line0`到`EXTI_Line15`,可以通过指针或数组来引用,但可能比较麻烦。直接使用位移运算更简单,因为这些宏的值就是对应的位掩码。这样修改后,编译器就不会再报隐式声明的警告了,因为现在使用的是正确的类型转换和宏值,而不是调用不存在的函数。</think> 这两个警告是由于代码中错误调用了不存在的函数`EXTI_PinSource()`和`EXTI_Line()`导致的。STM32标准库中**没有这两个函数**,实际应使用预定义的宏或类型转换来配置EXTI线。以下是修正方法及说明: ### 错误原因分析 1. **`EXTI_PinSource(pin)`错误** `SYSCFG_EXTILineConfig()`函数的第个参数需要的是`EXTI_PinSourceTypeDef`类型的宏(如`EXTI_PinSource0`、`EXTI_PinSource1`等),而非函数调用。这些宏的值是`0x00`到`0x0F`(对应Pin0到Pin15),可直接通过类型转换实现动态配置。 2. **`EXTI_Line(line)`错误** `EXTI_InitStructure.EXTI_Line`需要的是`EXTI_Line`类型的宏(如`EXTI_Line0`、`EXTI_Line1`等),这些宏本质是位掩码(`0x00000001`、`0x00000002`…),可通过位移运算(`1 << line`)动态生成。 ### 修正后的关键代码 ```c // 3. 绑定PC0-PC8到对应的EXTI线(修正后) for (uint8_t pin = 0; pin <= 8; pin++) { // 将pin转换为EXTI_PinSourceTypeDef类型(如pin=0对应EXTI_PinSource0) SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, (EXTI_PinSourceTypeDef)pin); } // 4. 配置EXTI中断(修正后) for (uint8_t line = 0; line <= 8; line++) { // EXTI_Line0对应1<<0(0x0001),EXTI_Line1对应1<<1(0x0002),以此类推 EXTI_InitStructure.EXTI_Line = (uint32_t)(1 << line); // 动态生成EXTI线掩码 EXTI_Init(&EXTI_InitStructure); } ``` ### 修正说明 - **`EXTI_PinSourceTypeDef`类型转换**:`SYSCFG_EXTILineConfig()`的第个参数要求是`EXTI_PinSourceTypeDef`枚举类型(定义在`stm32f4xx_exti.h`中),其值正好是`0`到`15`(对应Pin0到Pin15)。因此直接将循环变量`pin`转换为该类型即可,无需额外函数。 - **`EXTI_Line`位掩码生成**:`EXTI_Line0`到`EXTI_Line15`的宏定义本质是`1 << 0`到`1 << 15`(如`EXTI_Line0=0x0001`,`EXTI_Line1=0x0002`)。通过`(1 << line)`可以动态生成对应EXTI线的位掩码,无需调用函数。 ### 验证方法 编译后警告应消失。若仍有问题,需检查: 1. 是否包含`stm32f4xx_exti.h`头文件(确保`EXTI_PinSourceTypeDef`和`EXTI_Line`宏被正确识别)。 2. 循环变量`pin`和`line`的范围是否在`0-8`内(与PC0-PC8对应)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值