c语言值传递和地址传递

c语言值传递和地址传递
c语言值传递和地址传递

C语言地址传递和值传递简析

本文写作初衷是为了解决C语言初学者关于地址传递和值传递一直理解得不太好的问题。也是对这部分课程内容的一个总结。文档作者:

和薇论坛用户:hewei

北京工业大学实验学院理工学科部

计算机基础,C语言,C++语言,数据结构教师

不少同学在学到C语言的指针部分时感到很困惑,对经常提到的“值传递”和“地址传递”两个概念弄不明白。实际上,因为地址本身也可以作为一个特殊的“值”,所以地址传递也是一种特殊的值传递。只是为了强调其特殊性,故称之为“地址传递”。我们在学习过程中可以视参数的形式而区别对待,比如若参数传递的是简单数据类型的数值,则将其归类为值传递方式;若参数传递的是变量的地址,则视其为地址传递方式。

值传递过程中,被调函数的形参作为被调函数的局部变量处理,即在内存的堆栈中开辟空间以存放由主调函数放进来的实参的值,从而成为了实参的一个拷贝。值传递的特点是被调函数对形参的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值。

而在地址传递过程中,被调函数的形参虽然也作为局部变量在堆栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址,即通过堆栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量。

下面我们用书上出现频率最高的一个程序来分别实现值传递过程和地址传递过程。

void swap(int x,int y) { int temp; temp=x; x=y; y=temp;

printf("\n(swap):%d,%d\n",x,y); }

