精华内容
下载资源
问答
  • 关于函数调用时形参与实参情况

    千次阅读 2020-03-01 00:46:18
    关于函数调用时形参与实参情况 首先什么是形参与实参 形式参数:定义函数时函数名后括号中变量名! 实际参数:调用函数时函数名后括号中表达式! 1.形参未被调用时,不占存储单元。形参只在调用过程中占用存储...

    关于函数调用时形参与实参的情况

    首先什么是形参与实参

    形式参数:定义函数时函数名后括号中的变量名!
    实际参数:调用函数时函数名后括号中的表达式!

    1.形参未被调用时,不占存储单元。形参只在调用过程中占用存储单元。形参定义时必须指定类型!
    2.实参是常量。变量或者表达式!要与形参类型一致!而且实参要有确定的值,占用储存单元,在调用过程中实参将值赋给形参!
    3.C中实参对形参数据传递时时单向传递。在存储单元中是不同的单元

    三种情况

    情况一

    #include<stdio.h>
    void swap(int p,int q) { //p,q为形参
        int temp = p;
        p = q;
        q = temp;
    }
    int main() {
        int a,b;
        scanf("%d%d",&a,&b);//a,b为实参
        swap(a,b);
        printf("%d %d",a,b);
    }

    在这里插入图片描述
    在上面第三条性质中实参对形参数据传递时时单向传递,在存储单元中是不同的单元,所以在swap函数中并不能改变a,b的值

    情况二

    #include<stdio.h>
    void swap(int *p,int *q) { //p,q为形参
        int temp = *p;
        *p = *q;
        *q = temp;
    }
    int main() {
        int a,b;
        scanf("%d%d",&a,&b);//a,b为实参
        swap(&a,&b);
        printf("%d %d",a,b);
    }

    在这里插入图片描述
    要想在swap函数里改变a,b值则使用指针

    情况三

    #include<stdio.h>
    void swap(int *p,int *q) { //p为形参
    	printf("p = %d q = %d\n",p,q);
    	p = q;
    	printf("p = %d q = %d\n",p,q);
    }
    int main() {
        int a,b;
        scanf("%d%d",&a,&b);//a为实参
        swap(&a,&b);
        printf("&a = %d &b = %d\n",&a,&b);
        printf("a = %d b = %d\n",a,b);
    }

    大家先思考一下结果会是什么,该情况是我们在函数实参与实参使用时经常出的BUG

    在这里插入图片描述

    注:(以上图的地址为例)在理解该情况实参与形参的指针与地址传递时

    //在主函数开始swap函数传入a,b地址
    p = &a; //该操作使a与p变量公用一块地址
    q = &b; //该操作使b与q变量公用一块地址
    //在swap函数里
    p = q //使p与q公用一块地址,而p已经不与a用一块地址了,所以p的任何改变都与a无关,而与b有关

    所以大家在函数中应注意地址改变与数值改变区别

    展开全文
  • 关于函数调用中形参分析总结:SkyJacker贡献者:LiuXiao,小冬,Bahamut, 考拉, http://www.cnpack.orgCnPack IV QQ Group: 1309702007-02-02(转贴请注明作者、出处且保持完整)一、形参3种基本形式function a...

     

    关于函数调用中形参的分析
    总结:SkyJacker
    贡献者:LiuXiao,小冬,Bahamut, 考拉, 
    http://www.cnpack.org
    CnPack IV  QQ Group: 130970
    
    2007-02-02
    (转贴请注明作者、出处且保持完整)
    
    一、形参的3种基本形式
    function a(b: Integer): Integer; 
    function a(var b: Integer): Integer; 
    function a(const b: Integer): Integer; 
    
    b: 函数体内给b赋值后不会传出函数外 
    var b: 函数体内给b赋值后会传出函数外 
    const b: 函数体内不可以给b赋值  
    
    二、解释
    
    一种是用值传递的方式,
    也就是说,在参数传递的时候只把参数的值传入函数内部 
    另一种是地址传递的方式,在参数传递时传入参数的地址 function a(var b: Integer): Integer; 
    在调用A函数的时候 a(i); 其实参数是@i。  
    
    要清楚下面的解释过程,需要看一下 《如何理解Move参数中的const Source和var Dest》
    地址:
    
    http://www.cnpack.org/showdetail.php?id=476
    
    (一种典型的上下文 context ?)
    
    在函数内部的Pascal实现中,Source是传入的地址再指了一次而得到的结果,
    因此仍然代表传进来之前的Source。欲取得汇编中实现时传入来的地址,则需要用@Source。
    也就是说,这个var封装并且隐藏了函数被调用时传入的取地址操作和函数体内部使用时指了一次的操作。
    
    举个浅显的例子:  
    
    procedure(I: Integer); 
    var
      J: Integer; 
    begin   
      J := I; 
    end;  
    
    调用的时候,I的值被传进来,赋值给了J,这样理解没问题。  
    但如果是:
    
    procedure(var I: Integer); 
    var
      J: Integer; 
    begin   
      J := I; 
    end;  
    
    那么,在底层实现中,也就是在汇编中,I的地址被传进来了,
    然后函数内部指了一次,取到了它的值,赋值给了J。  
    但对外来讲,J := I;这句本身所完成的功能还是没有变化。
    但如果在函数体里头写 I := 0,那么这俩函数的实现功能就有区别了。  
    
    不带var的,传入的是一个I的值,这个值存在一个临时的地方,可能是寄存器,也可能是堆栈区。
    I := 0;就是把这个临时地方的值塞成0.   
    
    带var的,传入的是I的地址,这个地址值也存在一个临时地方。
    但赋值的时候,这个地址指了一次,于是就指向传入前的I了,那么I:= 0就把传入前的变量的值给改变了。  
    
    三、测试实例
    根据以上的介绍,上机测试了一下。学习乃学而时习之嘛。
    //调试环境:XP sp2 + Delphi6 + Update2
    //调试设置:关闭优化选项.
    //主要是看看效率如何
    //实际编程中应该如何应用,如何避免出现形参声明混乱的情况呢。
    //暂且将过程名A,B,C 叫为A模式,B模式,C模式
    //注:下面仅是对Integer形参的分析.
    
    procedure A(I: Integer);
    var
      J: Integer;
    begin
      J := I;
      I := 11;
    end;
    
    procedure B(var I: Integer);
    var
      J: Integer;
    begin
      J := I;
      I := 12; // 由于对 Var 类型的I 复制,因此无需关闭优化选项
    end;
    
    procedure C(const I: Integer);
    var
      J: Integer;
    begin
      J := I; 
      //I := 12; // Could not compile
    end;
    
    procedure TForm1.btnTestVarClick(Sender: TObject);
    var
      Ka: Integer;
      Kb: Integer;
      Kc: Integer;
    begin
      Ka := 11;
      Kb := 12;
      Kc := 13;
      A(Ka);
      B(Kb);
      C(Kc);
      Log('Ka' + IntToStr(Ka));
      Log('Kb' + IntToStr(Kb));
      Log('Kc' + IntToStr(Kc));
    end;
    
    //Delphi局部变量的生成特点:
    //存入堆栈,Ka,Kb,Kc在堆栈中的地址方向为从高地址到低地址
    0047D084 C745F80B000000   mov [ebp-$08],$0000000b  
    0047D08B C745F40C000000   mov [ebp-$0c],$0000000c
    0047D092 C745F00D000000   mov [ebp-$10],$0000000d
    0047D099 8B45F8           mov eax,[ebp-$08]
    0047D09C E86FFFFFFF       call A
    0047D0A1 8D45F4           lea eax,[ebp-$0c]  //B Var取得是地址
    0047D0A4 E883FFFFFF       call B
    0047D0A9 8B45F0           mov eax,[ebp-$10]
    0047D0AC E89BFFFFFF       call C
    0047D0B1 8D55E4           lea edx,[ebp-$1c]
    
    procedure A(I: Integer);
    0047CD28 55               push ebp
    0047CD29 8BEC             mov ebp,esp
    0047CD2B 83C4F8           add esp,-$08
    0047CD2E 8945FC           mov [ebp-$04],eax  //在堆栈中开辟一空间存放形参I值
    0047CD31 8B45FC           mov eax,[ebp-$04]
    0047CD34 8945F8           mov [ebp-$08],eax
    0047CD37 C745FC0B000000   mov [ebp-$04],$0000000b
    0047CD3E 59               pop ecx
    0047CD3F 59               pop ecx
    0047CD40 5D               pop ebp
    0047CD41 C3               ret 
    
    procedure B(var I: Integer);
    0047CD44 55               push ebp
    0047CD45 8BEC             mov ebp,esp
    0047CD47 83C4F8           add esp,-$08
    0047CD4A 8945FC           mov [ebp-$04],eax  //在堆栈中开辟一空间存放传入的地址
    0047CD4D 8B45FC           mov eax,[ebp-$04]
    0047CD50 8B00             mov eax,[eax]     //多了一次寻址
    0047CD52 8945F8           mov [ebp-$08],eax
    0047CD55 8B45FC           mov eax,[ebp-$04] //多了一次寻址
    0047CD58 C7000C000000     mov [eax],$0000000c
    0047CD5E 59               pop ecx
    0047CD5F 59               pop ecx
    0047CD60 5D               pop ebp
    0047CD61 C3               ret 
    
    procedure C(const I: Integer);
    0047CD64 55               push ebp
    0047CD65 8BEC             mov ebp,esp
    0047CD67 83C4F8           add esp,-$08
    0047CD6A 8945FC           mov [ebp-$04],eax //在堆栈中开辟一空间存放形参I值
    0047CD6D 8B45FC           mov eax,[ebp-$04]
    0047CD70 8945F8           mov [ebp-$08],eax
    0047CD73 59               pop ecx
    0047CD74 59               pop ecx
    0047CD75 5D               pop ebp
    0047CD76 C3               ret 
    
    说明如下 
    //对整型形参而言, 
    A, C的执行代码效率是比较高的,
    A比较简洁,C会增加编译器处理Const的时间
    A与C除了const外,内部执行过程没有任何不同。
    B 用于在函数内部修改外部变量的情况.
    
    具体如何使用呢,我想看看SysUtils.pas,StrUtils如何处理的.
    我对SysUtils,StrUtils走马观花看了一下,
    在SysUtils中,
    大部分函数的形参,如果是基本类型,比如Integer,Byte 基本上是按照A模式.
    如果形参是String,全部是B模式常量声明(没有看到没有用const的)。
    
    比如:
    function StrToInt(const S: string): Integer;
    function StrToIntDef(const S: string; Default: Integer): Integer;
    function TryStrToInt(const S: string; out Value: Integer): Boolean;
    function IntToStr(Value: Integer): string; overload;
    function IntToStr(Value: Int64): string; overload;
    function TrimLeft(const S: string): string; overload;
    function TrimLeft(const S: WideString): WideString; overload;
    
    一些特例:
    procedure ScanToNumber(const S: string; var Pos: Integer);
    function ScanChar(const S: string; var Pos: Integer; Ch: Char): Boolean;
    function StrLCat(Dest: PChar; const Source: PChar; MaxLen: Cardinal): PChar;
    function StrComp(const Str1, Str2: PChar): Integer;
    
    在StrUtils中,
    function ReverseString(const AText: string): string;
    function LeftStr(const AText: string; const ACount: Integer): string;
    function RightStr(const AText: string; const ACount: Integer): string;
    function MidStr(const AText: string; const AStart, ACount: Integer): string;
    
    
    System.pas中
    procedure _WStrDelete(var S: WideString; Index, Count: Integer);
    function StrPos(const Str1, Str2: PChar): PChar; assembler;
    function StrUpper(Str: PChar): PChar; assembler;
    function StrLower(Str: PChar): PChar; assembler;
    function StrPas(const Str: PChar): string;
    
    
    关于形参声明形式的个人小总结
      相信 Delphi 中的 System,SysUtils,StrUtils 中函数形参的使用,都有其用意.
      站在巨人的肩膀上,在实际开发中,声明大部分普通函数的形参的原则为:
      如果是string格式的一定要加上const,使用C模式.
      如果是基本类型如Integer,则使用A模式,什么也不加.
      如果考虑到一些特殊的需求,比如传输内存,含有字符串删除等操作, 则考虑使用var声明.
    
      还有许多没有解决或没有被证明的问题:
      1、为什么string最好声明为const
      2、const 的作用 等等。
      
      
    后记:
      之后,看了下 《Pascal精要》 第六章 过程与函数,觉得有些地方还是需要列出来以供参考:
    
    1、 
    Pascal 例程的传递参数可以是值参也可以是引用参数。
    值参传递是缺省的参数传递方式:即将值参的拷贝压入栈中,例程使用、操纵的是栈中的拷贝值,不是原始值。
    当通过引用传递参数时,没有按正常方式把参数值的拷贝压栈(避免拷贝值压栈一般能加快程序执行速度),
    而是直接引用参数原始值,例程中的代码也同样访问原始值,这样就能在过程或函数中改变参数的值。
    
    
    2、
    参数引用技术在大多数编程语言中都有,C语言中虽没有,但C++中引入了该技术。
    在C++中,用符号 &表示引用;在VB中,没有ByVal 标示的参数都为引用。
    
    3、
    通过引用传递参数对有序类型、传统字符串类型及大型记录类型才有意义。
    实际上Delphi总是通过值来传递对象,因为Delphi对象本身就是引用。
    因此通过引用传递对象就没什么意义(除了极特殊的情况),因为这样相当于传递一个引用到另一个引用。
    Delphi 长字符串的情况略有不同,长字符串看起来象引用,但是如果你改变了该字符串的串变量,
    那么这个串在更新前将被拷贝下来。
    作为值参被传递的长字符串只在内存使用和操作速度方面才象引用,
    但是如果你改变了字符串的值,初始值将不受影响。
    相反,如果通过引用传递长字符串,那么串的初始值就可以改变。
    

    展开全文
  • Nim函数调用的几种形式Nim转载条件:如果你需要转载本文,你需要做到完整转载本文所有的内容,不得删改文内的作者名字与链接。否则拒绝转载。 关于nim的例行介绍: Nim 是一门静态编译型的系统级编程语言,内置GC,...

    Nim函数调用的几种形式

    转载条件:如果你需要转载本文,你需要做到完整转载本文所有的内容,不得删改文内的作者名字与链接。否则拒绝转载。

    关于nim的例行介绍:

    Nim 是一门静态编译型的系统级编程语言,内置GC,采用像Python一样的缩进风格,Nim代码被翻译成C再编译成可执行文件。
    所以nim的特点是兼具简洁,性能不错,可执行文件也比较小,跨平台,开发效率快等等特点。
    如果你愿意,Nim也可以被编译成c++ 、Javascript 、OC之类的。

    nim 的官方网站: https://nim-lang.org/

    关于nim的开发环境:
    完整的nim环境由三个部分组成,nim程序后端编译器代码编辑器
    nim代码的编译过程大约是:→ 把nim代码编译成c → 再由c编译器编译成可执行文件。

    nim 编辑器环境我目前推荐 vscode + nim 扩展 ,装好就能用,基本不折腾。

    codegay 2017年9月19日 06:33:49

    正文:
    一开始的时候我注意到nim 这可以写echo "haha",也可以写成echo("haha") , 让我感觉很好奇。
    好了,你现在也知道这两种写法形式是等价的了,更多的写法形式请看代码。

    代码示例:

    1. #nim版Hello world 
    2.  
    3. #nim函数调用的基本形式,以下这三种写法是等效的 
    4. echo "v1-Hello world!" #命令式的风格,我个人最喜欢命令式啦,还能少写两括号。 
    5. echo("v2-Hello world!") #过程调用式的风格 
    6. "v3-Hello world!".echo #方法调用的风格 
    7.  
    8. #复合的风格形式 
    9. "v4-Hello world!".echo("空格 空格","第三个参数"
    10. "v5-Hello ".echo "world!" 
    11. "v6-Hello ".echo "world!", "第三个参数" 
    12.  
    13. echo 1,2,3 
    14. echo("a", "b", "c"
    15.  
    16. echo "数字也可以这样33333.echo" 
    17. 3333.echo 

    在命令行界面上运行一下chcp 65001,让windows的cmd用utf8显示中文。
    编译并运行后输出的信息如下:

    1. C:\Users\root\Desktop\test>nim c -r "c:\Users\root\Desktop\test\hellonim.nim" 
    2. Hint: used config file 'D:\dev\nim-0.17.2_x64\config\nim.cfg' [Conf] 
    3. Hint: system [Processing] 
    4. Hint: hellonim [Processing] 
    5. Hint: [Link] 
    6. Hint: operation successful (10999 lines compiled; 0.374 sec total; 17.938MiB peakmem; Debug Build) [SuccessX] 
    7. Hint: c:\Users\root\Desktop\test\hellonim.exe [Exec] 
    8. v1-Hello world! 
    9. v2-Hello world! 
    10. v3-Hello world! 
    11. v4-Hello world!空格 空格第三个参数 
    12. v5-Hello world! 
    13. v6-Hello world!第三个参数 
    14. 123 
    15. abc 
    16. 数字也可以这样33333.echo 
    17. 3333 

    参考资料:
    nim官方文档: https://nim-lang.org/docs/manual.html#procedures-method-call-syntax
    Nim 语言有哪些特点 : https://segmentfault.com/a/1190000002576013

    转载于:https://www.cnblogs.com/gayhub/p/7549849.html

    展开全文
  • 关于函数调用中形参分析

    千次阅读 2007-02-03 08:21:00
    关于函数调用中形参分析总结:SkyJacker贡献者:LiuXiao,小冬,Bahamut, 考拉, http://www.cnpack.orgCnPack IV QQ Group: 130970 2007-02-02(转贴请注明作者、出处且保持完整) 一、形参3种基本形式function...
    关于函数调用中形参的分析
    

    总结:SkyJacker
    贡献者:LiuXiao,小冬,Bahamut, 考拉,
    http://www.cnpack.org
    CnPack IV  QQ Group: 130970

    2007-02-02
    (转贴请注明作者、出处且保持完整)

    一、形参的3种基本形式
    function a(b: Integer): Integer;
    function a(var b: Integer): Integer;
    function a(const b: Integer): Integer;

    b: 函数体内给b赋值后不会传出函数外
    var b: 函数体内给b赋值后会传出函数外
    const b: 函数体内不可以给b赋值  

    二、解释

    一种是用值传递的方式,
    也就是说,在参数传递的时候只把参数的值传入函数内部
    另一种是地址传递的方式,在参数传递时传入参数的地址 function a(var b: Integer): Integer;
    在调用A函数的时候 a(i); 其实参数是@i。  

    要清楚下面的解释过程,需要看一下 《如何理解Move参数中的const Source和var Dest》
    地址:

    http://www.cnpack.org/showdetail.php?id=476

    (一种典型的上下文 context ?)

    在函数内部的Pascal实现中,Source是传入的地址再指了一次而得到的结果,
    因此仍然代表传进来之前的Source。欲取得汇编中实现时传入来的地址,则需要用@Source。
    也就是说,这个var封装并且隐藏了函数被调用时传入的取地址操作和函数体内部使用时指了一次的操作。

    举个浅显的例子:  

    procedure(I: Integer);
    var
      J: Integer;
    begin  
      J := I;
    end;  

    调用的时候,I的值被传进来,赋值给了J,这样理解没问题。  
    但如果是:

    procedure(var I: Integer);
    var
      J: Integer;
    begin  
      J := I;
    end;  

    那么,在底层实现中,也就是在汇编中,I的地址被传进来了,
    然后函数内部指了一次,取到了它的值,赋值给了J。  
    但对外来讲,J := I;这句本身所完成的功能还是没有变化。
    但如果在函数体里头写 I := 0,那么这俩函数的实现功能就有区别了。  

    不带var的,传入的是一个I的值,这个值存在一个临时的地方,可能是寄存器,也可能是堆栈区。
    I := 0;就是把这个临时地方的值塞成0.  

    带var的,传入的是I的地址,这个地址值也存在一个临时地方。
    但赋值的时候,这个地址指了一次,于是就指向传入前的I了,那么I:= 0就把传入前的变量的值给改变了。  

    三、测试实例
    根据以上的介绍,上机测试了一下。学习乃学而时习之嘛。
    //调试环境:XP sp2 + Delphi6 + Update2
    //调试设置:关闭优化选项.
    //主要是看看效率如何
    //实际编程中应该如何应用,如何避免出现形参声明混乱的情况呢。
    //暂且将过程名A,B,C 叫为A模式,B模式,C模式
    //注:下面仅是对Integer形参的分析.

    procedure A(I: Integer);
    var
      J: Integer;
    begin
      J := I;
      I := 11;
    end;

    procedure B(var I: Integer);
    var
      J: Integer;
    begin
      J := I;
      I := 12; // 由于对 Var 类型的I 复制,因此无需关闭优化选项
    end;

    procedure C(const I: Integer);
    var
      J: Integer;
    begin
      J := I;
      //I := 12; // Could not compile
    end;

    procedure TForm1.btnTestVarClick(Sender: TObject);
    var
      Ka: Integer;
      Kb: Integer;
      Kc: Integer;
    begin
      Ka := 11;
      Kb := 12;
      Kc := 13;
      A(Ka);
      B(Kb);
      C(Kc);
      Log('Ka' + IntToStr(Ka));
      Log('Kb' + IntToStr(Kb));
      Log('Kc' + IntToStr(Kc));
    end;

    //Delphi局部变量的生成特点:
    //存入堆栈,Ka,Kb,Kc在堆栈中的地址方向为从高地址到低地址
    0047D084 C745F80B000000   mov [ebp-$08],$0000000b  
    0047D08B C745F40C000000   mov [ebp-$0c],$0000000c
    0047D092 C745F00D000000   mov [ebp-$10],$0000000d
    0047D099 8B45F8           mov eax,[ebp-$08]
    0047D09C E86FFFFFFF       call A
    0047D0A1 8D45F4           lea eax,[ebp-$0c]  //B Var取得是地址
    0047D0A4 E883FFFFFF       call B
    0047D0A9 8B45F0           mov eax,[ebp-$10]
    0047D0AC E89BFFFFFF       call C
    0047D0B1 8D55E4           lea edx,[ebp-$1c]

    procedure A(I: Integer);
    0047CD28 55               push ebp
    0047CD29 8BEC             mov ebp,esp
    0047CD2B 83C4F8           add esp,-$08
    0047CD2E 8945FC           mov [ebp-$04],eax  //在堆栈中开辟一空间存放形参I值
    0047CD31 8B45FC           mov eax,[ebp-$04]
    0047CD34 8945F8           mov [ebp-$08],eax
    0047CD37 C745FC0B000000   mov [ebp-$04],$0000000b
    0047CD3E 59               pop ecx
    0047CD3F 59               pop ecx
    0047CD40 5D               pop ebp
    0047CD41 C3               ret

    procedure B(var I: Integer);
    0047CD44 55               push ebp
    0047CD45 8BEC             mov ebp,esp
    0047CD47 83C4F8           add esp,-$08
    0047CD4A 8945FC           mov [ebp-$04],eax  //在堆栈中开辟一空间存放传入的地址
    0047CD4D 8B45FC           mov eax,[ebp-$04]
    0047CD50 8B00             mov eax,[eax]     //多了一次寻址
    0047CD52 8945F8           mov [ebp-$08],eax
    0047CD55 8B45FC           mov eax,[ebp-$04] //多了一次寻址
    0047CD58 C7000C000000     mov [eax],$0000000c
    0047CD5E 59               pop ecx
    0047CD5F 59               pop ecx
    0047CD60 5D               pop ebp
    0047CD61 C3               ret

    procedure C(const I: Integer);
    0047CD64 55               push ebp
    0047CD65 8BEC             mov ebp,esp
    0047CD67 83C4F8           add esp,-$08
    0047CD6A 8945FC           mov [ebp-$04],eax //在堆栈中开辟一空间存放形参I值
    0047CD6D 8B45FC           mov eax,[ebp-$04]
    0047CD70 8945F8           mov [ebp-$08],eax
    0047CD73 59               pop ecx
    0047CD74 59               pop ecx
    0047CD75 5D               pop ebp
    0047CD76 C3               ret

    说明如下
    //对整型形参而言,
    A, C的执行代码效率是比较高的,
    A比较简洁,C会增加编译器处理Const的时间
    A与C除了const外,内部执行过程没有任何不同。
    B 用于在函数内部修改外部变量的情况.

    具体如何使用呢,我想看看SysUtils.pas,StrUtils如何处理的.
    我对SysUtils,StrUtils走马观花看了一下,
    在SysUtils中,
    大部分函数的形参,如果是基本类型,比如Integer,Byte 基本上是按照A模式.
    如果形参是String,全部是B模式常量声明(没有看到没有用const的)。

    比如:
    function StrToInt(const S: string): Integer;
    function StrToIntDef(const S: string; Default: Integer): Integer;
    function TryStrToInt(const S: string; out Value: Integer): Boolean;
    function IntToStr(Value: Integer): string; overload;
    function IntToStr(Value: Int64): string; overload;
    function TrimLeft(const S: string): string; overload;
    function TrimLeft(const S: WideString): WideString; overload;

    一些特例:
    procedure ScanToNumber(const S: string; var Pos: Integer);
    function ScanChar(const S: string; var Pos: Integer; Ch: Char): Boolean;
    function StrLCat(Dest: PChar; const Source: PChar; MaxLen: Cardinal): PChar;
    function StrComp(const Str1, Str2: PChar): Integer;

    在StrUtils中,
    function ReverseString(const AText: string): string;
    function LeftStr(const AText: string; const ACount: Integer): string;
    function RightStr(const AText: string; const ACount: Integer): string;
    function MidStr(const AText: string; const AStart, ACount: Integer): string;


    System.pas中
    procedure _WStrDelete(var S: WideString; Index, Count: Integer);
    function StrPos(const Str1, Str2: PChar): PChar; assembler;
    function StrUpper(Str: PChar): PChar; assembler;
    function StrLower(Str: PChar): PChar; assembler;
    function StrPas(const Str: PChar): string;


    关于形参声明形式的个人小总结
      相信 Delphi 中的 System,SysUtils,StrUtils 中函数形参的使用,都有其用意.
      站在巨人的肩膀上,在实际开发中,声明大部分普通函数的形参的原则为:
      如果是string格式的一定要加上const,使用C模式.
      如果是基本类型如Integer,则使用A模式,什么也不加.
      如果考虑到一些特殊的需求,比如传输内存,含有字符串删除等操作, 则考虑使用var声明.

      还有许多没有解决或没有被证明的问题:
      1、为什么string最好声明为const
      2、const 的作用 等等。
      
      
    后记:
      之后,看了下 《Pascal精要》 第六章 过程与函数,觉得有些地方还是需要列出来以供参考:

    1、
    Pascal 例程的传递参数可以是值参也可以是引用参数。
    值参传递是缺省的参数传递方式:即将值参的拷贝压入栈中,例程使用、操纵的是栈中的拷贝值,不是原始值。
    当通过引用传递参数时,没有按正常方式把参数值的拷贝压栈(避免拷贝值压栈一般能加快程序执行速度),
    而是直接引用参数原始值,例程中的代码也同样访问原始值,这样就能在过程或函数中改变参数的值。

    2、
    参数引用技术在大多数编程语言中都有,C语言中虽没有,但C++中引入了该技术。
    在C++中,用符号 &表示引用;在VB中,没有ByVal 标示的参数都为引用。

    3、
    通过引用传递参数对有序类型、传统字符串类型及大型记录类型才有意义。
    实际上Delphi总是通过值来传递对象,因为Delphi对象本身就是引用。
    因此通过引用传递对象就没什么意义(除了极特殊的情况),因为这样相当于传递一个引用到另一个引用。
    Delphi 长字符串的情况略有不同,长字符串看起来象引用,但是如果你改变了该字符串的串变量,
    那么这个串在更新前将被拷贝下来。
    作为值参被传递的长字符串只在内存使用和操作速度方面才象引用,
    但是如果你改变了字符串的值,初始值将不受影响。
    相反,如果通过引用传递长字符串,那么串的初始值就可以改变。

     
    展开全文
  • 关于函数调用

    2012-09-07 16:02:50
    因为子函数调用完之后,函数的形式变量或者指针将会被清零或者释放,所以,我们利用子函数处理数据的时候,经常使用指针,通过值的地址的传递来处理数据。
  • main函数可否被递归调用 在C和C++中是不同,我们知道C语言比较宽松、灵活,而C++目标就是改变C语言比较宽松特点,实行了比较严格做法,包括严格类型检查等等。实际上,在C语言中,main函数可被...
  • 函数调用传递实参两种做法: #include<bits/stdc++.h> using namespace std; typedef struct { int *elem;//为存储空间基地址,故使用时需为其分配内存,如以下两个函数中所示,若写为elem[20]...
  • 函数的使用与变量有点像。 先声明有这个函数,再去调用这个函数,反过来就没法使用。如果采用头文件的形式,可以将函数的声明都集中到一个文件里,这样可以使得界面更加简约。
  • 同C++不同,=的赋值并不会引起copy构造函数调用,而是必须通过class InstanceA = new class(InstanceB)的形式。Java并没有初始化列表一类的东西,但是有初始化块,其定义为一个代码块,如果为非static,则在构造...
  • 同C++不同,=的赋值并不会引起copy构造函数调用,而是必须通过class InstanceA = new class(InstanceB)的形式。Java并没有初始化列表一类的东西,但是有初始化块,其定义为一个代码块,如果为非static,则在构造...
  • 关于memset函数的调用

    2015-01-05 13:01:16
    之前一直对这个函数不是很了解,今天抽空好好了解了一下这个函数的使用方法,并做了一些总结。   1.使用memset需要头文件 2.给数字数组赋初值时候,一般情况下只能赋值为0;形式:memset(数组名,0,sizeof...
  • 关于MFC库函数与调用SDK函数调用格式的问题: 比如在一个对话框的OnOk函数中,我使用了GetDlgItemText(IDC_COMBO1,str);编译运行也都通过了,通过参数形式知道,这里调用的是MFC函数。在这里该MFC函数并没写成obj....
  • 零、写在前面 上一篇博文我们谈到了结构体的参数传递问题,接下来我想继续来谈一谈函数参数的定义和传递的问题。...形式参数(parameter):不是实际存在的变量,只是在定义函数的时候使用他的形式,来描述该参数如
  • 这篇文章主要介绍了关于Python函数的深度解剖,小编觉得挺不错,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧一、函数的创建和调用定义函数,不会去执行函数;想要执行函数,需要调用函数调用函数...
  • 朱金灿 对话框DoModal()函数调用失败一般而言有两种表现形式:一是对话框弹不出来,但是没有错误提示;二是对话框弹不出来,同时伴随内存访问错误提示框出现。 第一种表现主要是因为没有对资源句柄进行切换造成...
  • 学习《C++程序设计》(第二版) 谭浩强 主编 第四章 关于函数的调用 4.4 函数的调用 4.5 函数的嵌套调用 4.6 函数的递归调用 4.4 函数的调用 ... 函数调用的一般形式 调用函数的一般形式为: ...
  • 说到编程语言就不可不提编译器,编译器以生成机器代码的形式向程序员提供了两种抽象模型:一是定义了指令格式行为及寄存器状态的ISA;二是虚拟地址空间,虽然这涉及到物理内存、内存控制器以及操作系统的软件层。...
  • 今天看jQuery时候发现书写形式原来...不理解,后来上网查了一下,原来是javascript匿名函数的调用方式 http://zhidao.baidu.com/question/95789340.htmljavascript 可以以下方式调用函数 声明a = function(){}
  • 注意 本文前部份 引自 朱金灿 的关于对话框DoModal()函数调用失败原因分析 . 地址:http://blog.csdn.net/clever101/article/details/2576968     对话框DoModal()函数调用失败一般而言有两种表现形式:一...
  • 值传递:被调用的函数的形式参数作为被调函数局部变量处理,即在堆栈中开辟了内存空间以存放由主调函数放进来的实参的值,从而成为了实参的一个副本,不会影响主调函数实参变量的值。那么为什么课本上说指针传递可以...
  • 关于二维数组的函数调用

    千次阅读 2019-09-22 12:53:44
    void change(int a[][3],int b[][2]) { for(int i=0;i<2;i++) { for(int j=0;...解释:因为任何数组传入函数都是传入数组首地址,所以不能写成(a[][])形式,数组传入方式类似于指针,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,063
精华内容 425
关键字:

关于函数调用的形式