这一章主要是要解决这么几个问题:

当执行程序时,main函数是如何被调用的?

main函数的原型是:

int main(int argc, char *argv[]);

其中argc是命令个数,argv则是字符指针,指向字符串(命令)。

当内核执行一个C程序的时候,是由一个特别的起始例程(exex函数族的一个)来调用main函数的。

命令行参数是如何传递给执行程序的?

当执行一个程序时,调用exec的进程可将命令行参数传递给该新程序。argc[argc]是NULL。

典型的存储器布局是什么样式的?

一个C程序由这么几个segment(段)组成:text segment, data segment, bss segment, stack segment, heap等。

bss段就是用来存放全局变量等不在函数内声明的变量。(所以你定义了一个全局变量,但没有初始化,你打印出来会是等于0的。因为exec会帮你初始化为0)

如何分配额外的存储空间?

ISOC指定了三个用于动态分配内存的函数:

(1)malloc,分配指定字节数的存储区。此存储区的字节的初始值不确定。

(2)calloc,为指定数量和指定字节数的对象分配存储空间,该空间中的每一位都初始化为0。

(3)realloc,更改以前分配区的长度(增加或减少),当增加时,则是移向一块更加的新区域,新增的部分的初始值不确定。

#include <stdlib.h>

void *malloc(size_t size);

void *calloc(size_t nobj, size_t size);

void *realloc(void *ptr, size_t newsize);

三个函数返回值:成功返回非NULL指针,失败返回NULL指针

void free(void *ptr);

对于上面的这四个函数,我是对malloc和free比较熟悉。下面再说点,其实实际获得的空间会比要求的会多一些出来,多出来的会用来存储这个空间的一些参数,比如说:分配空间的大小,指向下一个分配空间的指针等等。

所以使用这些函数一般比较多犯的两个错误是:1.像数组那样,越界,往后面写东西,这样会导致一些很严重的错误,可能下一个分配空间的指针指向的空间就找不到了。

2.没有free调那些不用的空间,那么就会造成泄漏或者free掉一个空指针。

这两个错误都是很难检测出来的,所以要特别小心。

进程如何使用环境变量?

介绍几个用于环境变量操作的函数:

#include <stdlib.h>

char *getenv(const char *name);

找到则指向该环境变量的指针,否则返回NULL

int putenv(char *str);

int setenv(const char *name, const char *value, int rewrite);

int unsetenv(const char *name);

三个函数返回值:成功返回0,出错返回非0

getenv()函数就是获得某个环境变量的值;

putenv()取形式为name = value的,并将其放入环境表中。如果name已经存在,则先删除原来的定义字符串。

setenv()将name设置为value。如果环境中name已经存在,则若rewrite非0,则首先删除现有的定义;若rewrite为0,则不删除现有定义(什么都不干)。

unsetenv()则删除name的定义,即使不存在也不出错。

各种不同的进程终止方式(因为现在还不太懂,所以也只是简单的说一下)

有8种方式使进程终止,其中5种是正常终止

1.从main返回

2.调用exit

3.调用_exit或_Exit

4.最后一个线程从其启动例程返回

5.最后一个线程调用pthread_exit

异常终止有3种方式

6.调用abort

7.接到一个信号并终止

8.最后一个县城对取消请求作出响应

longjmp和setjmp函数以及它们和栈的交互作用

我们都知道,栈是保存用来保存函数的一些信息的,以便返回时能够找到之前的那个函数。比如这么一个例子,main函数里调用do_line函数,do_line函数里调用cmd_add函数,则当调用到cmd_add函数时,栈是这样的:

要是在cmd里遇到错误,想返回到main函数时怎么办?那就要用到setjmp函数和longjmp函数了。

#include <setjmp.h>

int setjmp(jmp_buf env);

返回值:直接调用返回0,否则就返回longjmp的val值

void longjmp(jmp_buf env, int val);

简单来说,在嵌套调用的函数中,如果遇到了longjmp函数,则会马上返回到调用setjmp函数的那个函数。比如说我在cmd_add函中调用了longjmp函数,在main函数中设置setjmp函数。当我在cmd_add函数中因为错误而触发到longjmp函数,那么就会马上返回到具有setjmp函数的main函数了。当返回去了,而在栈里各个函数的变量的值会变得怎样呢?

下面给出例子:

 #include "apue.h"
#include <setjmp.h> static void f1(int, int, int, int);
static void f2(void); static jmp_buf jmpbuffer;
static int globval; int main(void)
{
int autoval;
register int regival;
volatile int volaval;
static int statval; globval = ;
autoval = ;
regival = ;
volaval = ;
statval = ; if (setjmp(jmpbuffer) != )
{
printf("after longjmp\n");
printf("globval = %d, autoval = %d, regival = %d, volaval = %d, statval = %d\n",
globval, autoval, regival, volaval, statval);
exit();
} /*
* Change variables after setjmp, but before longjmp.
*/
globval = ;
autoval = ;
regival = ;
volaval = ;
statval = ; f1(autoval, regival, volaval, statval); /* never return */
exit(); } static void f1(int i, int j, int k, int l)
{
printf("in f1():\n");
printf("globval = %d, autoval = %d, regival = %d, volaval = %d, statval = %d\n",
globval, i, j, k, l);
f2();
} static void f2()
{
longjmp(jmpbuffer, );
}