void main() { int a,b;

scanf("%d,%d",&a,&b); if(a

printf("\n(main):%d,%d\n",a,b); }

这显然是一个值传递的过程。假设我们从键盘输入两个数据:5,9,先来看一下运行结果:(swap):9,5 (main):5,9

按照值传递的特点,我们可以很清楚的看到,虽然在swap函数中暂时使得运行结果显示了交换后的数据,即达到了交换的目的,但实际情况却是随着swap函数的结束,被作为局部参数的形参x,y以及swap函数本身的局部参数temp都将结束其生存期,在内存中的存储空间被释放。因此实参a,b的并未受到影响,依然保持原值。

从这道程序中我们也可以学到一个方法,比如有时不需要修改实参,但是又需要被调函数所作的工作能够得以体现,就可以灵活的在被调函数中使用打印语句。因此上面的程序可以改写为:

void swap(int x,int y) { int temp; temp=x; x=y; y=temp;

printf("\n从大到小排列的顺序为:%d,%d\n",x,y); } main() { int a,b;

scanf("%d,%d",&a,&b); if(a

在输入5,9两个数字后,得到的执行结果是:从大到小排列的顺序为:9,5

你看这样就可以使用相对容易理解的值传递方式,巧妙的解决问题了,并得到了想要的答案,虽然我们并未真正的让主函数中的两个变量发生改变。再来看地址传递方式:

void swap(int *p,int *q) { int temp; temp=*p; *p=*q; *q=temp; }

void main() { int a,b;

int *pointer_1=&a,*pointer_2=&b; scanf("%d,%d",&a,&b); if(a

假设我们从键盘输入两个数据:5,9,先来看一下运行结果:

9,5

在这个程序中用指针变量作参数,虽然传送的是变量的地址,但实参和形参之间的数据传递依然是单向的“值传递”,即调用函数不可能改变实参指针变量的值。但它不同于一般值传递的是,它可以通过指针间接访问的特点来改变指针变量所指变量的值,即最终达到了改变实参的目的。

这一部分内容对初学者来说理解起来有一定的难度,所以在学习过程中一定要多想多练多思考,希望以上的讲解能对初学者有所帮助。

C语言与汇编语言互相调用

浅谈C程序中调用汇编模块的方法 C语言是目前非常流行的一种编程语言,除具有高级语言使用方便灵活、数据处理能力强、编程简单等优点外,还可实现汇编语言的大部分功能,如可直接对硬件进行操作、生成的目标代码质量较高且执行的速度较快等。所以在工程上对硬件处理速度要求不很高的情况下,基本可以用C代替汇编语言,编写接口电路的控制软件。但C也不能完全取代汇编语言,如在一些对速度要求很高的实时控制系统中,以及对硬件的特殊控制方面,C有时也不能完全很好胜任,还需要汇编语言来编写。因为汇编语言目标代码更精练,对硬件直接控制能力更强和执行速度更快,但汇编语言编程烦难、表达能力差也显而易见。比较好的解决办法是C与汇编语言混合编程,即用C编写软件的调度程序、用户界面以及速度要求不高的控制部分,而用汇编语言对速度敏感部分提供最高速度的处理模块,供C调用。这种方法提供了最佳的软件设计方案,做到了兼顾速度效率高和灵活方便。由于本人的毕业设计需要C 程序中调用汇编模块的方法来提高ARM定点指令的执行速度,故对这方面进行了学习。学习心得如下: 对于C和汇编语言的接口主要有两个问题需要解决。 一、调用者与被调用者的参数传递 这种数据传递通过堆栈完成,在执行调用时从调用程序参数表中的最后一个参数开始,自动依次压入堆栈;将所有参数压入堆栈后,再自动将被调用程序执行结束后的返回地址(断点)压入堆栈,以使被调程序结束后能返回主调程序的正确位置而继续执行。例如一调用名为add汇编程序模块的主函数:main( ){...... add(dest,op1,op2,flages);......}。在此例中对主函数进行反汇编,主函数在调用add函数前自动组织的堆栈。 . . . lea 0xfffffffe8(%ebp),%eax #flages数组的首地址入栈 push %eax pushl 0xfffffff8(%ebp) #OP2入栈 pushl 0xfffffffc(%ebp) #OP1 入栈 pushl 0xfffffff0(%ebp) #dest地址入栈 call 0x80483f0 #调用add函数 . . 执行完add调用语句后,栈内数据结果如图一所示。 进入汇编子程序后,为了能正确获取主调程序并存入堆栈中的数据,被调的汇编子程序先后要做如下一些工作: 1、保存esp的副本 进入汇编子程序后,子程序中免不了要有压栈和出栈的操作,故ESP时刻在变化。为了能用ESP访问堆栈中的参数,安全办法是一进入子程序后,先为ESP制副本,以后对传递参数的访问都用副本进行。一般可用EBP保存ESP,如: push %ebp mov %ebp,%esp

C语言输入输出函数printf与scanf的用法格式

C 语言输入输出函数printf 与scanf 的用法格式 printf()函数用来向标准输出设备(屏幕)写数据; scanf() 函数用来从标准输入设备(键盘)上读数据。下面详细介绍这两个函数的用法。 一、printf()函数 printf()函数是格式化输出函数, 一般用于向标准输出设备按规定格式输出信息。在编写程序时经常会用到此函数。printf()函数的调用格式为: printf("<格式化字符串>", <参量表>); 其中格式化字符串包括两部分内容: 一部分是正常字符, 这些字符将按原样输出; 另一部分是格式控制字符, 以"%"开始, 后跟一个或几个控制字符,用来确定输出内容格式。 参量表是需要输出的一系列参数,可以是常量、变量或表达式,其个数必须与格式化字符串所说明的输出参数个数一样多, 各参数之间用","分开, 且顺序一一对应, 否则将会出现意想不到的错误。 例如: printf("a=%d b=%d",a,b); 1. 格式控制符Turbo C 2.0提供的格式化规定符如下: 格式控制字符 参量表 正常字符

━━━━━━━━━━━━━━━━━━━━━━━━━━ 符号作用 ────────────────────────── %d 十进制有符号整数 %u 十进制无符号整数 %f 浮点数 %s 字符串 %c 单个字符 %p 指针的值 %e,%E 指数形式的浮点数 %x, %X 无符号以十六进制表示的整数 %o 无符号以八进制表示的整数 %g,%G 自动选择合适的表示法 ━━━━━━━━━━━━━━━━━━━━━━━━━━ printf的附加格式说明字符 字符说明 l 用于长整型数或双精度实型,可加在格式 符d、o、x、u和f前面 m(代表一个正整数据最小输出显示宽度

C语言选择题(三)

第七、八、九章选择题 1.C语言中的函数[1] [1] A.嵌套定义和嵌套调用均可 B.可以嵌套定义但不可以嵌套调用 C.嵌套调用和递归调用均可 D.可以嵌套调用但不可以递归调用 2.C语言中函数返回值的类型是由[2]决定的 [2] A. return语句中的表达式类型 B.调用函数时临时指定 C.定义函数时所指定的函数类型 D.对被调用函数声明时指定 3.下列调用函数的说法中不正确的是[3] [3] A.主调函数和被调函数可以不在同一文件中 B.实际参数和形式参数可以同名 C.若用值传递方式,则形式参数不予分配内存 D.函数间传递数据可使用全局变量 E.函数调用时,若形、实参数均为数组名,则其传递方式是地址传递方式 4.若用数组名作为函数调用时的实参,则实际上传递给形参的是[4] [4] A.数组中全部元素的值 B.数组的第一个元素的值 C.数组的首地址 D.数组元素的个数 5.void作为函数的参数时,表示[5] [5] A.该函数无返回值 B.实参可为任意值 C.函数无参数 D.该函数可返回任意值 6.下面对typedef 不正确的叙述是[6] [6] A.用typedef 可以定义各种类型名,但不能定义变量 B.使用typedef 有利于程序的通用和移植 C.用typedef可以增加新类型 D.用typedef 只是将已存在的类型用一个新的标识符表示 7.使用共用体union的目的是[7] [7] A.将一组相同数据类型的数据作为一个整体,以便程序中使用 B.将一组相同数据类型的数据作为一个整体,以便其中的成员共享同一存储空间 C.以便其中的成员共享同一存储空间 D.将一组相关数据作为一个整体,以便程序中使用 8.下列数据类型中不属于构造类型的是[8] [8]A.数组型 B.结构型 C.枚举型 D.共用型 9.在C语言中,[9]类型变量的所有成员以覆盖方式共享存储单元 [9]A.数组型 B.结构型 C.共用型 D.枚举型 10.若程序中含有定义: struct abc { int x;int y;} struct abc s1,s2;则[10] [10] A.能编译、链接、运行 B.能编译、链接,但不能运行 C.编译时出错 D.能编译、但链接出错 11.C语言中,对于存储类型为[11]的变量,只有在使用它们时才占用存储单元 [11] A. static 和auto B.register 和 extern

C语言复习题85424

一、填空: 1.整型数据变量声明中所使用的关键字是 int 。 2.设float x=2.5,y=4.7; int a=7;,表达式x+a%3*(int)(x+y)%2/4的值为 2.5 。 3.printf(“My age is %d.”, age); 函数中,使用%d表示输出的是整型类型的数 据。 4.每个源程序有且只有一个主函数,系统总是从该函数开始执行C语言程序。 5.设int x=5,y,z;执行y=z=x;x=y==z;后,变量x的结果是 1 。 6. C 语言中,数组在内存中占一片的存储区,由代表它的首地址。数 组名是一个,不能对它进行赋值运算。 7.函数的参数为char *类型时,形参与实参结合的传递方式为。 8.C程序编译、连接后生成程序。 9.当a=10,b=4,c=2时,表达式f=a>b>c的值是。 10.字符串数组与字符数组的在长度至少一个元素。 11.若函数的形式参数是指针类型,则实参可以是或。 12.如定义语句为char a[ ]= "windows",b[ ]= "7";,语句printf("%s",strcat(a,b));的输出结果 为。 13.请在下面的程序段中填写正确的格式说明符: int main(void) { float salary; printf(“Enter your desired monthly salary:.”, salary); } 14.C程序编译后生成程序。 15. C 语言的标识符只能由、数字和三种字符组成。 16.设有定义int y; ,分别写出描述“y是偶数”的表达式,“y是奇 数”的表达式。 17.C语言没有字义专门的字符串变量类型,而是把它存储在数组中。 18.字符串常量"\\\22a,0\n\""的长度是。 19.字符串存储到数组中时,在数组的最后将增加一个标记字符串结束的字 符。 20.设有定义语句static int a[3][4] ={{1},{2},{3}}; 则a[1][0]值为,a[1][1] 值 为,a[2][1]的值为。 21.假设int a=7; 执行语句a+=a-=a*a; 后,a的值是。 22.若自定义函数要求返回一个值,则应在该函数体中有一条语句,若自定义 函数要求不返回一个值,则应在该函数说明时加一个类型说明符

C语言中参数的传值问题

C 语言中参数的传值问题 第1页 C 语言中参数的传值一直比较含糊,今天在网上看到三个面试题的详解,感觉讲的很好,就拿来记下,方便学习和记忆。 1. 考题一:程序代码如下: void Exchg1(int x, int y) { int tmp; tmp=x; x=y; y=tmp; printf(“x=%d,y=%d/n”,x,y) } void main() { int a=4,b=6; Exchg1 (a,b) ; printf(“a=%d,b=%d/n”,a,b) } 输出的结果: x=____, y=____ a=____, b=____ 问下划线的部分应是什么,请完成。 2. 考题二:代码如下。 Exchg2(int *px, int *py) { int tmp=*px; *px=*py; *py=tmp; print(“*px=%d,*py=%d/n”,*px,*py); } main() { int a=4; int b=6; Exchg2(&a,&b); Print(“a=%d,b=%d/n”, a, b); } 输出的结果为: *px=____, *py=____ a=____, b=____ 问下划线的部分应是什么,请完成。 3. 考题三: Exchg2(int &x, int &y) { int tmp=x; x=y; y=tmp; print(“x=%d,y=%d/n”,x,y); } main() { int a=4; int b=6; Exchg2(a,b); Print(“a=%d,b=%d/n”, a, b); } 输出的结果: x=____, y=____ a=____, b=____ 问下划线的部分输出的应是什么,请完成。 你不在机子上试,能作出来吗?你对你写出的答案有多大的把握? 正确的答案,想知道吗?(呵呵,让我慢慢地告诉你吧!) 好,废话少说,继续我们的探索之旅了。 我们都知道:C 语言中函数参数的传递有:值传递,地址传递,引用传递这三种形式。题一为值传递,题二为地址传递,题三为引用传递。不过,正是这几种参数传递的形式,曾把我给搞得晕头转向。我相信也有很多人与我有同感吧? 下面请让我逐个地谈谈这三种传递形式。 二、函数参数传递方式之一:值传递 1. 一个预备的常识 为了说明这个问题,我先给出一个代码: int a=4; int x; x=a; x=x+3; 看好了没,现在我问你:最终a 值是多少,x 值是多少? (怎么搞的,给我这个小儿科的问题。还不简单,不就是a==4 x==7嘛!) 在这个代码中,你要明白一个东西:虽然a 值赋给了x ,但是a 变量并不是x 变量哦。我们对x 任何的修改,都不会改变a 变量。呵呵!虽然简单,并且一看就理所当然,不过可是一个很重要的认识喔。

汇编语言的过程调用与c语言的函数调用

姓名:孙贵森 学号: 汇编语言地过程调用,如果需要传递参数,一般有种方法,通过寄存器来“传递”,或是通过参数来传递.(还有将所有参数制成参数列表并压栈地传递方法,但较少用.)通过寄存器来“传递”,不是真正意义上地传递,其只不过是事先在几个有限地寄存器中设置相应地值后,再调用过程,过程再直接读取这些寄存器地内容.可想而知,此法犹如语言中地全局变量,极易感染.而如果通过参数来传递,又不得不面临手工维护堆栈框架( )地重担.堆栈框架动态地存放着参数、调用过程地返回地址、过程局部变量、过程内地压栈等内容,也是不好对付地.一般情况下,一个普通地过程可能如下编写:文档来自于网络搜索 , ..... 作为遵从调用约定()调用者,则需这样调用上述过程: ; ; ; , * ; 而如果遵从调用约定,则: , ...... , [ ] ; , [ ]; ...... * ; , , ; ...... , [ ]; , [ ]; , [ ; , [ ]; ...... , ; * ;

在被调用地过程内,分为种情况: . 无参数,也无局部变量 . 有参数 . 有局部变量 当无参数且无局部变量时,堆栈中只是保存语句地下一条语句地地址,可以很安全地返回.而当有参数,使用伪指令地接收参数地形式,则会自动生成正确地返回代码.而当有局部变量,使用伪指令来定义局部变量,也会自动地生成正确地返回代码.在将参数压栈时,仍需将其打包为位地,文档来自于网络搜索 ; , ; ; 另一选择是,将用作地变量声明为. ; ; 还有另一种方法,即,总是传递指针. ; (, ) , ; , , , , , [] , , [] 这种方法在保留了我们可以声明仅需地变量类型地同时,也确保位地方法正确压栈.语言中地每一个函数都是一个独立地代码块.一个函数地代码块是隐藏于函数内部地,不能被任何其它函数中地任何语句(除调用它地语句之外)所访问(例如,用语句跳转到另一个函数内部是不可能地).构成一个函数体地代码对程序地其它部分来说是隐蔽地,它既不能影响程序其它部分,也不受其它部分地影响.换言之,由于两个函数有不同地作用域,定义在

c语言输入输出函数知识点总结

c语言输入输出函数知识点总结 1.I/O input output(输入端,输出端) 输入:从计算机向外部输出设备(显示器,打印机)输出数据。 输出:从输入设备(键盘、鼠标、扫描仪)向计算机输入数据。 2.C语言本身不提供输入输出语句,输入和输出操作是由C函数库中的函数实现的。 3.字符输出函数一般形式:putchar(a);a可以是字符型变量、整型变量、字符常量、整型常量。函数作用:向终端输出一个字符。 4.字符输入函数一般形式:a=getchar( );函数作用:从终端输入一个字符。函数值:从输入设备得到的字符。 5.格式输出字符 %d:以十进制输出整数;%o:以八进制形式输出整数;%c:以字符形式输出一个字符;%s:输出字符串;%f:以小数形式输出单、双精度数,隐含输出六位小数。 6.getchar一次只能输入一个字符,有几个getchar()就输入几个字符,多输入的计算机不能识别。 7.getchar()输入的时候,空格键、Enter键、Tab键不能乱用,他们都当成字符对待。 printf("%d,%c,%f,%o,%x,%s",a,b,c,d,e,f); .......................................... 8.格式控制都是小写字母; 9.格式控制与后面要输出的变量是一一对应;................................................... 10.printf("%md",a); 1).m是整数; 2).m是指输出的结果占m列宽度; 3).m是正整数的话,输出结果差几列左补几个空格; m是负整数的话,输出结果差几列右补几个空格; 4).如果m的绝对值小于原来数的宽度,则原样输出。................................................... 11.printf("%m.nf",a); 1).m是指输出占几列宽度,n是指输出结果小数点后保留几位有效数字; 2).m是正整数的话,输出结果差几列左补几个空格; m是负整数的话,输出结果差几列右补几个空格; 3).printf("%2.5f",a); m

