精华内容
下载资源
问答
  • C语言函数
    千次阅读
    2021-05-21 05:26:57

    C语言中的函数在其他编程语言中也称为过程或子程序。要执行任务,我们可以创建函数。一个函数可以被多次调用。 它提供了模块化和代码可重用性。

    C语言中函数的优点

    函数有很多优点。它们分别如下 -

    (1)代码可重用性

    通过在CC语言中创建函数,开发人员可以多次调用它。 所以开发人员不需要一次又一次地编写相同的代码。

    (2)代码优化

    它使代码优化,我们不需要编写很多代码。

    假设你要检查3个数字(781,883和531)是否是素数。如果不使用函数,需要编写3次计算素数逻辑。所以有重复的代码。

    但是,如果您使用函数,则只需将计算的逻辑编写一次即可重复使用多次。

    函数类型

    C语言编程中有两种类型的函数:

    库函数:是在C头文件中声明的函数,如:scanf(),printf(),gets(),puts(),ceil(),floor()等。

    用户定义的函数:是由C程序员自己创建的函数,以便他/她可以使用它多次。 它可以降低大型程序的复杂性并优化代码。

    e50d8f5bb76ac48834e78609ccee66f5.png

    函数声明

    C语言中创建函数的语法如下:

    return_type function_name(data_type parameter...){

    //code to be executed

    }

    返回值

    C语言函数可以返回或不返回该函数的值。如果您不需要从函数返回任何值,请对返回类型使用void。

    我们来看一个C语言函数的简单示例,它不会从函数返回任何值。

    没有返回值的示例:

    void hello(){

    printf("hello c");// 没有返回值,只是打印一个字符串

    }

    如果要从函数返回返回某个/些值,则需要使用任何数据类型,如:int,long,char等。返回类型取决于要从函数返回的值。

    我们来看一个C语言函数的简单例子,它从函数返回int值。

    返回值示例:

    int get(){

    return 10;

    }

    在上面的例子中,我们必须返回10作为一个值,所以返回类型是int。 如果要返回浮点值(例如10.2,3.1,54.5等),则需要指定使用float作为函数的返回类型。如下所示 -

    float get(){

    return 10.2;

    }

    现在,需要来了解如何调用函数,获取函数的返回值。

    C语言函数中的参数

    C语言函数可能有0个或更多个参数。可以在C程序中具有任何类型的参数,如:int,float,char等。参数也称为形式参数。

    没有使用参数的函数示例:

    void hello(){

    printf("hello c");

    }

    具有1个参数的函数示例:

    int cube(int n){

    return n*n*n;

    }

    具有2个参数的函数示例:

    int add(int a, int b){

    return a+b;

    }

    在C语言中调用函数

    如果函数返回任何值,则需要调用函数来获取函数返回的值。 在C语言中调用函数的语法如下:

    variable=function_name(arguments...);

    (1)variable:变量不是强制性的。如果函数返回类型为void,则不能提供变量来接收函数返回的值,因为void函数不返回任何值。

    (2)function_name:function_name是要调用的函数的名称。

    (3)arguments:调用C语言函数时需要提供参数。它也被称为实际参数(简称:实参)。

    调用函数的例子:

    hello(); //calls function that doesn't return a value

    int value=get(); //calls function that returns value

    int value2=add(10,20); //calls parameterized function by passing 2 values

    函数示例

    1. 没有return语句的函数示例

    下面来看看看C语言函数的简单程序,它不从函数返回任何值。创建一个名称为:function的工程,并在这个工程里创建一个源文件:function-without-params.c,其代码如下所示 -

    #include

    #include

    //定义一个无参数函数,简单地打印一个字符串

    void hello() {

    printf("hello c programming");

    }

    void main() {

    hello(); // 调用函数

    hello(); // 再一次调用函数

    hello(); // 再一次调用函数

    }

    执行上面示例代码,得到以下结果 -

    hello c programming

    hello c programming

    hello c programming

    2. 带有return语句的C函数示例

    我们来看看C语言中一个带有参数的函数程序。

    创建一个源文件:function-with-params.c,其代码如下所示 -

    #include

    // 定义一函数,返回给定参数值的立方值

    int cube(int n) {

    return n*n*n;

    }

    // 定义一函数,返回给定两个参数值的最大值

    int max(int a, int b) {

    if (a > b) {

    return a;

    }else {

    return b;

    }

    }

    void main() {

    int result1 = 0, result2 = 0;

    int a = 10, b = 20, c = 0;

    result1 = cube(2); // 调用函数

    result2 = cube(5);

    c = max(a, b); //

    printf("the cube of 2 is : %d \n", result1);

    printf("the cube of 5 is : %d \n", result2);

    printf("the max value of %d and %d is :%d \n", a, b, c);

    }

    执行上面示例代码,得到以下结果 -

    the cube of 2 is : 8

    the cube of 5 is : 125

    the max value of 10 and 20 is :20

    ¥ 我要打赏

    纠错/补充

    收藏

    加QQ群啦,易百教程官方技术学习群

    注意:建议每个人选自己的技术方向加群,同一个QQ最多限加 3 个群。

    更多相关内容
  • C语言函数调用栈(一)

    2021-02-02 23:22:49
    编译器使用堆栈传递函数参数、保存返回地址、临时保存寄存器原有值(即函数调用的上下文)以备恢复以及存储本地局部变量。不同处理器和编译器的堆栈布局、函数调用方法都可能不同,但堆栈的基本概念是一样的。寄存器是...
  • C语言是一个强大的语言,特别是对于嵌入式开发过程中有时需要反汇编分析代码中存在的问题,函数C语言中的难点,关于函数调用也是很多人不能理解的,很多知道的也是一知半解。对C语言调用有了一个比较清晰的...
  • 假如函数在调用它之前定义... 您可能感兴趣的文章:深入理解C++中public、protected及private用法C/C++函数调用的几种方式总结浅析C语言中堆和栈的区别关于C语言中参数的传值问题浅谈C语言函数调用参数压栈的相关问题
  • 主要介绍了Python实现的调用C语言函数功能,结合简单实例形式分析了Python使用ctypes模块调用C语言函数的具体步骤与相关操作技巧,需要的朋友可以参考下
  • c语言函数调用及应用举例

    万次阅读 多人点赞 2019-04-20 16:27:29
    一般来说,执行源程序就是执行主函数main,其他函数只能被主函数所调用,而其他函数之间也可以相互调用。 1.标准库函数: 分为:I/O函数,字符串,字符处理函数,数学函数,接口函数,时间转换和操作函数,动态...

    一,函数的定义

    一般来说,执行源程序就是执行主函数main,其他函数只能被主函数所调用,而其他函数之间也可以相互调用。

    1.标准库函数:

    分为:I/O函数,字符串,字符处理函数,数学函数,接口函数,时间转换和操作函数,动态地址分配函数,目录函数,过程控制函数,字符屏幕和图形功能函数。

    这些库函数在不同的头文件中声明。比如:

    math.h头文件中有:sin(x),cos(x),exp(x)(求e^x),fabs(x)(求x的绝对值)等库函数。

    stdio.h头文件中有:scanf(),printf(),gets(),puts(),getchar(),putchar()等库函数。

    string.h头文件中有:strcmp(),strcpy(),strcat(),strlen等库函数。

    2.函数的定义:

    (1)定义无参函数:

    类型名  函数名()

    {

    函数体

    }

    or

    类型名  函数名(void)

    {

    函数体

    }

    (2)定义有参函数

    类型名 函数名(形式参数表列)

    {

    函数体

    }

    (3)定义空函数

    类型名 函数名()

    {    }

    二,函数的调用

    1.函数调用时的参数传递

    函数间通过参数来传递数据,即通过主调函数中的实际参数(实参)向被调用函数中的形式参数(形参)进行传递。

    实参向形参传递数据的方式:实参将值单向传递给形参,形参的变化不影响实参值。

    for example:

    #include<stdio.h>
    #include<stdlib.h>
    int main()
    {
    	int a, b;
    	void swap(int a, int b);		//函数声明
    	scanf("%d%d", &a, &b);		//键盘输入
    	swap(a, b);		//函数调用
    	printf("最终的a,b值:\n  a=%d b=%d\n", a, b);
    	system("pause");
    	return 0;
    }
    void swap(int a, int b)
    {
    	int t;
    	if (a < b)
    	{
    		t = a;
    		a = b;
    		b = t;		//a中放大值,b中放小值
    	}
    	printf("自定义函数的a,b值:\n  a=%d b=%d\n", a, b);
    }
    

    运行结果为:

    分析:形参交换了数据,而实参保持原数据不变。这是单向的值传递,所以形参的值改变后而实参的值没有改变。

    • 形参在函数中是变量名,在函数调用时,形参被临时分配相应的内存,调用结束后,形参单元被释放,而实参单元保留并维持原值。
    • 实参是表达式,负责向对应的形参标识的内存单元传递数据,实参向形参的数据传递是“值传递”。
    • 实参与形参必须个数相同
    • 对应的形参和实参的类型必须一致

    2.函数的返回值

    (1)函数的返回值通过函数中的return语句获得。如果需要从调用函数带回一个函数值(供主函数使用),被调函数中需包含return语句。

    for example:

    int max(int x,int y)
    {
        return(x>y?x:y);
    }

    (2)在定义函数时要指定函数值的类型

    int max(float x,float y)            //函数值为整型
    char letter(char c1,char c2)            //函数值为字符型
    double max(int x,int y)            //函数值为双精度型

    (3)函数类型决定返回值的类型。

    3.函数的嵌套

    定义函数时不能定义另一个函数,但是可以进行嵌套调用函数。

    for example:

    *用函数嵌套找出4个数中的最大值。

    #include<stdio.h>
    #include<stdlib.h>
    int max2(int a, int b)			//找出a和b中的最大值
    {
    	if (a >= b)
    	{
    		return a;			//	a作为返回值
    	}
    	return b;				//	b作为返回值
    }
    int max4(int a, int b, int c, int d)	//定义找4个数最大值的函数
    {
    	int m;		//存最大值
    	m = max2(a, b);		//调用max2函数,将a,b中大的值放在m中
    	m = max2(m, c);		//调用max2函数,将a,b,c中大的值放在m中
    	m = max2(m, d);		//调用max2函数,将a,b,c,d中大的值放在m中
    	return m;		//返回到主函数
    }
    int main()
    {
    	int a, b, c, d;
    	int max;
    	printf("请输入四个数:\n");
    	scanf("%d%d%d%d", &a, &b, &c, &d);
    	max = max4(a, b, c, d);			//调用max4函数
    	printf("最大数位:%d\n", max);
    	system("pause");
    	return 0;
    }
    

    三,函数的递归

    1.递归概念:

    函数的递归调用是指:一个函数在他的函数体内直接或间接地调用它自身。分为:直接递归(函数直接调用自身)和间接递归(函数通过其他函数调用自身)。可分为“回溯”和“递推”两个阶段。

    2.递归函数的一般形式:

    反值类型   递归函数名(参数说明表)

    {

    if(递归终止条件)

    返回值=递归终止值;

    else

    返回值=递归调用(...)的表达式;

    return 返回值;

    }

    3.递归函数举例:

    *用递归求n的阶乘。

    #include<stdio.h>
    #include<stdlib.h>
    int fac(int n)		//定义函数
    {
    	int f;
    	if (n < 0)
    		printf("数据错误\n");
    	else if (n == 0 || n == 1)
    		f = 1;
    	else
    		f = n* fac(n - 1);			//n!=n*(n-1)
    	return f;			//返回主函数
    }
    int main()
    {
    	int n, y;
    	printf("请输入n的值\n");
    	scanf("%d", &n);
    	y = fac(n);		//这里n为实参
    	printf("%d!=%d\n", n, y);
    	system("pause");
    	return 0;
    }

    汉诺塔问题为经典的递归调用实例。代码如下:

    #include<stdio.h>
    #include<stdlib.h>
    void move(char x, char y)	//输出移盘方案
    {
    	printf("%c->%c\n", x, y);
    }
    void hanoi(int n, char one, char two, char three)		//移盘
    {
    	if (n == 1)
    		move(one, three);		//如果是1个盘,直接从第一个座移到第3个座上
    	else
    	{
    		hanoi(n - 1, one, three, two);		
    		move(one, three);
    		hanoi(n - 1, two, one, three);
    	}
    }
    int main()
    {
    	int n;
    	printf("输入盘的个数\n");
    	scanf("%d", &n);
    	printf("移盘的步骤:\n");
    	hanoi(n, 'A', 'B', 'C');
    	system("pause");
    	return 0;
    

    分析:将n个盘子从A座上移到C座上需要三步:

    (1)将A上的n-1个盘子借助C座先移到B座上;

    (2)把A座上剩下的一个盘子移到C座上;

    (3)将n-1个盘从B座上借助于A移到C座上。

     

    展开全文
  • C语言函数及其调用

    万次阅读 多人点赞 2019-04-19 00:08:23
    一、C语言函数 1.概念:函数是一组一起执行一个任务的语句,每个c程序都必须有一个main函数,程序员可以把代码划分到不同的函数当中去,在逻辑上,划分通常是根据每个函数执行一个特定的任务来进行的。c标准库提供...

    一、C语言函数

    1.概念:函数是一组一起执行一个任务的语句,每个c程序都必须有一个main函数,程序员可以把代码划分到不同的函数当中去,在逻辑上,划分通常是根据每个函数执行一个特定的任务来进行的。c标准库提供了可以大量调用的库函数,比如,printf,strcmp等。

    2.函数的定义

    c语言中函数的一般定义如下:

    return_type Function_name(Parameter List)
    {
        The function body
    }

    在c语言中,函数由一个函数头和一个函数主体组成,组成有以下方面:

    1. 函数名称:上面的函数名称即为max。
    2. 函数的返回类型:一个函数可以返回一个值,这里的max函数的返回值是一个int型的整数,函数也可以没有返回值,例如void max(),void代表该函数是一个没有返回值的函数。

    注意函返回类型的值以该函数的返回类型一致,具体表现为:

    1. 函数的参数:当一个函数被调用时可以向该函数的参数传递一个值,这个值叫做实际参数,简称实参,函数的参数叫形式参数,简称形参。当然,一个函数也可以没有参数。
    2. 函数主体:其包括该函数里执行任务的语句,例子中的函数主体就是return a>b?a:b;

    下面是一个定义一个比较大小函数的实例:

    3.函数在定义时会有两种情况

    1. 在main函数之前定义,程序在这种情况下不需要再main函数里声明。
    2. 在main函数之后定义,这时需要在main函数里声明该函数,比如,声明Max函数时
    int main()
    {
        int Max(int a,int b);
    }
    

    二、函数的调用

    1.定义函数时会定义这个函数要做什么,然后通过调用该函数来完成定义的任务。当程序调用函数时,程序控制权会转移给被调用的函数。被调用的函数执行已定义的任务,当函数的返回语句被执行时,或到达函数的结束括号时,会把程序控制权交还给主程序。下面是一个具体调用函数的例子:

    2.函数的嵌套调用与递归

    1. 函数的嵌套调用:简单来说就是在一个定义的函数里在调用另一个函数;

    下面是一个比较三个数大小的例子:

    1. 函数的递归调用:递归是一种特殊的函数调用方式,简单来说就是在一个函数里再调用它自身为递归调用,函数递归会不断调用自己,每调用自己一次就进入新的一层,当最内层函数执行完后然后一层层向外退出。

    以上可以看出递归的代码量比较少,但递归会占用较大的内存,而且运行时间长,所以如果不是什么特殊问题需要用递归解决尽量少用递归。

    3.函数的传参

    函数传递参数会有两种方式:

    1.传值调用:该方法把参数的实际值复制给函数的形式参数。在这种情况下,修改函数内的形式参数不会影响实际参数。(该方式在函数内部不会改变实参的值),比如下面的例子可以说明这点:

    在函数调用过程中,系统会为形参重新申请内存,函数调用完后形参会被释放掉。

    2.引用调用:通过指针传递方式,形参为指向实参地址的指针,当对形参的指向操作时,就相当于对实参本身进行的操作。

     

     

     

     

    展开全文
  • C语言函数调用过程

    千次阅读 多人点赞 2018-04-22 18:44:44
    C语言函数调用过程 反汇编代码 main()函数的创建 Add()函数的调用过程 main()函数的销毁 C语言函数调用过程 先上一段代码 #include&lt;stdio.h&gt; int Add(int x, int y) { int z = 0; z = x...

    目录

    C语言的函数调用过程

    先上一段代码

    #include<stdio.h>
    int Add(int x, int y)
    {
        int z = 0;
        z = x + y;
        return z;
    }
    #include <stdio.h>
    int main()
    {
        int a = 10;
        int b = 20;
        int c = Add(a, b);
        return 0;
    }

    这个函数计算两个数的值。接下来我们通过反汇编,来看看函数被后的过程。

    反汇编代码

    #include <stdio.h>
    int main()
    {
    01151720  push        ebp  
    01151721  mov         ebp,esp  
    01151723  sub         esp,0E4h  
    01151729  push        ebx  
    0115172A  push        esi  
    0115172B  push        edi  
    0115172C  lea         edi,[ebp-0E4h]  
    01151732  mov         ecx,39h  
    01151737  mov         eax,0CCCCCCCCh  
    0115173C  rep stos    dword ptr es:[edi]  
        int a = 10;
    0115173E  mov         dword ptr [a],0Ah  
        int b = 20;
    01151745  mov         dword ptr [b],14h  
        int c = Add(a, b);
    0115174C  mov         eax,dword ptr [b]  
    0115174F  push        eax  
    01151750  mov         ecx,dword ptr [a]  
    01151753  push        ecx  
    01151754  call        _Add (01151104h)  
    01151759  add         esp,8  
    0115175C  mov         dword ptr [c],eax  
        return 0;
    0115175F  xor         eax,eax  
    }
    01151761  pop         edi  
    01151762  pop         esi  
    01151763  pop         ebx  
    01151764  add         esp,0E4h  
    0115176A  cmp         ebp,esp  
    0115176C  call        __RTC_CheckEsp (01151122h)  
    01151771  mov         esp,ebp  
    01151773  pop         ebp  
    }
    //Add()
    #include<stdio.h>
    int Add(int x, int y)
    {
    001016D0  push        ebp  
    001016D1  mov         ebp,esp  
    001016D3  sub         esp,0CCh  
    001016D9  push        ebx  
    001016DA  push        esi  
    001016DB  push        edi  
    001016DC  lea         edi,[ebp-0CCh]  
    001016E2  mov         ecx,33h  
    001016E7  mov         eax,0CCCCCCCCh  
    001016EC  rep stos    dword ptr es:[edi]  
        int z = 0;
    001016EE  mov         dword ptr [z],0  
        z = x + y;
    001016F5  mov         eax,dword ptr [x]  
    001016F8  add         eax,dword ptr [y]  
    001016FB  mov         dword ptr [z],eax  
        return z;
    001016FE  mov         eax,dword ptr [z]  
    }
    00101701  pop         edi  
    00101702  pop         esi  
    00101703  pop         ebx  
    00101704  mov         esp,ebp  
    00101706  pop         ebp  
    00101707  ret  

    以上就是反汇编代码。现在我们一段一段的进行解读,去看看整个程序是怎么执行的。

    main()函数的创建

    01151720  push        ebp  
    01151721  mov         ebp,esp  
    01151723  sub         esp,0E4h  
    01151729  push        ebx  
    0115172A  push        esi  
    0115172B  push        edi  
    0115172C  lea         edi,[ebp-0E4h]  
    01151732  mov         ecx,39h  
    01151737  mov         eax,0CCCCCCCCh  
    0115173C  rep stos    dword ptr es:[edi]  
    //分割线.........................
    int a = 10;
    0115173E  mov         dword ptr [a],0Ah  
        int b = 20;
    01151745  mov         dword ptr [b],14h 

    这里要给读者朋友们简单说一下变量的含义。ebp 和 esp 是两个通用寄存器。它们可以存储 立即数内存地址。esi是源变址寄存器。edi是目的变址寄存器。
    它们都可用来储存地址。

    在main()函数之前有一个函数CRTStartUp,ebp为这个函数的栈底,esp为这个函数的栈顶。
    这里写图片描述
    接下来通过前两句代码mov 赋值移动,它们的状态变成了如下:
    这里写图片描述
    第三句话中,sub是减法指令,这句话使得esp向后移动了0E4h个单位。
    接下来的三句话,是将ebx,esi,edi压入了栈当中。
    这里写图片描述
    第七句话,lea 的意思是load effective address,也就是将[ebp - 0E4h]的地址取出来,赋值给了edi。
    第八句话,将39h赋值移动到ecx。第九句话,将内容赋值移动给eax。
    第十句话,rep stos 是重复拷贝数据。
    注意:
    ecx寄存器是用来保存复制粘贴的次数,ecx是计数器。
    eax寄存器是用来传送信息的,eax是累加器,通常用来存储数据。
    rep 是重复上述指令。
    stos 是将eax的值赋值移动给 es:[edi]这个地址的存储单元。
    这里写图片描述
    现在其中的空白部分被cc cc cc cc充满了。这里cc cc就是经常遇到的“烫烫”。
    分割线
    接下来的操作很好理解,其目的是将 a和b创建,并且压入栈中。
    这里写图片描述

    Add()函数的调用过程

        int c = Add(a, b);
    0115174C  mov         eax,dword ptr [b]  
    0115174F  push        eax  
    01151750  mov         ecx,dword ptr [a]  
    01151753  push        ecx  
    01151754  call        _Add (01151104h)  
    01151759  add         esp,8  
    0115175C  mov         dword ptr [c],eax  

    前四句话,它将a和b找了个寄存器存起来,与此同时,以函数参数列表倒着的方式压入栈中。
    这里写图片描述
    方便起见,下面的图将只截取上半部分。

    接下来使用了call指令,这个指令是先将 指令 移动到下一句话,然后再操纵call 后面的内容。在call处按F11我们将跳转到Add()函数。
    这里写图片描述
    Add()函数

    
    #include<stdio.h>
    int Add(int x, int y)
    {
    001016D0  push        ebp  
    001016D1  mov         ebp,esp  
    001016D3  sub         esp,0CCh  
    001016D9  push        ebx  
    001016DA  push        esi  
    001016DB  push        edi  
    001016DC  lea         edi,[ebp-0CCh]  
    001016E2  mov         ecx,33h  
    001016E7  mov         eax,0CCCCCCCCh  
    001016EC  rep stos    dword ptr es:[edi]  

    这一部分和main函数创建过程非常相似。所以用俩图来表示。
    这里写图片描述
    这里写图片描述

        int z = 0;
    001016EE  mov         dword ptr [z],0  
        z = x + y;
    001016F5  mov         eax,dword ptr [x]  
    001016F8  add         eax,dword ptr [y]  
    001016FB  mov         dword ptr [z],eax  
        return z;
    001016FE  mov         eax,dword ptr [z]  
    }
    00101701  pop         edi  
    00101702  pop         esi  
    00101703  pop         ebx  
    00101704  mov         esp,ebp  
    00101706  pop         ebp  
    00101707  ret  

    这段代码非常有意思,请读者朋友们一定要注意。
    首先,我们创建了变量 ptr[z]。然后,将ptr[x]的值放在eax里边,将ptr[y]的值与eax相加后再放在eax里,将eax的值赋值移动到 ptr[z]中。最后,我们需要return z。这个地方编译器再次将ptr[z]的值赋值移动到了eax。这么做的原因是:ptr[x]、ptr[y]、ptr[z]将在函数完成后就会销毁,但是寄存器eax不会被销毁,所以在eax的值非常安全。

    括号外的第四句话非常重要。它将销毁该函数的所有数据。
    这里写图片描述
    将ebp弹出后,该点只有一个指针esp。接下来执行ret,即 return 返回。返回到我们刚才call下面的地方。

    main()函数的销毁

    01151759  add         esp,8  
    0115175C  mov         dword ptr [c],eax  
        return 0;
    0115175F  xor         eax,eax  
    }
    01151761  pop         edi  
    01151762  pop         esi  
    01151763  pop         ebx  
    01151764  add         esp,0E4h  
    0115176A  cmp         ebp,esp  
    0115176C  call        __RTC_CheckEsp (01151122h)  
    01151771  mov         esp,ebp  
    01151773  pop         ebp  
    }

    现在我们跳回到了该段的第一句话,现在esp + 8向高地址进发了。其目的就是消去了形参实例化的a,b。第二句话,我们将eax里保存的数据赋值移动给了c。最后,xor异或,自己和自己异或 其值变为0。

    这里写图片描述
    之后,我们出栈了 edi,esi,ebx。现在esp指向了最开始我们红色那个箭头 ebp - 0E4h
    然后,由于add操作,我们继续向高地址进发,到了我们最开始的地方。
    这里写图片描述
    这里写图片描述
    现在,我们到了cmp指令,cmp是比较指令。它的操作是拿第一个数减去第二个数,如果相减为ZF=0说明相等。但是cmp并不会真的减。到此位置main()函数就真的执行完毕,然后esp,ebp。回到了原来的位置。至于后面的函数调用,并不需要深究。至此我们就看到了在汇编上函数如何实现的

    谢谢您的阅读,如有问题,请多指教。

    展开全文
  • c语言函数调用原理底层分析

    千次阅读 2019-03-26 22:51:27
    2函数调用机制 2.1按调用约定传递参数 2.1调用约定 调用方(caller)和被调方(callee)需要约定以下内容: 1传参顺序 2传递参数的媒介(是放栈还是寄存器) 3清理参数的责任归属 4返回值的传递媒介(返回值...
  • 主要介绍了Lua中调用C语言函数实例,本文先讲解了相关知识,然后给出了调用实例,需要的朋友可以参考下
  • C语言函数调用常见问题(1)

    千次阅读 2019-01-09 11:34:58
    在我看来 有许多计算问题如果通过函数调用方式来解决就会使得代码整体看起来简介又便于识别 但是在调用函数时候要注意以下几个问题 一、基本功能 1、函数调用,即把函数的输入值填进函数名后面的括号中,不需要注明...
  • C语言函数调用

    千次阅读 2020-02-24 11:38:59
    函数调用(Function Call),就是使用已经定义好的函数。 函数调用的一般形式为: functionName(param1, param2, param3 ...);...C语言中,函数调用的方式有多种,例如: //函数作为表达式中的一项出...
  • C语言函数定义和函数调用

    千次阅读 2020-04-01 19:05:47
    最简单的程序有一个主函数 main(),但实用程序往往由多个函数组成,由 主函数调用其他函数,其他函数也可以互相调用函数是C源程序的基本模块,程序的许多功能是通过对 函数模块的调用来实现的,学会编写和调用函数可以...
  • 浅谈C语言函数调用与系统调用

    千次阅读 2019-11-12 09:55:50
    很多初学C语言的同学,亦或者开发中很少接触系统底层的同学可能会认为函数调用以及系统调用是一回事。因为在应用程序,两者都被抽象成接口去给应用程序调用。其实函数调用和系统调用还是有区别,我们通过下图先有个...
  • C语言函数调用时候内存中栈的动态变化详细分析

    千次阅读 多人点赞 2019-05-02 00:23:41
    先了解如下几点知识和过程: ...这些指令代码是存放在内存中进程的代码段,同一个函数内的指令代码是按照地址顺序存储的(编译器决定的)(也就是说只要指令地址+1就可以自动得到下一条指令的地址...
  • C语言实现函数调用的三种方法

    千次阅读 2021-01-28 21:53:20
    在一个.c文件里面进行子函数调用 step1:函数声明 step:mian函数 step:子函数 /******************************** 数组元素之和 法一: 子函数调用 **********************************/ #include<stdio.h&...
  • C语言函数调用是怎么样一个过程?

    千次阅读 2019-03-07 19:04:27
    大多数CPU上的程序实现使用栈来支持函数调用操作,栈被用来传递函数参数、存储返回信息、临时保存寄存器原有的值以备恢复以及用来存储局部变量。 函数调用操作所使用的栈部分叫做栈帧结构,每个函数调用都有属于...
  • 在java中调用C语言函数,对初学者很不错的实例! 在java中调用C语言函数,对初学者很不错的实例!
  • C语言函数调用的底层机制C语言函数调用的底层机制C语言函数调用的底层机制C语言函数调用的底层机制C语言函数调用的底层机制C语言函数调用的底层机制
  • c语言函数的三种调用方式是什么?

    千次阅读 2021-07-27 00:12:25
    函数的三种调用方式:1、函数作为表达式中的一项出现在表达式中,例“z=max(x,y)”;2、函数作为一个单独的语句,例“printf("%d",a)”;3、函数作为调用另...
  • 主要介绍了C语言调用Lua函数实例,本文讲解了调用一个Lua函数的步骤和C语言调用Lua函数实例,需要的朋友可以参考下
  • C语言调用函数传递二维数组

    千次阅读 2021-05-21 09:25:08
    转置二维数组的实例代码,探究二维数组作为参数...void main(){//在主函数内声明被调函数void convert(int array[][3]);int i,j;printf("输入数组:\n");for(j=0;jfor(i=0;iscanf("%d",&array[i][j]);printf("\n"...
  • c语言函数调用的参数太多

    千次阅读 2021-07-29 13:24:23
    c语言函数调用的参数太多问题问题展示问题分析解决方法 问题展示 (图中是我遇到的情况) 问题分析 大家可以看到,在函数中,指针变量和后面的整数变量都成了灰色 解决方法 图中问题只需将中文逗号,改为英文...
  • c语言函数调用中用指针操作数组

    千次阅读 2020-08-18 17:23:07
    直接上代码 #include using namespace std; int p[20]; void change(int *p){ for(int... } 输出为 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 如果你传入的指针指向的是一个数组,在函数体中就可以直接用数组下标等操作
  • C语言函数调用流程

    千次阅读 2019-12-27 21:51:47
    保存的上下文:包括在函数调用前后需要保持不变的寄存器 //函数从左到右,还是从右向左压栈 int fun(int a,int b ) { int t_a = a; int t_b = b; return t_a + t_b; } int main() { int ret = 0; ret = fun...
  • c语言函数的三种调用方式是什么

    千次阅读 2021-05-22 01:22:33
    函数的三种调用方式:1、函数作为表达式中的一项出现在表达式中,例“z=max(x,y)”;2、函数作为一个单独的语句,例“printf("%d",a)”;3、函数作为调用另一个函数时的实参,例“printf("%d...函数调用的一般形式为...
  • C语言函数调用的简单例子

    千次阅读 2019-11-29 10:41:00
    #include<stdio.h> void p1() { printf("******************\n");... printf("一起学习C语言函数呀!\n"); } int main() { p1(); p2(); p1(); return 0; } 例题中p1和p2都是用户定义的函数...
  • C语言函数调用问题汇总

    千次阅读 2016-10-08 11:18:41
    在进行函数/方法的调用时,函数的实参是存在于存储空间某个具体位置的一段指定空间的,而任何函数或方法都会被程序控制器开辟一个栈空间(stack),这个空间也是一段存储位置,有时候为了效率起见,它存在于
  • 差不多每个程序员都知道,函数调用过程,就是层层入栈出栈的过程。 那么这个过程中的详细的细节是什么样子的呢? 阅读了以下几篇文章之后,对整个过程基本理解了: C函数调用过程原理及函数栈帧分析 阅读经典——...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 442,039
精华内容 176,815
关键字:

C语言函数调用保存