C语言程序执行起点:深入理解main函数与程序计数器

创始人
2024-12-26 03:44:39
0 次浏览
0 评论

c语言程序从哪里开始执行

在C语言编程的世界里,程序的执行路径通常都是从main函数开始的,main函数就像程序的指挥中心,标志着程序生命的开始。
main函数是程序的主入口,它的第一条语句标志着程序的正式开始。
C语言程序遵循严格的执行顺序,从main函数的第一行开始,逐行执行。
每个代码块都按照预定的逻辑顺序执行。
在主函数中,您可以设置变量、调用其他函数、执行各种计算和操作以及构建程序骨架。
当程序被用户或操作系统加载时,操作系统会定位到可执行文件,然后将控制权交给主函数,就像司机坐在驾驶舱里准备开始驾驶一样。
这时,主函数占用的内存空间就成为程序的阶段,准备接收和执行指令。
在主函数代码中,你将发挥自己的编程能力,利用C语言提供的工具,如语句、表达式、控制结构等,设计并实现各种复杂的逻辑和算法,一切都为你所欲。
实现的具体功能。
总结一下,C语言程序的执行路径是从main函数开始的。
随着代码逐行进行,每一行都包含实现特定功能的关键步骤,直至完成整个程序的使命。

保存下一条将要执行的指令地址的寄存器是

程序计数器PC。
为了保证程序(理解为操作系统中的进程)能够连续运行,CPU必须有某种手段来确定下一条指令的地址。
程序计数器就是起到这个作用的,所以也常被称为指令计数器。

程序计数器流程:在程序开始运行之前,必须将起始地址,即程序指令所在的内存单元地址发送到PC,因此程序的内容计数器(PC)是从内存中取出的第一条指令的地址。
当指令执行时,CPU会自动改变PC的内容。

即每执行一条指令,PC就增加等于该指令字节数的量,这样它就始终维护着下一条要执行的指令的地址。
由于大多数指令都是顺序执行的,因此修改过程通常只是将PC加1。

扩展信息

程序计数器异常处理流程

当遇到JMP指令等传送指令时,后续指令的地址(即PC内容)必须从指令寄存器的地址字段中检索。
在这种情况下,从内存中取出的下一条指令将由分支指令指定,而不是像平常那样顺序取出。
因此,程序计数器的结构应该是具有记录信息和计数两种功能的结构。

程序中的每条指令都指定机器完成一组基本操作。
如果把计算机完成任务的过程比作乐队表演,那么控制器就像指挥家,计算机的其他功能部件就像不同的乐器和演员,程序就像乐谱。
计算机的工作过程就是行程序的过程,或者说控制器按照程序的规定对计算机进行控制。

电气三班c语言选择题