C语言中的函数间数据传递

理论广角 C语言是一种结构化程序设计语言,而结构化程序设计的总体思想是采用模块化结构,自上而下,逐步求精。即首先把一个复杂的大问题分解为若干相对独立的小问题,如果小问题仍较复杂,则可以把这些小问题又继续分解成若干子问题这样不断地分解,使得小问题或子问题简单到能够直接用程序的三种基本结构表达为止。然后,对应每一个小问题或子问题编写出一个功能上相对独立的程序块来,这种像积木一样的程序块被称为模块。 而每个模块可以由实现不同功能的函数组成。C语言的函数有两种:一是库函数(标准函数,C语言程序自带),用户可以直接调用;另一类是自定义函数,由用户根据使用的目的自己设计。可以说,C语言的程序是由函数组成,而在函数之间存在相互调用及调用时数据的传递问题。 在 C 语言中,我们通过函数实现模块化程序设计思想,即用函数实现功能模块的定义,然后通过函数之间的调用来实现程序功能。因此,程序中的函数根据其在某个程序中的使用方式的不同分为主调函数和被调用函数。函数本身并没有这种区分。函数间也可互相调用。有参函数的参数是主调函数和被调用函数进行数据传递的主要方式。无参函数不需要数据传递。参数有形式参数和实在参数之分。在函数的定义和说明语句中,我们将函数名后面括号中的参数称为形式参数,简称“形参”;在函数的调用语句中函数名后面括号中用的参数称为实在参数,简称“实参”。当函数被调用时,主调函数通过实参要向被调用函数的形参传递数据;函数调用并完成一定的功能后,也要向主调函数返回一些数据。在函数调用中,被调用函数应在主调函数之前定义 或被声明,如是系统提供的库函数,一般应将放该函数头文件用#include包含到本文件中;如果是用户自己定义的函数,则该函数与调用它的函数在同一文件中。被调用函数的形参应确定数据类型;而在函数调用时,用被调用函数名和实参的形式调用,实参的数据类型与形参应一致,否则易出错。 根据作者的多年教学经验,函数间的数据传递是C语言初学者的难点之一。下面重点介绍函数间的数据传递方式。 一、值传递方式 当形参为变量而实参为变量、某个数组元素、常量或表达式时,在函数调用过程中数据传递通常使用的是值传递方式。既在程序执行中,系统会给形参和实参分别分配内存单元,在函数调用时,程序将实参的值传递给形参,存在系统分配的内存单元中,供被调用函数使用,形参和实参使用不同的内存单元;函数执行完毕,形参不将处理后的值返回给实参,实参的值不变,被调用函数最多只能通过ruturn语句返回一个值给主调函数,形参的内存单元被释放。在此程序中,通过把主调函数中被调用函数名后的实参(即变量的值)赋值给被调用函数的形参(变量),由被调用函数进行处理,从而实现主调函数与被调用函数间数据的传递。在这种数据传递方式中,函数最多只能返回一个值,这就有一定的局限性。 例1:采用值传递方式交换两个变量的数据并求和。 swap-sum (int x, int y) /*定义交换及求和函数*/{int temp; printf(“2.x=%d y=%d\n”, x, y );temp=x; x=y; y=temp; /*进行值的交换*/ printf(“3.x=%d y=%d\n”, x, y );return (x+y ); /*返回变量求和的值*/}main() /*主函数*/ {int a, b, sum;scanf (“1.a=%d, b=%d”, &a, &b );sum=swap-sum(a, b ); printf (“4.a=%d b=%d\n”, a, b );printf (“sum=%d\n”, sum);}运行结果为:1.a=9 b=132.x=9 y=133.x=13 y=94.a=9 b=13sum=22 从运行结果,在被调用函数中交换形参变量的值并不影响实参变量的值,从被调用函数中返回主调函数的值只能通过return语句。 二、地址传递方式 当函数调用时,被调用函数的形参和实参为指针变量或数组时,函数间的数据传递使用的是地址传递方式。既在程序的执行过程中,系统给实参分配存储空间;在函数调用时,将实参获得的存储空间的地址传递给形参,使形参指向同一存储空间,当形参指向存储空间的值参与被调用函数的处理,也就是实参指向存储空间的值被处理。被调用函数执行完毕返回主调函数时,由于形参和实参指向同一存储空间,形参指向的存储空间的值的变化也就是实参指向存储空间的值的变化。从而实现被调用函数返回多个值给主调函数。如形参和实参使用的是数组时,传递的是数组首元素的地址。应注意,在函数中被处理的是形参指向的存储空间中存储的值,而不是存储空 C 语言中的函数间数据传递 [摘 要]C语言是结构化程序设计语言,其程序是由模块组成,而模块由完成不同功能的函数组成,函数 间存在相互调用和数据传递问题。数据传递分为值传递方式、地址传递方式、全局变量传递方式,每种方式传递的内容、要求不同,各有其应用的优点和局限性。 [关键词]函数 数据传递 值传递方式 地址传递方式 全局变量 学术要论

