在C语言中,函数实参与形参之间的数据传递方式是( )传递方式?
实参与形参数据传递有两种方式:值传递与地址传递
地址传递的形式为 int &a=b;也就是我们所说的引用,但引用只有C++中有,所以C语言都是值传递的。函数实参与形参之间的数据传递方式是传递方式,在C语言中,数据传递方式有值传递和引用传递。
值传递:传值,实际是把实参的值赋值给行参,相当于copy。那么对行参的修改不会影响实参的值引用传递: 实际是传值的一种特殊方式只是他传递的是地址,不是普通的赋值,那么传地址以后,实参和行参都指向同一个对象,因此对形参的修改会影响到实参。
机器语言的全部指令?
计算机指令的集合是程序。 分析: 计算机指令集合称为指令集,计算机指令达到指定的目的为程序。 指令是指计算机完成某个基本操作的命令。 指令能被计算机硬件理解并执行。 一条指令就是 计算机机器语言的一个语句,是程序设计的最小语言单位。 一台计算机所能执行的全部指令 的集合,称为这台计算机的指令系统。 指令系统比较充分地说明了计算机对数据进行处理的 能力。 不同种类的计算机,其指令系统的指令数目与格式也不同。 指令系统越丰富完备,编 制程序就越方便灵活。 指令系统是根据计算机使用要求设计的。
Linux系统中,C语言程序属于进程吗?进程和程序之间是什么关系?
C语言程序员编写的代码可以编译为程序,程序通常存放在磁盘等存储介质中。在 Linux 中,处于运行期的程序被称作“进程”。
进程
虽说进程是处于运行期的程序,但是进程并不仅仅局限于可执行的C语言代码(Linux 称其为代码段,text section),它还包括其他资源,例如用于存放全局变量的数据段(data section)、具有内存映射的内存地址空间、要处理的数据、挂起的信号、打开的文件,可能还会包括多个执行线程等等。
事实上,进程是 Linux 操作系统抽象概念的最基本的一种,Linux 最基础最重要的工作之一就是管理系统中繁杂的各种进程。
上面提到的“执行线程”通常被简称为“线程”,它被进程包含,同一个进程可能有多个线程,每个线程都有自己独立的程序计数器、进程栈以及相关的进程寄存器。虽说 Linux 内核管理的是进程,但其实最小的调度单位是线程。
早期传统的 Unix 系统中,一个进程只能包含一个线程,所以当时进程调度和线程调度其实结果是一致的。
线程
如今的操作系统中,进程包含多个线程是非常常见的。Linux 与一些其他操作系统不同,它对进程和线程并不明确区分,对于 Linux 来说,线程不过是一种比较特殊的进程而已。
包括 Linux,现代操作系统一般都会为进程提供两种虚拟机制:虚拟处理器和虚拟内存。读者应注意“虚拟”一词,多个进程可能共同使用一个 CPU 和内存,但是“虚拟机制”会让进程活在楚门的世界一样,自以为自己独占 CPU 和全部内存。
应注意,线程之间可以共享虚拟内存,但是它们仍然拥有各自的虚拟 CPU。
到这里,读者应该明白了,编译器生成的C语言程序本身并不是进程。进程实际上是处于运行期的程序,与相关资源的总和。
事实上,无论是程序不同,还是执行时的数据不同,都会产生不同的进程。举例来说,同样一个C语言程序,是可以产生两个不同的进程的——它们的运行资源可能是不同的。反过来也是一样的,多个不同的进程也可以共享同一份资源,例如打开同一个文件,映射同一块内存空间等。
进程的产生与消亡
可能有读者认为,直接执行一个程序不就产生新进程了吗?这样说没有错,但是不够本质。在 Linux 操作系统中,通过 fork() 系统调用可以复制现有进程,并产生新进程。调用 fork() 的进程一般被称作“父进程”,而 fork() 产生的新进程则被称作“子进程”。
fork() 调用结束时,会从 Linux 内核返回两次:一次返回到父进程,父进程恢复运行。一次返回到子进程,子进程开始执行,在这之后,父子进程的进程资源彼此隔离,不再共享。
不过一般来说,如果有需求创建新的进程,一般都是为了执行不同的新的程序。这一过程通过 exec() 函数族可以方便实现,它们可以为新程序创建新的地址空间,然后加载程序执行。
Linux 操作界面的 shell 终端其实也是一个进程,通过 shell 输入的执行新程序命令(如 ./a.out )产生的新进程其实都是对应 shell 终端的子进程。
程序既然有新生,也就会有死亡,程序运行结束后,通过 exit() 系统调用退出运行,这个函数会杀死进程,并且将其占用的资源释放,通知其父进程“死亡信息”。父进程则可以通过 wait() 函数族接收子进程的“死亡信息”,并着手为子进程做后续的“收尸工作”,避免子进程编程“僵尸进程(zombie)”。
“僵尸进程”很难杀死,但是留着“僵尸进程”又会白白浪费系统资源。