下列说法不正确的是()。
调用函数时,实际参数可以是表达式。
调用函数时,实参和形参可以共享一个内存单元。
调用函数时,将实参值复制到形参变量和形参变量在数值上相等,并且实参和形参的类型必须一致~B~~~6实参中的实参个数下面的函数调用语句是()。
func((exp1,exp2),(exp3,exp4,exp5));1235~B~~~6在C语言中,当function()被调用时。
实际参数和形式参数都占据独立的体积。
系统自动判断实参和形参是否共用一个存储单元。
~A~~6C语言规定程序中函数之间存在there()。
直接递归调用和间接递归调用都是允许的。
不允许直接递归调用不允许直接递归调用不允许直接递归调用不允许直接递归调用不允许间接递归调用不允许直接递归调用间接递归调用~A~~~8可以定义如下正确。
一维数组的选项是()。
inta[5]={0,1,2,3,4,5};chara[]={0,1,2,3,4,5};chara={'A','B','C'};inta[5]="0123";~B~~~8下面的说法是错误的()。
对于双精度型数组,不能直接使用数组名来输入或输出整个数组。
数组名代表数组所占用的存储区域的首地址,其值在程序执行过程中不能改变,数组元素的下标超过指定值。
当超出低限范围时,系统将给出“低限越界”错误信息。
可以通过设置初始值来指定数组元素的个数~C~~8包含如下程序:#includemain(){charp[]={'a','b','c'},q[10]={'a','b','c'};printf("%d%d\n",strlen(p),strlen(q));}以下说明有效()。
当你为数组p和q设置初始值时,系统自动添加字符串分隔符,因此输出长度为3。
由于数组p中没有字符串分隔符,因此无法确定长度,但字符串的长度由于没有字符串分隔符,数组q中的长度为3矩阵q中的长度无法确定,但矩阵p中的字符串长度为3。
由于数组p和q中都没有字符串分隔符,因此长度~A~~~8无法确定是否需要读取来自键盘的包含空格字符的字符串,必须使用函数()。
getc()gets()getchar()scanf()~B~~~8当要求用户输入字符串时包含空格,使用的输入函数是()。
scanf()getchar()gets()getc()~C~~~8当有定义语句:chars[10];时,如果要从终端向s输入5个字符,错误的输入语句是()。
get(&s[0]);scanf("%s",s+1);gets(s);scanf("%s",s[1]);~D~~~8以下描述错误时是的()。
get函数用于从终端读取字符串。
getchar函数用于从磁盘文件中读取字符。
fputs函数用于将字符串以二进制形式输出到文件中,下列对字符串的正确描述是()。
C语言中有字符串类型的常量和变量,只有当两个字符串的字符数相同时才能比较字符串大小。
可以使用关系运算符来比较字符串的大小。
以空格开头的字符串Small~D~~~8可以正确执行以下字符串映射()。
chars[5]={"ABCDE"};chars[5]={'A','B','C','D','E'};char*s;s="ABCDE";char*s;printf("%s",s);~C~~~8字符串“\\”ABCDEF\“\\”的长度为()。
151078~B~~~8下列语句中,能正确进行字符串赋值运算的是()。
chars[5]={'a','b','c','d','e'};char*s;gets(s);char*s;*s="ABCDEF";chars[5]];scanf("%s",&s);~B~~~8假设预编译命令#include已经执行完毕,下一个程序段的输出结果为()。
chars[]="abcdefg";printf("%d\n",strlen(s));78910~A~~~8如果包含头文件并且定义了chars1[18],s2={“ABCDE”}和inti,现在我们要将字符串“ABCDE”设置为s1。
下列说法错误的是()。
strcpy(s1,s2);strcpy(s1,"ABCDE");s1="ABCDE";for(i=0;i<6 i++)s1[i]=s2[i];~C###~~~7*或更少序列输出结果为[>]。
*#include*main()*{*inta[5]={2,4,6,8,10},*p;*p=a;p++;*printf("%d",*p);*}~~7*下面程序的输出结果是[<35>]。
*#include*voidswap(int*a,int*b)*{*int*t;*t=a;a=b;b=t;*}*main()*{*inti=3,j=5,*p=&i,*q=&j;*swap(p,q);printf("%d%d",*p,*q);*}~~7*下面是运行结果程序段为[<68>]。
*charstr[]="ABCD",*p=str;*printf("%d\n",*(p+3));###~~7假设定义了floatx,则以下语句对有效定义指示变量p并赋予初始值()。
float*p=1024;int*p=(float)x;floatp=&x;float*p=&x;~D~~~7包含定义语句int(*f)(int);,那么下面的描述是真是()。
f是基类型int的指针变量。
f是一个指向函数的指针变量。
函数的形式为intf类型,它是一个指针变量,指向f类型的一维数组函数函数的返回值是类型地址~B~~~7被定义为int类型:intn1=0,n2,*p=&n2,*q=&n1;,下面的赋值语句等价于语句n2=n1is()。
*p=*qp=q*p=&n1;p=*q~A~~~7在16位汇编系统中,如果inta[]={10,20,30},*p=&a;执行p++时,下列说法不正确的是;p向高地址移动一个字节p向高地址移动一卷p向高地址移动两个字节p相当于n+1~A~~~7如果有定义语句:intk[2][3],*pk[3];下列说法正确的是()。
pk=k;pk[0]=&k[1][2];pk=k[0];pk[1]=k;~B~~~7如果定义:char(*p)[6];idp().它是一个指向字符变量的指针,它是一个指针数组的名称,它指向一个包含6个字符元素的一维数组。
下一个程序段是()。
#includevoidmain(){charstr[]="abc",*p=str;printf("%d\n",*(p+3));}670字符标题字符'C''C'~B~~~7如果有下面的定义,则对数组元素的正确引用是()。
inta[5],*p=a;*&a[5]*a+1*(p+5)*(a+2)~D###~~3C语言使用[]来表达逻辑“true”,使用[<0>]表示布尔值“false”。
~~~3C中逻辑运算符[<!>]的优先级高于算术运算符。
~~~3当a=1,b=2,c=3时,执行下面的if语句后,a,b,c的值为[<3>],[<2>],[<2>分别]。
if(a>c)b=a;a=c;c=b;~~~3以下程序段的输出结果为[<无限循环>]intk,n,m;n=10;m=1;k=1;while(k<=n)m*=2;printf("%d\n",m);~~3下面程序的输出结果为[<-1>]main(){intx=2;while(x--);printf("%d\n",x);}~~~3以下程序段:s=1.0;for(k=1;k<=n;k++)s=s+1.0/(k*(k+1))printf("%f\n",s);请填空,使下列程序段的功能完全相同。
s=0.0[]k=0;do{s=s+d;[]d=1.0/(k*(k+1));}while[]printf("%f\n",s);~~~3下面程序的功能是:从键盘输入几个学生的成绩,计算最高分和最低分并输出,当输入负数。
请填空。
main(){floatx,amax,amin;scanf("%f",&x);amax=x;amin=x;while[=0>]{if(x>amax)amax=x;if[]amin=x;scanf("%f",&x);}printf("\namax=%f\namin=%f\n",amax,amin);}~~~5ifinta[3][5];被定义,数组中的第9个有序元素是[]~~~5strlen("Howareyou\n")是[<中的字符串12>]~~~5C结束标志为[<'\0'>]~~~5写入一个一维、单精度实数数组s,长度为6,所有元素初始值为0。
数组的定义语句是[]~~~5strcmp("how","How")是[<32>0>]~~起始6C语言程序实现是[]~~~6C程序中的函数由两部分组成:[<声明部分>]和[<执行部分>]~~~6为了保证被调用的函数不返回任何值,其函数定义类型必须是[<无效>]~~~6下面的函数pi就是根据下面的公式返回满足精度要求ε的∏值。
请填空。
∏/2=1+1/3+(1/3)*(2/5)+(1/3)*(2/5)*(3/7)+(1/3)*(2/5)))*(3/7)*(4/9)+...doublepi(doubleps){doubles=0.0,t=1.0;intn;for([];t>eps;n++){s+=t;t=n*t/(2*n+1);}return(2.0*[]);}~~~6以下函数用于求x的y次方。
请填空。
doublefun(doublex,inty){inti;doublez;for(i=1;i[<<=y>];i++)z=[];returnz;}~~6函数下面的程序是计算s=0!+1!+2!+3!+...+n!。
请填空。
longf(intn){inti;longs;s=[<1L>];for(i=1;i<=n;i++)s=[];返回;}main(){longs;intk,n;扫描("%d"&n);s=[<0>];for(k=0;k<=n;k++)s=s+[];printf("%ld\n",s);}###~~3下列运算符中优先级最高的运算符是()。
!%-=&&~A~~~3下列运算符中优先级最低的是()。
||!=<=+~A~~~3表示x≥y≥z的关系,使用的C语言表达式是()。
(x>=y)&&(y>=z)(x>=y)AND(y>=z)(x>=y>=z)(x>=y)&(y>=z)~A~~~3假设a、b、c都是int类型的变量,a=3,b=4,c=5,那么下面的表达式中,值为0的表达式就是()。
a&&ba<=ba||b+c&&b-c!(a1234~D~~~5数组的正确描述是()。
一旦选择,数组的大小就被指定,但数组元素的类型可以变化。
一旦定义,数组的大小就定义好了,但是数组元素类型必须相同。
数组是可变的,但是数组元素类型可以不同。
一定是一样的~B~~~5字符串“Boy”完整的映射过程为chars[3]={'B','o','y'}chars[]="Boy"chars[3]={"Boy"}chars[3];s="Boy"~B~~~5在C中引用数组元素时,数组下标类型允许为()常整数整数表达式常整数或表达式整数或任意类型的表达式~C~~5下面语句的正确理解是()*inta[10]={6,7,8,9,10}将a[1]的五个初始值赋给a[5]序列中并赋予五个初始值[1]至[5]。
依次将值赋给[0]到[4],并依次赋给A[6]的五个初始值。
到[10],由于数组的长度和初始值的个数不同,所以这个说法是不正确的~B~~~5下面的程序段用()*main()*为数组的所有元素插入数据{*inta[10],i=0;*while(i<10 a+(i++)&a(i+1)a+i&a[++i]~D~~~5下面的程序结果输出为()*main()*{*inta[]={2,4,6,8},y x,*p;*p=&a[1];*for(x x<3;x++)y+=*(p+x);*printf(>仅当实参与形参同名时,实参与其对应的形参共同占用一个内存单元,形参占用相同的内存单元并且是虚拟的,不占用内存单元~A~~~6使用时数组名作为函数的实参,传递给形参的是array()的首地址、数组的第一个元素、数组中所有元素的元素个数,~A~复合表达式范围内的~~6指定的变量是()整个源文件、整个函数、程序定义的复合语句~D~~~6函数的返回值由()返回语句中的表达式决定调用的类型function系统默认类型所请求函数的类型~D~~~6以下语句均为true()C程序总是从第一个定义的函数开始执行。
在C编程中,C程序应该始终从main函数开始执行。
C程序总是从main函数开始执行。
main函数应该放在程序的开头~C~~~6下列函数的类型为()*fff(floatx)*{*printf("",x*x);*},即与参数x类型相同从Empty类型无法判断int类型~C~~6下面程序的输出结果为()*fun(inta,intb)*{intc;*c=a+b;*retutnc;*}*main()*{intx=6,y=7,z=8,r;*r=func((x--,y++,x+y),z--);*printf("%d\n",r);*}11202131~C~~~10描述结构体变量时,系统分配给它的内存为总计的总和各成员所需内存结构体第一个成员所需内存量占用内存最大的成员所需内存容量结构体最后一个成员所需内存量~A~~~10包含以下描述语句:*structstu*{inta;*floatb;*}stutype。
;*以下描述不正确的是strut()是结构体类型的关键字strutstu是用户自定义结构体类型Stutype是用户自定义结构体类型的名称a、b都是结构体成员的名称~C~~10C结构类型变量语言约束execute()所有成员始终位于内存中。
记忆中只有一名成员。
内存中不存在任何成员。
~A~~~11如果你只想读取文本文件,打开方法is()"r""W""a""r+"~A~~~11如果你想打开abc.dat文件在C盘的文件夹中,那么fopen函数中的第一个参数应该是c:file\abc.datc:\file\abc.dat"c:\file\abc.dat()"c:\\file\\abc.dat"~D~~~11使用fopen函数打开文件。
操作完成后,使用()函数关闭fopenopenfclosure~C~~~11以下可以作为fopen函数第一个参数的正确格式为c:user\test.txtc:\user\test.txt"c:\user\test().txt""c:\\user\\test.txt"~D~~~11如果执行fopen函数期间发生错误。
函数的返回值为()地址值01EOF~B~~~11。
如果要使用fopen函数打开一个新的二进制文件,该文件必须可读可写,因此文件模式字符串必须为“ab++”wb+“rb+”ab”()()如果打开现有文件在“ab”模式a+”下,以下描述为真:()打开文件时,不删除原文件内容,并将位置指针移动到文件末尾当打开文件进行add和读取操作,原文件内容并没有被删除,位置光标移动到文件开头,打开文件时可以进行重写和读取操作,原文件内容并没有被删除,以上说法均不成立~A###~~9以下是程序功能:将数据输入r后计算半径为r的圆的面积。
编译程序时发生错误。
main(){intr;floats;scanf("%d",&r);s=pi*r*r;printf("s=%f\n",s);}错误是由()引起的。
评论声明写错地方了。
存储圆半径的变量r不应声明为整数。
输出语句中的格式描述代码不合法​​。
赋值语句中使用了非法变量CircleArea~D~~~9下列描述中错误的是()。
程序中,任何以“#”开头的语句行都是预处理命令行,不能以分号结尾。
#defineMAX是宏定义的合法命令行。
C程序在程序执行过程中处理~C~~9中的预处理命令行,下列哪项语句为真()。
预处理命令行必须位于源文件的开头。
源文件的一行上可以有多个预处理命令。
宏名称必须为大写字母。
宏替换不占用程序运行空间~D~~~9如果程序行中有宏定义:#defineN100,则下列描述中正确的是()。
宏定义中将标识符N的值定义为整数100。
当编译器预处理C源程序时,标识符N被替换为100。
编译C源程序时,标识符N被替换为100。
当C源程序被编译时,标识符N被替换为100。
编译源程序,将标识符N替换为100。
代码N~B~~~9程序的输出结果#include#defineM5#defineNM+Mmain(){intk;k=N*N*5;printf("%d\n",k);}是()。
100505545~C~~~9下列说法正确的是()。
预处理命令行必须位于C源程序的开头,并且预处理命令行以#开头。
每个C程序开头都必须包含一个预处理命令行:#includeC语言预处理命令行无法进行宏定义和条件编译的处理函数~B~~~9C语言汇编系统处理宏命令在()。
系统编译源程序前,与其他数据同时执行,程序运行时执行,错误为()。
所有预处理命令行必须以“#”开头且不能以分号结尾。
程序中所有以“#”开头的数据行都是预处理命令行,C程序在执行过程中处理预处理命令在程序~C~~~9的任何地方,下列正确的描述是()。
C语言中的预处理是指完成指定文件的宏替换和插入。
预处理命令只能放在C源程序文件的开头预处理命令可以放在程序的任何地方预处理命令结束~C~~~9下列关于宏替换的说法不正确的是()。
宏定义只能使用宏定义来嵌套。
宏名称必须以大写字母表示。
热门文章
1
Java与JavaScript:基础入门... javas是什么?Java是一种面向对象的编程语言,可用于编写跨平台的应用软件。...

2
Java操作文本值:提取与求和技巧详解 java怎么把文本框的数字读出来想加求和获取Java文本中的值并执行操作有两种方...

3
手机QQ浏览器助力安卓用户:JavaSc... 请问,哪种浏览器支持JavaScript?——本人使用安卓手机。他们都受到支持。...

4
用Java或C语言轻松解决经典数学问题:... 我想求救100元买100鸡的问题用java程序编写或c程序编写各位大虾有知道的帮...

5
C语言实现阶乘累加和:从函数定义到代码示... 用C语言求1到N的阶层的累加和思路:首先定义一个函数计算一个数的阶乘,然后从1到...

6
Python教程:高效判断素数的实现方法 用python判断素数1.根据素数的定义,只要一个数除了1和它本身之外没有其他约...

7
Python教程:如何验证输入字符串是否... python中如何判断输入的字符串为实数,谢谢!尝试:x=float(input...

8
C语言实现400位高精度计算器:思路解析... 用C语言做一个可进行加减乘除的400位计算器?(求思路)这个可以用个位数全加器的...

9
C语言数组定义与赋值详解:char与in... c语言数组定义和赋值是什么?C语言数组定义为:charc[6]={'c','h'...

10
C语言期末复习攻略:基础知识点+经典例题... c语言怎么学考试基础知识笔记经典例题题库指针大一期末考试题入门二级怎么学代码烟花...