C语言输入输出函数格式详解

1、输入和输出: 输入:输入也叫读,数据由内核流向用户程序 输出:输出也称写、打印,数据由用户程序流向内核 以下介绍一些输入输出函数,尽管都是一些有缺陷的函数,但比较适合初学者使用 2、printf用法(其缺陷在于带缓存) printf输出时必须加上\n(刷新缓存) 解释:第一幅图没有加'\n',不会刷新缓存区,则不会打印出来;第二幅图是因为主函数结束时刷新了缓存区,但由于没有换行符,所以没有换行便显示了后面的内容;第三幅图时正常打印。 变量定义的是什么类型,在printf打印时就需要选择什么格式符,否则会造成数据的精度丢失(隐式强转),甚至会出现错误

修饰符功能 m输出数据域宽,数据长度

C语言函数调用三种方式 传值调用,引用调用和传地址调

C语言函数调用三种方式传值调用,引用调用和传地址调 我想,你只要看了C语言上关于传值函数调用的测试题,一切都会了然于胸:1. 考题一:程序代码如下: void Exchg1(int x, int y) { int tmp; tmp=x; x=y; y=tmp; printf(“x=%d,y=%d\n”,x,y) } void main() { int a=4,b=6; Exchg1 (a,b) ; printf(“a=%d,b=%d\n”,a,b) } 输出的结果: x=____, y=____ a=____, b=____ 问下划线的部分应是什么,请完成。 2. 考题二:代码如下。 Exchg2(int *px, int *py) { int tmp=*px; *px=*py; *py=tmp; print(“*px=%d,*py=%d\n”,*px,*py); } main()