书上说这变量变不变是看情况,你可以在你自己的电脑上试一试。

《APUE》第七章笔记的更多相关文章

  1. #Python编程从入门到实践#第四章笔记

    #Python编程从入门到实践#第四章笔记   操作列表 ​​​1.遍历列表 使用for循环,遍历values列表 for value in values: print(value) 2.数字列表 使 ...

  2. #Python编程从入门到实践#第三章笔记

      列表简介 ​​​1.什么是列表 列表:由一系列按也顶顺序排列的元素组成.元素之间可以没有任何关系. 列表:用方括号[]表示,并用逗号分隔其中元素.名称一般为复数 2.访问元素 (1)列表是有序集合 ...

  3. 《Python编程从入门到实践》第二章_变量和简单数据类型

    什么是变量呢? 举例: >>> message = "Hello,Python!" >>> print (message) Hello,Pyth ...

  4. 设置应用程序的样式并对其进行部署——《Python编程从入门到实践》

    我们将使用应用程序django-bootstrap3为Web应用程序设计样式.我们将把项目"学习笔记"部署到Heroku,这个网站能让我们们将项目推送到其服务器,让任何有网络连接的 ...

  5. Python编程从入门到实践笔记——异常和存储数据

    Python编程从入门到实践笔记——异常和存储数据 #coding=gbk #Python编程从入门到实践笔记——异常和存储数据 #10.3异常 #Python使用被称为异常的特殊对象来管理程序执行期 ...

  6. Python编程从入门到实践笔记——文件

    Python编程从入门到实践笔记——文件 #coding=gbk #Python编程从入门到实践笔记——文件 #10.1从文件中读取数据 #1.读取整个文件 file_name = 'pi_digit ...

  7. Python编程从入门到实践笔记——类

    Python编程从入门到实践笔记——类 #coding=gbk #Python编程从入门到实践笔记——类 #9.1创建和使用类 #1.创建Dog类 class Dog():#类名首字母大写 " ...

  8. Python编程从入门到实践笔记——函数

    Python编程从入门到实践笔记——函数 #coding=gbk #Python编程从入门到实践笔记——函数 #8.1定义函数 def 函数名(形参): # [缩进]注释+函数体 #1.向函数传递信息 ...

  9. Python编程从入门到实践笔记——用户输入和while循环

    Python编程从入门到实践笔记——用户输入和while循环 #coding=utf-8 #函数input()让程序暂停运行,等待用户输入一些文本.得到用户的输入以后将其存储在一个变量中,方便后续使用 ...

  10. Python编程从入门到实践笔记——字典

    Python编程从入门到实践笔记——字典 #coding=utf-8 #字典--放在{}中的键值对:跟json很像 #键和值之间用:分隔:键值对之间用,分隔 alien_0 = {'color':'g ...

随机推荐

  1. PHP设计模式之策略模式

    前提: 在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能.如查 找.排序等,一种常用的方法是硬编码(Hard Cod ...

  2. 编程语言拟人化:Java、C++、Python、Ruby、PHP、C#、JS!--隆重推荐转

    http://next.rikunabi.com/tech/docs/ct_s03600.jsp?p=002412 Java.C++.Python.Ruby.C#.PHP.JavaScript.7つの ...

  3. 深入理解C语言中的指针与数组之指针篇(转载)

    前言 其实很早就想要写一篇关于指针和数组的文章,毕竟可以认为这是C语言的根本所在.相信,任意一家公司如果想要考察一个人对C语言的理解,指针和数组绝对是必考的一部分. 但是之前一方面之前一直在忙各种事情 ...

  4. Spring与Struts整合

    Spring框架是一个非常优秀的轻量级Java EE容器,Spring框架是整个轻量级Java EE框架的核心.大部分的Java EE应用,都会考虑使用Spring容器管理应用中的组件,从而保证各组件 ...

  5. Android(java)学习笔记71:生产者和消费者之等待唤醒机制

    1. 首先我们根据梳理我们之前Android(java)学习笔记70中关于生产者和消费者程序思路: 2. 下面我们就要重点介绍这个等待唤醒机制: (1)第一步:还是先通过代码体现出等待唤醒机制 pac ...

  6. JSON 日期格式问题 /Date(1325696521000)/

    json返回的日期格式/Date(1325696521000)/,怎么办? Controller返回的是JsonResult对象就会导致出现这样的格式: /Date(1325696521000)/ p ...

  7. android初学-togglebutton

    1.属性:textOn &textOff &checked 2.使用: 1)初始化:TB: 2)设置监听器:TB.setOnCheckedChangeListener(listener ...

  8. oracle锁

    1.概念 数据库中有两种基本的锁类型:排它锁(Exclusive Locks,即X锁)和共享锁(Share Locks,即S锁). 当数据对象被加上排它锁时,其他的事务不能对它读取和修改:加了共享锁的 ...

  9. [转]DataTable用中使用Compute 实现简单的DataTable数据的统计

    本文转自:http://blog.csdn.net/zwxrain/article/details/252285 調用格式: object DataTable.Compute(string expre ...

  10. [改善Java代码]集合中的元素必须做到compareTo和equals同步

    实现了Comparable接口的元素就可以排序,