第七章 高级环境

第七章 高级环境

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];
  • 栈。自动变量以及每次函数调用时所需保存的信息都存放在此段中。每次函数调用时,其返回地址以及调用者的环境信息(如某些机器寄存器的值)都存放在栈中。然后,最近被调用的函数在栈上为其自动和临时变量分配存储空间。
  • 堆。通常在堆中进行动态存储分配。由于历史形成的惯例,堆位于未初始化数据段和栈之间。

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

时间: 2024-10-07 03:19:03

第七章 高级环境的相关文章

APUE学习笔记:第七章 进程环境

7.1 引言 本章将学习:当执行程序时,其main函数是如何被调用的:命令行参数是如何传送给执行程序的:典型的存储器布局是什么样式:如何分配另外的存储空间:进程如何使用环境变量:各种不同的进程终止方式等:另外还将说明longjmp和setjmp函数以及它们与栈的交互作用:还将介绍研究进程的资源限制 7.2 main函数 C程序总是从main函数开始执行.当内核执行C程序时,在调用main前先调用一个特殊的启动例程.可执行程序文件将此启动例程指定为程序的起始地址——这是由连接编辑器设置的,而连接编

APUE学习笔记(第七章 进程环境)

本章将了解进程的环境. main函数 C程序总是从main函数开始执行,main函数的原型是: int main(int argc,char *argv[]); 其中,argc是命令行参数的数目,argv是指向参数的各个指针所构成的数组. 进程终止 3个函数用于正常终止一个程序:_exit和_Exit立即进入内核,exit则先执行一些清理处理(对于所有打开流调用fclose函数),然后返回内核. #include <stdlib.h> void exit(int status); void _

Java数据结构与算法(第七章高级排序1)

希尔排序 希尔排序是计算机科学家Donald L.Shell 而得名,他在1959年发现了希尔排序算法.希尔排序基于插入排序,但是增加了一个新的特性,大大提高了插入排序的执行效率. 插入排序:复制的次数太多 由于希尔排序是基于插入排序的,所以需要回顾下"插入排除".在插入排除执行的一半的时候,标记符左边这部分数据项都是排过序的(这些数据之间是有序的),而记右边的数据项没有排过序.这个算法取出标记符所指的数据项,把它存储在一个临时的变量.接着,从刚刚被移除的数据项的左边第一个单元看是,每

BPM-第七章-高级OOP特征

对象克隆,继承,接口,抽象类,命名空间 PHP5之后,将所有的对象都看成了引用. PHP不支持的高级OOP特征: 方法重载:不支持通过方法重载实现多态 操作都重载:不支持根据数据类型为操作符赋予新的含义 多重继承:不支持多重继承,支持实现多个接口 对象克隆 clone 关键字 destobj = clone sourceobj; __clone() 方法.在类中定义__clone()方法来调整对象的克隆行为. 继承 继承通过extends关键字实现 继承与延时绑定 ## 接口 原文地址:http

Java数据结构与算法(第七章高级排序2)

划    分 划分数据就是把数据分为两组,使所有关键字大于特定值的数据项在一组,是所有关键字小于特定值的数据项在另一组. package com.gaojipaixu.partition; public class Arraypar{     private long[] theArray;     private int nElems;          public Arraypar(int max){         theArray = new long[max];         nE

《Unix环境高级编程》读书笔记 第7章-进程环境

1. main函数 int main( int argc, char *argv[] ); argc是命令行参数的数目,包括程序名在内 argv是指向参数的各个指针所构成的数组,即指针数组 当内核执行C程序时(使用exec函数),在调用main前先调用一个特殊的启动例程.可执行程序文件将此启动例程指定为程序的起始地址——这是由连接器设置的,而连接器则是由C编译器调用.启动例程从内核取得命令行参数和环境变量值,然后按上述方式调用main函数做好安排. 2. 进程终止 有8种方式使进程终止,其中5种

JavaScript高级程序设计(第3版)第七章读书笔记

第七章 函数表达式 1. 函数声明有一个重要特征 ,函数声明提升.即在执行代码之前会先读取函数声明,意味着可以把函数声明放在调用它的语句后面. 2. 使用arguments.callee实现对函数的递归调用.但在严格模式下,不能通过脚本访问arguments.callee,但可以使用命名函数表达式来达成相同的效果. 3. 闭包是指有权访问另一个函数作用域中的变量的函数.创建闭包的常用方式,就是在一个函数内部创建另一个函数. 4. 由于闭包会携带包含它的函数的作用域,因此会比其他函数占更多的内存.

第七章、高级数据库查询

第七章.高级数据库查询 内容提要: 1. 掌握一般数据查询功能扩展 2. 掌握查询的并.交.差运算 3.掌握子查询的使用 4.了解其他一些查询功能 第一节 一般数据查询功能扩展 1.1. SELECT语句 //SQL的一般查询语句 SELECT [DISTINCT] [TOP n] select_list //将查询的结果插入到了一个表中 [INTO new_table] //需要查询的表 [FROM table_source] //查询的条件 [WHERE search_conditition

C#高级编程第11版 - 第七章

导航 C# 全版本特性一览 全书目录 第七章 Arrays 7.1 相同类型的多个对象 151 7.2 简单数组 152 7.2.1 数组的声明 152 7.2.2 数组的初始化 152 7.2.3 访问数组元素 153 7.2.4 使用引用类型 153 7.3 多维数组 154 7.4 锯齿数组 155 7.5 Array 类 156 7.5.1 创建数组 156 7.5.2 复制数组 156 7.5.3 排序 157 7.6 数组作为参数 159 7.7 数组协变 159 7.8 枚举 16