{ int a=4; int b=6; Exchg2(&a,&b); Print(“a=%d,b=%d\n”, a, b); } 输出的结果为: *px=____, *py=____ a=____, b=____ 问下划线的部分应是什么,请完成。 3. 考题三: Exchg2(int &x, int &y) { int tmp=x; x=y; y=tmp; print(“x=%d,y=%d\n”,x,y); } main() { int a=4; int b=6; Exchg2(a,b); Print(“a=%d,b=%d\n”, a, b); } 二.函数参数传递方式之一:值传递 1.值传递的一个错误认识 先看题一中Exchg1函数的定义: void Exchg1(int x, int y) //定义中的x,y变量被称为Exchg1函数的形式参数{

C语言字符串的输入和输出

C语言字符串的输入和输出 字符串的输入和输出 %c人为加入\0进行输入输出 %s直接输入输出 *输入输出字符串时字符数组应有足够的存储空间,指针变量作为输入项时,指针必须已经指向确切的、足够大的存储空间 %s的使用 scanf("%s",地址值) 地址值:字符数组名、字符指针、字符数组元素的地址 例:char str[15]; scanf("%s",str); abc123 1.不读入空格和回车,从空格处结束 2.输入字符串长度超过字符数组元素个数,不报错 3.当输入项为字符指针时,指针必须已指向确定的有足够空间的连续 存储单元 4.当为数组元素地址时,从此元素地址开始存放 2.printf("%s",地址值) 输出时遇到第一个'\0'为止 3.gets和puts函数 开头必须stdio.h #include"stdio.h"

