码迷,mamicode.com
首页 > 其他好文 > 详细

第七章 高级环境

时间:2018-04-15 20:53:57      阅读:142      评论:0      收藏:0      [点我收藏+]

标签:存储   调用   汇编   数据   修改   reg   关闭   return   程序   

第七章 高级环境
7.2 main函数
C程序总是从main函数开始执行的。main函数的原型是:
int main(int argc, char *argv[]);
其中,argc是命令行参数的数目,argv是指向参数的各个指针所构成的数组。
当内核执行C程序的时候(使用一个exec函数),在调用main前先调用一个特殊的启动例程。可执行程序文件将此启动例程指定为程序的起始地址--
这是由连接编辑器设置的,而连接编辑器则是由C编译器调用的。启动例程从内核取得命令行参数和环境变量值,然后为按上述方式调用main函数做好安排。
 
7.3进程终止
有8种方式使进程终止。其中5种为正常终止,依次是:
  • 从main函数返回
  • 调用exit
  • 调用_exit或_Exit
  • 最后一个线程从期启动例程返回
  • 从最后一个线程调用pthread_exit
异常终止有3种,依次为:
  • 调用abort
  • 接到一个信号
  • 最后一个线程对取消请求做出响应
 
7.3.1 退出函数
3个函数用于正常终止一个程序:_exit和_Exit立即进入内核,exit则先执行一些清理处理,然后返回内核。
#include <stdlib.h>
void exit(int status);
void _Exit(int status);
#include <unistd.h>
void _exit(int status);
//exit函数总是执行一个标准I/O库的清理关闭操作:对所有打开流调用fclose函数。
3个退出函数都带一个整型参数,称为终止状态。如果
调用这些函数时不带参数 或
main执行了一个无返回值的return语句 或
main没有声明返回类型为整型
则该进程的终止状态为未定义的。但是,若main返回类型是整型,并且main执行到最后一条语句时返回,则该进程的终止状态是0;
main函数返回一个整型值与用该值调用exit是等价的。于是在main函数中exit(0)等价于return(0);
7.3.2 atexit
按照ISO C的规定,一个进程可以登记多至32个函数,这些函数将由exit自动调用。我们称这些函数为终止处理程序,并调用atexit函数来登记这些函数。
#include<stdlib.h>
int atexit(void (*func)(void));
也就是说通过atexit函数登记若干函数,在程序退出时会自动调用被登记的函数。
 技术分享图片
 
技术分享图片
 
说明使用atexit函数。
 
#include <stdlib.h>
#include <stdio.h>
static void my_exit1(void);
static void my_exit2(void);
 
int main(void)
{
    if (atexit(my_exit2) != 0)
    {
    printf("can‘t register my_exit2\n");
    }
 
    if (atexit(my_exit1) != 0)
    {
    printf("can‘t register my_exit1\n");
    }
 
    if (atexit(my_exit1) != 0)
    {
    printf("can‘t register my_exit1\n");
    }
    
    printf("main id done\n");
    return 0;
}
static void my_exit1(void)
{
    printf("first exit handler\n");
}
 
static void my_exit2(void)
{
    printf("second exit handler\n");
}
 技术分享图片
技术分享图片
 
7.4命令行参数
当执行一个程序的时候,调用exec的进程可以将命令行参数传递给该新函数。
#include<stdio.h>
int main(int args, char *argv[])
{
    int i;
    for (i = 0; i<args; i++)
    {
        printf("argv[%d]:%s\n", i, argv[i]);
    }
    return 0;
}
 技术分享图片
技术分享图片
7.5环境表
每个程序都接收到一张环境表。与参数表一样,环境表也是一个字符指针数组。其中每个指针包含一个以null结尾的C字符串地址。全局变量
environ则包含了该指针数组的地址:extern char **environ;
7.6 C程序的存储空间布局
C程序一直由下列部分构成:
  • 正文段。这是由CPU执行的机器指令部分。通常,正文段是可共享的,所以即使是频繁的执行的程序在存储器中也只需有一个副本。此外正文段常常是只读的,以防止程序由于意外而修改其指令。
  • 初始化数据段。通常将此段称为数据段,它包含了程序中需明确地赋初值的变量。例如,在C程序中任何函数之外的声明:int maxcoubnt =99; 使此变量以其初值存放在初始化数据段中。
  • 未初始化数据段。通常将此段称为bss段。这一名称来源于早期汇编程序一个操作符,意思是“由符号开始的块”,在程序开始执行前,内核将此段中的数据初始化为0或空指针。函数外声明:long sum[10];
  • 栈。自动变量以及每次函数调用时所需保存的信息都存放在此段中。每次函数调用时,其返回地址以及调用者的环境信息(如某些机器寄存器的值)都存放在栈中。然后,最近被调用的函数在栈上为其自动和临时变量分配存储空间。
  • 堆。通常在堆中进行动态存储分配。由于历史形成的惯例,堆位于未初始化数据段和栈之间。
 技术分享图片
 
技术分享图片
 
 

第七章 高级环境

标签:存储   调用   汇编   数据   修改   reg   关闭   return   程序   

原文地址:https://www.cnblogs.com/xiaodeyao/p/8849077.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!