1.gets(地址值) 地址值:字符数组名、字符指针、字符数组元素的地址 4.当为数组元素地址时,从此元素地址开始存放 5.printf("%s",地址值) 输出时遇到第一个'\0'为止 6.gets和puts函数 开头必须stdio.h #include"stdio.h" 1.gets(地址值) 地址值:字符数组名、字符指针、字符数组元素的地址 7.例: char str[10]; gets(str); 包括空格符 8. 2.puts(字符串起始地址) 遇第一个'\0'结束,自动加入换行符 9.字符串数组:数组中每个元素都是一个存放字符串的数组 可以将一个二维数组看作是字符串数组 10.char ca[3][5]={"A","BB","CCC"}; A\0 B B\0 C C C\0 字符型指针数组 char*pa[3]={"a","bb","ccc"}; pa[0]pa[1]pa[2] 可以重新赋值gets(pa[2]);

C语言函数参数传递(非常重要)

一、三道考题 开讲之前,我先请你做三道题目。(嘿嘿,得先把你的头脑搞昏才行……唉呀,谁扔我鸡蛋?) 考题一,程序代码如下: void Exchg1(int x, int y) { int tmp; tmp = x; x = y; y = tmp; printf("x = %d, y = %d\n", x, y); } main() { int a = 4,b = 6; Exchg1(a, b); printf("a = %d, b = %d\n", a, b); return(0); } 输出的结果为: x = ____, y=____. a = ____, b=____. 问下划线的部分应是什么,请完成。 考题二,程序代码如下: void Exchg2(int *px, int *py) { int tmp = *px; *px = *py; *py = tmp; printf("*px = %d, *py = %d.\n", *px, *py); } main() { int a = 4; int b = 6; Exchg2(&a, &b); printf("a = %d, b = %d.\n", a, b); return(0); } 输出的结果为为: *px=____, *py=____.

a=____, b=____. 问下划线的部分应是什么,请完成。 考题三,程序代码如下: void Exchg3(int &x, int &y) { int tmp = x; x = y; y = tmp; printf("x = %d,y = %d\n", x, y); } main() { int a = 4; int b = 6; Exchg3(a, b); printf("a = %d, b = %d\n", a, b); return(0); } 输出的结果为: x=____, y=____. a=____, b=____. 问下划线的部分应是什么,请完成。你不在机子上试,能作出来吗?你对你写出的答案有多大的把握?正确的答案,想知道吗?(呵呵,让我慢慢地告诉你吧!) 好,废话少说,继续我们的探索之旅了。 我们都知道:C语言中函数参数的传递有:值传递、地址传递、引用传递这三种形式。题一为值传递,题二为地址传递,题三为引用传递。不过,正是这几种参数传递的形式,曾把我给搞得晕头转向。我相信也有很多人与我有同感吧? 下面请让我逐个地谈谈这三种传递形式。 二、函数参数传递方式之一:值传递 (1)值传递的一个错误认识 先看考题一中Exchg1函数的定义: void Exchg1(int x, int y) /* 定义中的x,y变量被称为Exchg1函数的形式参数*/ { int tmp; tmp = x; x = y; y = tmp; printf("x = %d, y = %d.\n", x, y); }

C语言常考的知识点

C语言常考的知识点: 总体上必须清楚的: 1)程序结构是三种:顺序结构 , 循环结构(三个循环结构), 选择结构(if 和switch) 2)读程序都要从main()入口, 然后从最上面顺序往下读(碰到循环做循环,碰到选择做选择)。 3)计算机的数据在电脑中保存是以二进制的形式. 数据存放的位置就是他的地址. 4)bit是位是指为0 或者1。 byte 是指字节, 一个字节 = 八个位. 5)一定要记住二进制如何划成十进制。 概念常考到的: 1、编译预处理不是C语言的一部分,不再运行时间。C语言编译的程序称为源程序,它以ASCII数值存放在文本文件中。 2、每个C语言程序中main函数是有且只有一个。 3、在函数中不可以再定义函数。 4、算法的是一定要有输出的,他可以没有输入。 5、break可用于循环结构和switch语句。 6、逗号运算符的级别最低。 第一章 1)合法的用户标识符考查: 合法的要求是由字母,数字,下划线组成。有其它元素就错了。

并且第一个必须为字母或则是下划线。第一个为数字就错了。 关键字不可以作为用户标识符号。main define scanf printf都不是关键字。迷惑你的地方If是可以做为用户标识符。因为If中的第一个字母大写了,所以不是关键字。 2)实型数据的合法形式: 2.333e-1 就是合法的,且数据是2.333×10-1。 考试口诀:e前e后必有数,e后必为整数。. 3)字符数据的合法形式:: '1' 是字符占一个字节,"1"是字符串占两个字节(含有一个结束符号)。 '0' 的ASCII数值表示为48,'a' 的ASCII数值是97,'A'的ASCII数值是65。 4) 整型一般是两个字节, 字符型是一个字节,双精度一般是4个字节: 考试时候一般会说,在16位编译系统,或者是32位系统。碰到这种情况,不要去管,一样做题。掌握整型一般是两个字节, 字符型是一个字节,双精度一般是4个字节就可以了。 5)转义字符的考查: 在程序中 int a = 0x6d,是把一个十六进制的数给变量a 注意这里的0x必须存在。 在程序中 int a = 06d, 是一个八进制的形式。 在转义字符中,’\x6d’ 才是合法的,0不能写,并且x是小写。 ‘\141’ 是合法的, 0是不能写的。 ‘\108’是非法的,因为不可以出现8。 6)算术运算符号的优先级别: 同级别的有的是从左到右,有的是从右到左。 7)强制类型转换: 一定是(int)a不是 int(a),注意类型上一定有括号的。 注意(int)(a+b)和(int)a+b 的区别。前是把a+b转型,后是把a转型再加b。

汇编语言编程规范

软件设计更多地是一种工程,而不是一种个人艺术。如果不统一编程规范,最终写出的程序,其可读性将较差,这不仅给代码的理解带来障碍,增加维护阶段的工作量,同时不规范的代码隐含错误的可能性也比较大。 分析表明,编码阶段产生的错误当中,语法错误大概占20%左右,而由于未严格检查软件逻辑导致的错误、函数(模块)之间接口错误及由于代码可理解度低导致优化维护阶段对代码的错误修改引起的错误则占了一半以上。 可见,提高软件质量必须降低编码阶段的错误率。如何有效降低编码阶段的错误呢?这需要制定详细的软件编程规范,并培训每一位程序员,最终的结果可以把编码阶段的错误降至10%左右,同时也降低了程序的测试费用,效果相当显著。 本文从代码的可维护性(可读性、可理解性、可修改性)、代码逻辑与效率、函数(模块)接口、可测试性四个方面阐述了软件编程规范,规范分成规则和建议两种,其中规则部分为强制执行项目,而建议部分则不作强制,可根据习惯取舍。 1.排版 规则1 程序块使用缩进方式,函数和标号使用空格缩进,程序段混合使用TAB和空格缩进。缩进的目的是使程序结构清晰,便于阅读和理解。 默认宽度应为8个空格,由于Word中为4个空格,为示范清晰,此处用2个代替(下同)。 例如: MOV R1, #00H MOV R2, #00H MOV PMR, #PMRNORMAL MOV DPS, #FLAGDPTR MOV DPTR, #ADDREEPROM read1kloop: read1kpage: INC R1

MOVX A, @DPTR MOV SBUF, A JNB TI, $ CLR TI INC DPTR CJNE R1, #20H, read1kpage INC R2 MOV R1, #00H CPL WDI CJNE R2, #20H, read1kloop ;END OF EEPROM 规则2 在指令的操作数之间的,使用空格进行间隔,采用这种松散方式编写代码的目的是使代码更加清晰。 例如: CJNE R2, #20H, read1kloop ;END OF EEPROM 规则3 一行最多写一条语句。 规则4 变量定义时,保持对齐。便于阅读和检查内存的使用情况。 例如: RegLEDLOSS EQU 30H ; VARIABLE ; TESTLED==RegLEDLOSS.0 RegLEDRA EQU 31H ; VARIABLE

C语言中文件_数据的输入输出_读写

C语言中文件,数据的输入输出,读写. 文件是数据的集合体,对文件的处理过程就是对文件的读写过程,或输入输出过程。 所谓文件是指内存以外的媒体上以某种形式组织的一组相关数据的有序集合。文件分类: 顺序文件,随机文件。 文本文件和二进制文件。 文本文件也称为ASCII文件,在磁盘中存放时每个字符对应一个字节,用于存放对应的ASCII码。 文本文件可以在屏幕上按字符显示,源程序文件就是文本文件,由于是按字符显示,所以能读懂文件内容。 二进制文件是按二进制编码方式来存放的。这里主要讨论文件的打开,关闭,读,写,定位等操作。 文件的存取方法 C程序的输入输出(I/O)有两种方式:一种称为标准I/O或流式I/O,另一种称为低级I/O。流式I/O是依靠标准库函数中的输入输出函数实现的。低级I/O利用操作系统提供的接口函数(称为底层接口或系统调用)实现输入输出,低级I/O 主要提供系统软件使用。 在C语言中用一个FILE类型的指针变量指向一个文件,(FILE类型是系统在stdio.h中定义的描述已打开文件的一种结构类型),这个指针称为文件指针。FILE *指针变量标识符; 如 FILE *fp; 文件的打开与关闭 所谓打开文件,指的是建立文件的各种有关信息,并使文件指针指向该文件,以便对它进行操作。 关闭文件则是断开指针与文件之间的联系,也就禁止再对该文件进行操作。 1、fopen 函数原型:FILE *fopen(const char *filename,const char *mode); Fopen函数用来打开一个文件,前一部分用来说明文件路径及文件名,后一部分mode指出了打开文件的存取方式;返回值是被打开文件的FILE型指针,若打开失败,则返回NULL。打开文件的语法格式如下: 文件指针名=fopen(文件名,使用文件方式); 文件指针名必须被说明为FILE类型的指针变量。 FILE *fp; fp=fopen(“C:\\Windowss\\abc.txt”,”r”); 注意用两个反斜杠\\来表示目录间的间隔符。 存取文件的模式是一个字符串,可以由字母r,w,a,t,b及+组合而成,各字符的含

c语言值传递的3种形式

//全部摘自别的博客,以前对值传递很迷糊,看完豁然开朗,整理下,来百度文库赚点分。 一、三道考题 开讲之前,我先请你做三道题目。(嘿嘿,得先把你的头脑搞昏才行……唉呀,谁扔我鸡蛋?) 考题一,程序代码如下: void Exchg1(int x, int y) { inttmp; tmp = x; x = y; y = tmp; printf("x = %d, y = %d\n", x, y); } main() { int a = 4,b = 6; Exchg1(a, b); printf("a = %d, b = %d\n", a, b); return(0); } 输出的结果为: x = ____, y=____. a = ____, b=____. 问下划线的部分应是什么,请完成。 考题二,程序代码如下: void Exchg2(int *px, int *py) { inttmp = *px; *px = *py; *py = tmp; printf("*px = %d, *py = %d.\n", *px, *py); } main() { int a = 4; int b = 6; Exchg2(&a, &b);

printf("a = %d, b = %d.\n", a, b); return(0); } 输出的结果为为: *px=____, *py=____. a=____, b=____. 问下划线的部分应是什么,请完成。 考题三,程序代码如下: void Exchg3(int&x, int&y) { inttmp = x; x = y; y = tmp; printf("x = %d,y = %d\n", x, y); } main() { int a = 4; int b = 6; Exchg3(a, b); printf("a = %d, b = %d\n", a, b); return(0); } 输出的结果为: x=____, y=____. a=____, b=____. 问下划线的部分应是什么,请完成。你不在机子上试,能作出来吗?你对你写出的答案有多大的把握?正确的答案,想知道吗?(呵呵,让我慢慢地告诉你吧!) 好,废话少说,继续我们的探索之旅了。 我们都知道:C语言中函数参数的传递有:值传递、地址传递、引用传递这三种形式。题一为值传递,题二为地址传递,题三为引用传递。不过,正是这几种参数传递的形式,曾把我给搞得晕头转向。我相信也有很多人与我有同感吧? 下面请让我逐个地谈谈这三种传递形式。 二、函数参数传递方式之一:值传递 (1)值传递的一个错误认识 先看考题一中Exchg1函数的定义: void Exchg1(int x, int y) /* 定义中的x,y变量被称为Exchg1函数的形式参数*/ {

arm汇编语言调用C函数之参数传递

arm汇编语言调用C函数之参数传递 于ARM体系来说,不同语言撰写的函数之间相互调用(mix calls)遵循的是 ATPCS(ARM-Thumb Procedure Call Standard),ATPCS 主要是定义了函数呼叫时参数的传递规则以及如何从函数返回,关于ATPCS的详细内容可以查看ADS1.2 Online Books ——Developer Guide的2.1节。这篇文档要讲的是汇编代码中对C函数调用时如何进行参数的传递以及如何从C函数正确返回。 不同于x86的参数传递规则,ATPCS建议函数的形参不超过4个,如果形参个数少于或等于4,则形参由R0,R1,R2,R3四个寄存器进行传递;若形参个数大于4,大于4的部分必须通过堆栈进行传递。 我们先讨论一下形参个数为4的情况. 实例1: test_asm_args.asm //-------------------------------------------------------------------------------- IMPORT test_c_args ;声明test_c_args函数 AREA TEST_ASM, CODE, READONLY EXPORT test_asm_args test_asm_args STR lr, [sp, #-4]! ;保存当前lr ldr r0,=0x10 ;参数 1 ldr r1,=0x20 ;参数 2

ldr r2,=0x30 ;参数 3 ldr r3,=0x40 ;参数 4 bl test_c_args ;调用C函数 LDR pc, [sp], #4 ;将lr装进pc(返回main函数) END test_c_args.c //-------------------------------------------------------------------------------- void test_c_args(int a,int b,int c,int d) { printk("test_c_args:\n"); printk("%0x %0x %0x %0x\n",a,b,c,d); } main.c //-------------------------------------------------------------------------------- int main() { test_asm_args(); for(;;); } 程序从main函数开始执行,main调用了test_asm_args,test_asm_args 调用了test_c_args,最后从test_asm_args返回main。代码分别使用了

相关文档
最新文档