精华内容
下载资源
问答
  • 匿名用户1级2010-12-11 回答递归(recursion)就是程序(或函数)直接调用自己或通过一系列调用语句间接调用自己,是一描述问题解决问题基本方法。递归通常用来解决结构自相似问题。所谓结构自相似,是指构成...

    匿名用户

    1级

    2010-12-11 回答

    递归(recursion)就是子程序(或函数)直接调用自己或通过一系列调用语句间接调用自己,是一种描述问题和解决问题的基本方法。

    递归通常用来解决结构自相似的问题。所谓结构自相似,是指构成原问题的子问题与原问题在结构上相似,可以用类似的方法解决。具体地,整个问题的解决,可以分为两部分:第一部分是一些特殊情况,有直接的解法;第二部分与原问题相似,但比原问题的规模小。实际上,递归是把一个不能或不好解决的大问题转化为一个或几个小问题,再把这些小问题进一步分解成更小的问题,直至每个小问题都可以直接解决。因此,递归有两个基本要素:

    (1)边界条件:确定递归到何时终止,也称为递归出口。

    (2)递归模式:大问题是如何分解为小问题的,也称为递归体。递归函数只有具备了这两个要素,才能在有限次计算后得出结果

    汉诺塔问题:对汉诺塔问题的求解,可以通过以下3个步骤实现:

    (1)将塔上的n-1个碟子借助塔C先移到塔B上;

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

    (3)将n-1个碟子从塔B借助塔A移到塔C上。

    在递归函数中,调用函数和被调用函数是同一个函数,需要注意的是递归函数的调用层次,如果把调用递归函数的主函数称为第0层,进入函数后,首次递归调用自身称为第1层调用;从第i层递归调用自身称为第i+1层。反之,退出第i+1层调用应该返回第i层。采用图示方法描述递归函数的运行轨迹,从中可较直观地了解到各调用层次及其执行情况,具体方法如下:

    (1)写出函数当前调用层执行的各语句,并用有向弧表示语句的执行次序;

    (2)对函数的每个递归调用,写出对应的函数调用,从调用处画一条有向弧指向被调用函数入口,表示调用路线,从被调用函数末尾处画一条有向弧指向调用语句的下面,表示返回路线;

    (3)在返回路线上标出本层调用所得的函数值。n=3时汉诺塔算法的运行轨迹如下图所示,有向弧上的数字表示递归调用和返回的执行顺序

    三、递归函数的内部执行过程

    一个递归函数的调用过程类似于多个函数的嵌套的调用,只不过调用函数和被调用函数是同一个函数。为了保证递归函数的正确执行,系统需设立一个工作栈。具体地说,递归调用的内部执行过程如下:

    (1)运动开始时,首先为递归调用建立一个工作栈,其结构包括值参、局部变量和返回地址;

    (2)每次执行递归调用之前,把递归函数的值参和局部变量的当前值以及调用后的返回地址压栈;

    (3)每次递归调用结束后,将栈顶元素出栈,使相应的值参和局部变量恢复为调用前的值,然后转向返回地址指定的位置继续执行。

    上述汉诺塔算法执行过程中,工作栈的变化如下图所示,其中栈元素的结构为(返回地址,n值,A值,B值,C值),返回地址对应算法中语句的行号,分图的序号对应图中递归调用和返回的序号

    我可以帮助你,你先设置我最佳答案后,我百度Hii教你。

    展开全文
  • C语言函数

    2021-06-14 15:36:10
    虽然C中的函数和其他语言中的函数程序、过程作用相同,但是细节上略不同。一些函数执行某些动作,如printf()把数据打印到屏幕上;一些函数找出一个值供程序使用,如 strlen()把指定字符串长度返回给程序。...

    什么是函数﹖函数是完成特定任务的独立程序代码单元。语法规则定义了函数的结构和使用方式。虽然C中的函数和其他语言中的函数、子程序、过程作用相同,但是细节上略有不同。一些函数执行某些动作,如printf()把数据打印到屏幕上;一些函数找出一个值供程序使用,如 strlen()把指定字符串的长度返回给程序。一般而言,函数可以同时具备以上两种功能。

    为什么要使用函数?首先,使用函数可以省去编写重复代码的苦差。如果程序要多次完成某项任务,那么只需编写一个合适的函数,就可以在需要时使用这个函数,或者在不同的程序中使用该函数,就像许多程序中使用putchar ()一样。其次,即使程序只完成某项任务一次,也值得使用函数。因为函数让程序更加模块化,从而提高了程序代码的可读性,更方便后期修改、完善。

    如何了解函数?首先要知道如何正确地定义函数、如何调用函数和如何建立函数间的通信。

     

    创建一个再一行打印40个星号的函数,并在一个打印表头的程序中使用该函数。

    编译运行:

     

    分析程序:

    (1)程序在3处使用了starbar标识符:函数原型告诉编译器函数starbar()的类型;函数调用表明在此处执行函数;函数定义明确地指出定了函数要做什么。

    (2)函数和变量一样,有多种类型。任何程序在使用函数之前都要声明该函数得类型。因此,在main()函数定义的前面出现了下面的ANSI C风格的函数原型:

    void starbar(void);

    圆括号表明starbar是一个函数名。第一个void是函数类型,void类型表明函数没有返回值。第二个void(在圆括号中)表明该函数不带参数。分号表明这是在声明函数,不是定义函数。也就是说,着行声明了程序将使用一个名为starbar()、没有返回值、没有参数的函数,并告诉编译器在别处查找该函数的定义。

    (3)一般而言,函数原型指明了函数的返回值类型和函数接受的参数类型。这些信息称为该函数的签名。对于starbar()函数而言,其签名是该函数没有返回值,没有参数。

    (4)程序把starbar()原型置于main()的前面。也可以放在main()里面的声明变量处。放在哪个位置都行。

    (5)在main()中,执行到下面的语句时调用了starbar()函数:

    starbar();

    这是调用void类型函数的一种形式。当计算机执行到starbar();语句时,会找到该函数的定义并执行其中的内容。执行完starbar()中的代码后,计算机返回主调函数继续执行下一行(本例中,主调函数是main())。

    (6)程序中starbar()和main()的定义形式相同。首先函数头包括函数类型、函数名和圆括号,接着是左花括号、变量声明、函数表达式语句,最后以右花括号结束。注意,函数头中的starbar()后面没有分号,告诉编译器这是定义starbar(),而不是调用函数或声明函数原型。

    (7)程序把starbar()和main()放在一个文件中。也可以把它们分别放在两个文件中。把函数都放在一个文件中的单文件形式比较容易编译,而使用多个文件方便在不同的程序中使用同一个函数。如果把函数放在一个单独的文件中,要把#define和#include指令也放入该文件。现在,先把所有函数都放在一个文件中。main()的右花括号告诉编译器该函数结束的位置,后面的starbar()函数头告诉编译器starbar()是一个函数。

    (8)starbar()函数中的变量count是局部变量,意思是该变量只属于starbar()函数。可以在程序中的其他地方(包括main()中)使用count,这不会引起名称冲突,他们是同名的不同变量。

     

    要是再刚刚的程序中,文字能居中,那么打印出来就会更加美观。所以可以在打印文字之前打印一定数量的空格来实现,这和打印一定数量的星好(starbar()函数)类似,只不过现在要打印的是一定数量的空格。因此我们设计一个新的函数show_n_char()(显示一个字符n次)。唯一要改变的是使用内置的值来显示字符和重复次数,show_n_char()将使用函数参数来传递这些值。

    因此来具体分析。假设可用的空间是40个字符宽。调用show_n_char(‘*’,40)应该正好打印一行40个星号,就像starbar()之前做的那样。第2行GIGATHINK,INT.的空格怎么处理?GIGATHINK,INT.是15个字符宽,所以第1个版本中,文字后面有25个空格。为了让文字居中,文字的左侧应该有12个,右侧有13个空格。因此,可以调用show_n_char(‘*’,12)。

    show_n_char()与starbar()很相似,但是show_n_char()带有参数。从功能上看,前者不会添加换行符,而后者会,因为show_n_char()要把空格和文本打印成一行。因此就有如下的程序:

    编译运行:

    函数定义从函数头开始:

    void show_n_char(char ch,int num)

    该行告知编译器show_n_char()使用两个参数ch和num,ch是char类型,num是int类型。这两个变量被称为形式参数,简称形参。和定义在函数中变量一样,形式参数也是局部变量,属该函数私有。这意味着在其他函数中使用同名变量不会引起名称冲突。每次调用函数,就会给这些变量赋值。

    在ANSI C 中要求在每个变量前都声明其类型。也就是说,不能像普通变量声明那样使用同一类型的变量列表:

    void dubs(int x,int y,int z)

    虽然show_n_char()接受来自main()的值,但是它没有返回值。因此,show_n_char()的类型是void。

     

    使用函数:

    在使用函数之前,要用ANSI C形式声明函数原型:

    void show_n_char(char ch,int num);

    当函数接受参数时,函数原型用逗号分隔的列表指明参数的数量和类型。

     

    在函数调用中,实际参数提供了ch和num的值。在上面的程序中第一次调用show_n_char():

    Show_n_char(SPACE,12);

    实际参数是空格字符和12。这两个值给赋给show_n_char()中相应的形式参数:变量ch和num。形式参数是被调函数中的变量,实际参数是主调函数赋给被调函数的具体值。如上例所示,实际参数可以是常量、变量,或甚至是更复杂的表达式。无论实际参数是何种形式都要被求值,然后该值被拷贝给被调函数相应的形式参数。以上面程序中最后一次调用show_n_char()为例:

    show_n_char(SPACE,(WIDTH-strlen(PLACE))/2);

    构成该函数第2个实际参数的是一个很长的表达式,对该表达式求值为10。然后,10被赋给变量num。被调函数不知道也不关心传入的数值是来自常量、变量还是一般表达式。再次强调,实际参数是具体的值,该值要被赋给作为形式参数的变量。因为被调函数使用的值是从主调函数中拷贝而来,所以无论被调函数对拷贝数据进行什么操作,都不会影响主调函数中的原始数据。

     

    实际参数和形式参数:实际参数是出现在函数调用圆括号中的表达式。形式参数是函数定义的函数头中声明的变量。调用函数时,创建了声明为形式参数的变量并初始化为实际参数的求值结果。在上面程序中, '*'和WIDTH都是第1次调用show_n_char()时的实际参数,而SPACE和11是第2次调用show_n_char()时的实际参数。在函数定义中,ch和num都是该函数的形式参数。

     

     

    使用return从函数中返回值:函数的返回值可以把信息从被调函数传回主调函数。为了进一步说明,我们将创建一个返回两个参数中较小值的函数。由于函数被设计用来处理int类型的值,所以被命名为imin()。另外,还要创建一个简单的main(),用来检查imin()是否正常工作。这种被设计用于测试函数的程序有时被称为驱动程序,该驱动程序调用一个函数。

     

    编译运行:

     

    关键字return后面的表达式的值就是函数的返回值。在该例中,该函数返回的值就是变量min的值。因为min是int类型的变量,所以imin()函数的类型也是int。

    变量min属于imin()函数私有,但是return语句把min的值传回了主调函数。下面这条语句的作用是把min的值赋给lesser:

    lesser = imin(n,m);

    是否能写成这样呢:

    imin(n,m );

    lesser = min;

    不能。因为主调函数甚至不知道min的存在。Imin()中的变量是imin()的局部变量。函数调用imin(evil1,evil2)只是把两个变量的值拷贝了一份。

    返回值不仅可以赋给变量,也可以被用作表达式的一部分。例如:

    answer = 2*imin(z,zstar)+25;

    printf(“%d\n”,imin(-32+answer,LIMIT));

    返回值不一定是变量的值,也可以是任意表达式的值。例如:

    imin(int n,int m)

    {

           return(n<m)?n:m;

    }

    条件表达式的值如果是n和m中的较小者,该值要被返回给主调函数。

    使用return语句的另一个作用是,终止函数并把控制返回给主调函数的下一条语句。也可以这么编写imin():

    imin(int n,int m)

    {

        If(n < m)

               return n;

        else

               return m;

    }

     

    函数类型:声明函数时必须声明函数的类型。带返回值的函数类型应该与其返回值类型相同,而没有返回值的函数应声明为void类型。类型声明是函数定义的一部分。要记住,函数类型指的是返回值的类型,不是函数参数的类型。例如,下面的函数头定义了一个带两个int类型参数的函数,但是其返回值是double类型。

    double klink(int a,int b)

     

    如何正确使用函数:程序在第一次使用函数之前必须知道函数的类型。方法之一是,把完成的函数定义放在第一次调用函数的前面,通常的做法是提前声明函数,把函数的信息告知编译器。

     

    递归:C允许函数调用它自己,这种调用过程称为递归。递归有时难以捉摸,有时却很方便实用。结束递归是使用递归的难点,因为如果递归代码中没有终止递归的条件测试部分,一个调用自己的函数会无限递归。

    可以使用循环的地方通常都可以使用递归。有时用循环解决问题比较好,但有时用递归更好。递归方案更简洁,但效率却没有循环高。

    递归演示:

    main()函数调用up_and_down()函数,这次调用称为“第1级递归”。然后up_and_down()调用自己,这次调用称为“第2级递归”。接着第2级递归调用第3级递归,共有4级递归。

     

    编译运行:

     

    分析一下递归是如何工作的。首先main()调用了带参数1的up_and_down()函数,执行结果是up_and_down()中的形式参数n的值是1,所以打印语句#1打印Level 1。然后由于n小于4,up_and_down()调用实际参数为n+1的up_and_down()。于是第2级调用中的n的值是2,打印语句#1打印Level 2。同样的方法打印Level 3和Level 4。当执行到第4级时,n的值是4,所以if测试为假。up_and_down()函数不在调用自己。第4级调用接着执行打印语句#2,即打印LEVEL 4,因为n的值是4。此时,第4级调用结束,控制被传回它的主调函数(即第3级调用)。在第3级调用中,执行的最后一条语句是调用if语句中的第4级调用。被调函数(第4级调用)把控制返回在这个位置,因此,第3级调用继续执行后面的代码,打印语句#2打印LEVEL 3。然后第3级调用结束,控制被传回第2级调用,接着打印LEVEL 2,以此类推。

     

    展开全文
  • 第八回合:函数 函数函数是包含一条或多条C语言的语句,完成程序中的部分功能的子程序。C源程序是由函数组成的。 A: 函数的分类 ...(二) C语言的函数其他语言中的函数和过程两种功能: (a)

    第八回合:函数

    函数:函数是包含一条或多条C语言的语句,完成程序中的部分功能的子程序。C源程序是由函数组成的。

    A: 函数的分类

    (一)  从函数的定义角度看:

    (a)      库函数:由C系统提供,无需定义,如:printf,scanf,putchar…

    (b)      用户定义函数:由用户定义的函数

    (二)  C语言的函数兼有其他语言中的函数和过程两种功能:

    (a)      有返回值的函数:此函数执行完任务后,向调用者返回函数值

    (b)      无返回值的函数:此函数完成任务后,不会向调用者返回函数值

    (三)  从主调函数和被调函数之间数据的传输:

    (a)      有参函数:(即带参函数)在函数定义和声明时都有参数

    (b)      无参函数:函数定义、函数说明及函数调用均都不带参数

     

    B: 函数的定义

    (一)   无参函数的定义形式

    类型标识符函数名()      //括号内没有参数

    {

      函数语句体;

      return (表达式); //==  return表达式; 没返回值时,此语句不要。

    }

    (二)   有参函数的定义形式:

    类型标志符函数名(参数列表){

    函数体语句;

    return(表达式);//有返回值时,此句存在。没返回值=时,此语句不要。

    }

      C形式参数和实际参数

    (一)   形式参数(即形参):形参出现在函数的定义中,整个函数都可以使用。

    (二)   实际参数(即实参):实参出现在主函数中,进入被调函数后,实参就不能使用了。

    PS:发生函数调用时,主函数把实参的值传送给被调用函数的形参从而实现主调函数向被调函数传送数据。

      特点:

    (a)      形参变量只有在被调用时才分配内存单元,结束后就会释放。所以形参的作用范围只有在函数内有效。

    (b)      实参可以是常量、变量、表达式、函数等,无论实参是哪种类型,在进行函数调用时,他们必须有具体的值。

    (c)      实参和形参在数量上、类型上、顺序上应严格一致,否则会发生“类型不配”的错误

    (d)      函数调用中的数据传送时单向的。即只能把实参的值传送给形参,而不是把形参的值方向地传送给实参。因此在函数调用过程中,形参的值发生改变,而实参中的值不会变化。


    (复习做的笔记,还在整理中。。。。)

    展开全文
  • 2. C语言的函数兼其它语言中的函数和过程两种功能,从这个角度看,又可把函数分为返回值函数无返回值函数两种。 (1)返回值函数  此类函数被调用执行完后将向调用者返回一个执行结果, 称为函数返回值。如...
  • 使用C语言开发Oracle应用程序通常有两种方法。一是利用嵌入式SQL语言,将SQL作为语言嵌入到C语言中,借助C语言访问Oracle以及实现过程化控制复杂计算。二是利用Oracle调用接口(Oracle Call Interface简称OCI),...

        使用C语言开发Oracle应用程序通常有两种方法。一是利用嵌入式SQL语言,将SQL作为子语言嵌入到C语言中,借助C语言访问Oracle以及实现过程化控制和复杂计算。二是利用Oracle调用接口(Oracle Call Interface简称OCI),通过调用一系列OCI函数即可访问数据库。我在这里介绍的是前一种方法。另外,在本文中,我重点介绍的是利用C语言开发Oracle应用程序的流程和步骤,而对嵌入式SQL的语法不会过多介绍,如果想了解详细语法,我在这里可以推荐一本书,书名是《Oracle 11g Pro*C\C++编程艺术》,此书对Oracle嵌入式SQL有详细详解,非常适合做新手入门教材,电子版在网上有,请需要的读者自行查找,

    一、工具

        Oracle 11g、vs2017、win10

    二、概述

        要用C语言开发Oracle应用程序,首先编写包含嵌有SQL语言的C语言的源代码,后缀名为pc,然后将代码通过Oracle自带的预编译工具Proc将SQL语句转为对Oracle运行库函数(SQLLIB)的调用,预编译后的代码即为C语言源代码,再将预编译后的代码拷到vs中,经过vs编译、链接和运行后,相应的Oracle应用程序即开发完成。过程如下图所示。

                                                                     

     

    三、详细步骤

    1.编写pc源文件。注意,编码格式应为ANSI编码,如果使用其他编码,可能会报错。例如,我使用UTF-8编码,会报如下图所示错误。

                                                                  

     

        示例源代码test.pc如下所示。此代码的功能是查询表STUDENT中学号为2005的学生的学生姓名。

    #include <stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<sqlca.h>
    
    //我最后用C++编译器编译此文件,不加“extern "C"”会报错
    //如报错:无法解析的外部符号
    extern "C" unsigned int sqlgls(char *, size_t *, size_t *);
    
    //连接数据库
    void connect()
    {
    	EXEC SQL BEGIN DECLARE SECTION;
    	char username[20], password[20];
    	EXEC SQL END DECLARE SECTION;
    
    	strcpy_s(username, strlen("scott") + 1, "scott");
    	strcpy_s(password, strlen("tiger") + 1, "tiger");
    	EXEC SQL CONNECT : username IDENTIFIED BY : password;
    }
    
    //断开连接,提交事务
    void release()
    {
    	EXEC SQL COMMIT RELEASE;
    }
    
    //错误处理函数,当访问数据库出错时,会中止程序执行,打印错误信息
    void sql_error()
    {
    	char stm[100];
    	size_t sqlfc, stmlen = 100;
    	unsigned int i;
    	i = sqlgls(stm, &stmlen, &sqlfc);
    	printf("出错语句为:%.*s\n", stmlen, stm);
    	printf("%.*s\n", sqlca.sqlerrm.sqlerrml, sqlca.sqlerrm.sqlerrmc);
    	system("PAUSE");
    	exit(1);
    }
    
    int main()
    {
    
        //主变量说明
    	EXEC SQL BEGIN DECLARE SECTION;
    	char name[9];
    	int sno;
    	EXEC SQL END DECLARE SECTION;
    	
    	//错误处理
    	EXEC SQL WHENEVER NOT FOUND DO sql_error();
    	EXEC SQL WHENEVER SQLERROR DO sql_error();
    	EXEC SQL WHENEVER SQLWARNING DO sql_error();
    	
        connect();
    	
    	sno=2005;
    	
    	EXEC SQL SELECT SNAME INTO :name
    	FROM STUDENT
    	WHERE SNO=:sno;
    	
    	printf("学号为2005的学生是%s\n",name);
    	
    	release();
    	
    	system("PAUSE");
    	return 0;
    }

    2、预编译pc源程序。在命令行中输入命令proc,再加上一些预编译选项即可。常用预编译选项有INAME,INCLUDE,CODE,PARSE,CHAR_MAP等。INAME指定要预编译的文件名,当该选项是命令行第一个选项时,可省略“INAME=”。INCLUDE选项用于指定#include或EXEC SQL INCLUDE所对应的头文件所在路径。CODE选项用于指定预编译器所生成的C函数原型格式,可为ANSI_C,KR_C或CPP。PARSE指定解析pc源文件的方法,PARSE=FULL时,使用C解析器解析;PARSE=NONE或PARTICAL时,使用C++解析器解析,此时必须在定义部分内定义宿主变量和结构(如果不在定义部分内定义结构,当宿主变量是自定义结构时,将无法识别结构名)。CHAR_MAP用于指定char[n]与Oracle外部数据类型的映射关系,它有CHARZ,STRING,VARCHAR2,CHARF四种值,当CHAR_MAP=CHARZ时,字符宿主变量为用空格填充、以null('\0')终止的定长字符串;当CHAR_MAP=STRING时,字符宿主变量为以null终止的变长字符串;当CHAR_MAP=VARCHAR2时,字符宿主变量为以空格填充的定长字符串(包括null);当CHAR_MAP=CHARF时,字符数组变量为以空格填充的定长字符串。若想知道更多预编译选项的介绍,可查看《Oracle 11g Pro*C\C++编程艺术》的附录A。

        直接在命令行中指定预编译选项有时候会很麻烦,因为预编译选项有很多,一个个指定太过繁琐。所以,除了在命令行中指定预编译选项,也可在系统配置文件pcscfg.cfg(在%SRCHOME%/precomp/admin目录中)中配置一些常用的、相对固定的预编译选项。当进行预编译时,proc会自动加载此配置文件。pcscfg.cfg配置示例如下。“include=F:\test\include”为程序中所用到的C语言标准库所在的文件目录(我试过用vs中C语言标准库所在的文件目录或Dev-C++中C语言标准库所在目录作为此目录,但都在预编译过程中报错,最终,我下载了vc,将vc中C语言的标准库文件拷入F:\test\include中,才得以预编译成功)。

    include=%SRCHOME%/precomp/public
    include=F:\test\include
    CHAR_MAP=STRING
    CODE=CPP
    PARSE=NONE

     

        示例命令行命令如下:

    proc F:\test\test.pc

       预编译pc源代码test.pc后,将生成test.cpp文件,其内容如下。

    
    /* Result Sets Interface */
    #ifndef SQL_CRSR
    #  define SQL_CRSR
      struct sql_cursor
      {
        unsigned int curocn;
        void *ptr1;
        void *ptr2;
        unsigned int magic;
      };
      typedef struct sql_cursor sql_cursor;
      typedef struct sql_cursor SQL_CURSOR;
    #endif /* SQL_CRSR */
    
    /* Thread Safety */
    typedef void * sql_context;
    typedef void * SQL_CONTEXT;
    
    /* Object support */
    struct sqltvn
    {
      unsigned char *tvnvsn; 
      unsigned short tvnvsnl; 
      unsigned char *tvnnm;
      unsigned short tvnnml; 
      unsigned char *tvnsnm;
      unsigned short tvnsnml;
    };
    typedef struct sqltvn sqltvn;
    
    struct sqladts
    {
      unsigned int adtvsn; 
      unsigned short adtmode; 
      unsigned short adtnum;  
      sqltvn adttvn[1];       
    };
    typedef struct sqladts sqladts;
    
    static struct sqladts sqladt = {
      1,1,0,
    };
    
    /* Binding to PL/SQL Records */
    struct sqltdss
    {
      unsigned int tdsvsn; 
      unsigned short tdsnum; 
      unsigned char *tdsval[1]; 
    };
    typedef struct sqltdss sqltdss;
    static struct sqltdss sqltds =
    {
      1,
      0,
    };
    
    /* File name & Package Name */
    struct sqlcxp
    {
      unsigned short fillen;
               char  filnam[16];
    };
    static const struct sqlcxp sqlfpn =
    {
        15,
        "F:\\test\\test.pc"
    };
    
    
    static unsigned int sqlctx = 2327307;
    
    
    static struct sqlexd {
       unsigned int   sqlvsn;
       unsigned int   arrsiz;
       unsigned int   iters;
       unsigned int   offset;
       unsigned short selerr;
       unsigned short sqlety;
       unsigned int   occurs;
          const short *cud;
       unsigned char  *sqlest;
          const char  *stmt;
       sqladts *sqladtp;
       sqltdss *sqltdsp;
                void  **sqphsv;
       unsigned int   *sqphsl;
                int   *sqphss;
                void  **sqpind;
                int   *sqpins;
       unsigned int   *sqparm;
       unsigned int   **sqparc;
       unsigned short  *sqpadto;
       unsigned short  *sqptdso;
       unsigned int   sqlcmax;
       unsigned int   sqlcmin;
       unsigned int   sqlcincr;
       unsigned int   sqlctimeout;
       unsigned int   sqlcnowait;
                  int   sqfoff;
       unsigned int   sqcmod;
       unsigned int   sqfmod;
                void  *sqhstv[4];
       unsigned int   sqhstl[4];
                int   sqhsts[4];
                void  *sqindv[4];
                int   sqinds[4];
       unsigned int   sqharm[4];
       unsigned int   *sqharc[4];
       unsigned short  sqadto[4];
       unsigned short  sqtdso[4];
    } sqlstm = {12,4};
    
    // Prototypes
    extern "C" {
      void sqlcxt (void **, unsigned int *,
                   struct sqlexd *, const struct sqlcxp *);
      void sqlcx2t(void **, unsigned int *,
                   struct sqlexd *, const struct sqlcxp *);
      void sqlbuft(void **, char *);
      void sqlgs2t(void **, char *);
      void sqlorat(void **, unsigned int *, void *);
    }
    
    // Forms Interface
    static const int IAPSUCC = 0;
    static const int IAPFAIL = 1403;
    static const int IAPFTL  = 535;
    extern "C" { void sqliem(unsigned char *, signed int *); }
    
    typedef struct { unsigned short len; unsigned char arr[1]; } VARCHAR;
    typedef struct { unsigned short len; unsigned char arr[1]; } varchar;
    
    /* cud (compilation unit data) array */
    static const short sqlcud0[] =
    {12,4130,852,0,0,
    5,0,0,0,0,0,27,19,0,0,4,4,0,1,0,1,5,0,0,1,5,0,0,1,10,0,0,1,10,0,0,
    36,0,0,2,0,0,30,25,0,0,0,0,0,1,0,
    51,0,0,3,49,0,4,59,0,0,2,1,0,1,0,2,5,0,0,1,3,0,0,
    };
    
    
    #include <stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<sqlca.h>
    
    //我最后用C++编译器编译此文件,不加“extern "C"”会报错
    //如报错:无法解析的外部符号
    extern "C" unsigned int sqlgls(char *, size_t *, size_t *);
    
    //连接数据库
    void connect()
    {
    	/* EXEC SQL BEGIN DECLARE SECTION; */ 
    
    	char username[20], password[20];
    	/* EXEC SQL END DECLARE SECTION; */ 
    
    
    	strcpy_s(username, strlen("scott") + 1, "scott");
    	strcpy_s(password, strlen("tiger") + 1, "tiger");
    	/* EXEC SQL CONNECT : username IDENTIFIED BY : password; */ 
    
    {
     struct sqlexd sqlstm;
     sqlstm.sqlvsn = 12;
     sqlstm.arrsiz = 4;
     sqlstm.sqladtp = &sqladt;
     sqlstm.sqltdsp = &sqltds;
     sqlstm.iters = (unsigned int  )10;
     sqlstm.offset = (unsigned int  )5;
     sqlstm.cud = sqlcud0;
     sqlstm.sqlest = (unsigned char  *)&sqlca;
     sqlstm.sqlety = (unsigned short)4352;
     sqlstm.occurs = (unsigned int  )0;
     sqlstm.sqhstv[0] = (         void  *)username;
     sqlstm.sqhstl[0] = (unsigned int  )20;
     sqlstm.sqhsts[0] = (         int  )20;
     sqlstm.sqindv[0] = (         void  *)0;
     sqlstm.sqinds[0] = (         int  )0;
     sqlstm.sqharm[0] = (unsigned int  )0;
     sqlstm.sqadto[0] = (unsigned short )0;
     sqlstm.sqtdso[0] = (unsigned short )0;
     sqlstm.sqhstv[1] = (         void  *)password;
     sqlstm.sqhstl[1] = (unsigned int  )20;
     sqlstm.sqhsts[1] = (         int  )20;
     sqlstm.sqindv[1] = (         void  *)0;
     sqlstm.sqinds[1] = (         int  )0;
     sqlstm.sqharm[1] = (unsigned int  )0;
     sqlstm.sqadto[1] = (unsigned short )0;
     sqlstm.sqtdso[1] = (unsigned short )0;
     sqlstm.sqphsv = sqlstm.sqhstv;
     sqlstm.sqphsl = sqlstm.sqhstl;
     sqlstm.sqphss = sqlstm.sqhsts;
     sqlstm.sqpind = sqlstm.sqindv;
     sqlstm.sqpins = sqlstm.sqinds;
     sqlstm.sqparm = sqlstm.sqharm;
     sqlstm.sqparc = sqlstm.sqharc;
     sqlstm.sqpadto = sqlstm.sqadto;
     sqlstm.sqptdso = sqlstm.sqtdso;
     sqlstm.sqlcmax = (unsigned int )100;
     sqlstm.sqlcmin = (unsigned int )2;
     sqlstm.sqlcincr = (unsigned int )1;
     sqlstm.sqlctimeout = (unsigned int )0;
     sqlstm.sqlcnowait = (unsigned int )0;
     sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
    }
    
    
    }
    
    //断开连接,提交事务
    void release()
    {
    	/* EXEC SQL COMMIT RELEASE; */ 
    
    {
     struct sqlexd sqlstm;
     sqlstm.sqlvsn = 12;
     sqlstm.arrsiz = 4;
     sqlstm.sqladtp = &sqladt;
     sqlstm.sqltdsp = &sqltds;
     sqlstm.iters = (unsigned int  )1;
     sqlstm.offset = (unsigned int  )36;
     sqlstm.cud = sqlcud0;
     sqlstm.sqlest = (unsigned char  *)&sqlca;
     sqlstm.sqlety = (unsigned short)4352;
     sqlstm.occurs = (unsigned int  )0;
     sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
    }
    
    
    }
    
    //错误处理函数,当访问数据库出错时,会中止程序执行,打印错误信息
    void sql_error()
    {
    	char stm[100];
    	size_t sqlfc, stmlen = 100;
    	unsigned int i;
    	i = sqlgls(stm, &stmlen, &sqlfc);
    	printf("出错语句为:%.*s\n", stmlen, stm);
    	printf("%.*s\n", sqlca.sqlerrm.sqlerrml, sqlca.sqlerrm.sqlerrmc);
    	system("PAUSE");
    	exit(1);
    }
    
    int main()
    {
    
        //主变量说明
    	/* EXEC SQL BEGIN DECLARE SECTION; */ 
    
    	char name[9];
    	int sno;
    	/* EXEC SQL END DECLARE SECTION; */ 
    
    	
    	//错误处理
    	/* EXEC SQL WHENEVER NOT FOUND DO sql_error(); */ 
    
    	/* EXEC SQL WHENEVER SQLERROR DO sql_error(); */ 
    
    	/* EXEC SQL WHENEVER SQLWARNING DO sql_error(); */ 
    
    	
        connect();
    	
    	sno=2005;
    	
    	/* EXEC SQL SELECT SNAME INTO :name
    	FROM STUDENT
    	WHERE SNO=:sno; */ 
    
    {
     struct sqlexd sqlstm;
     sqlstm.sqlvsn = 12;
     sqlstm.arrsiz = 4;
     sqlstm.sqladtp = &sqladt;
     sqlstm.sqltdsp = &sqltds;
     sqlstm.stmt = "select SNAME into :b0  from STUDENT where SNO=:b1";
     sqlstm.iters = (unsigned int  )1;
     sqlstm.offset = (unsigned int  )51;
     sqlstm.selerr = (unsigned short)1;
     sqlstm.cud = sqlcud0;
     sqlstm.sqlest = (unsigned char  *)&sqlca;
     sqlstm.sqlety = (unsigned short)4352;
     sqlstm.occurs = (unsigned int  )0;
     sqlstm.sqhstv[0] = (         void  *)name;
     sqlstm.sqhstl[0] = (unsigned int  )9;
     sqlstm.sqhsts[0] = (         int  )0;
     sqlstm.sqindv[0] = (         void  *)0;
     sqlstm.sqinds[0] = (         int  )0;
     sqlstm.sqharm[0] = (unsigned int  )0;
     sqlstm.sqadto[0] = (unsigned short )0;
     sqlstm.sqtdso[0] = (unsigned short )0;
     sqlstm.sqhstv[1] = (         void  *)&sno;
     sqlstm.sqhstl[1] = (unsigned int  )sizeof(int);
     sqlstm.sqhsts[1] = (         int  )0;
     sqlstm.sqindv[1] = (         void  *)0;
     sqlstm.sqinds[1] = (         int  )0;
     sqlstm.sqharm[1] = (unsigned int  )0;
     sqlstm.sqadto[1] = (unsigned short )0;
     sqlstm.sqtdso[1] = (unsigned short )0;
     sqlstm.sqphsv = sqlstm.sqhstv;
     sqlstm.sqphsl = sqlstm.sqhstl;
     sqlstm.sqphss = sqlstm.sqhsts;
     sqlstm.sqpind = sqlstm.sqindv;
     sqlstm.sqpins = sqlstm.sqinds;
     sqlstm.sqparm = sqlstm.sqharm;
     sqlstm.sqparc = sqlstm.sqharc;
     sqlstm.sqpadto = sqlstm.sqadto;
     sqlstm.sqptdso = sqlstm.sqtdso;
     sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
     if (sqlca.sqlcode == 1403) sql_error();
     if (sqlca.sqlcode < 0) sql_error();
     if (sqlca.sqlwarn[0] == 'W') sql_error();
    }
    
    
    	
    	printf("学号为2005的学生是%s\n",name);
    	
    	system("PAUSE");
    	return 0;
    }

    3、编译C语言源代码,生成可执行文件。首先,要新建一个项目,将C语言源代码导入进去。然后要配置项目属性,点击项目->Project属性,进入Project属性页界面,点击配置属性->VC++ 目录,向包含目录中加入sqlca.h头文件所在目录,我电脑中此目录是D:\oracle\product\11.2.0\dbhome_1\precomp\public,向库目录中加入Oracle运行库(SQLLIB)所在目录,其中Oracle 11g 的运行库名称是orasql11.lib,我电脑中此目录是D:\oracle\product\11.2.0\dbhome_1\precomp\LIB。点击链接->输入,在附加依赖项中加入orasql11.lib。然后点击确定。解决方案配置要一致,所以我将Debug×86改为Debug×64。最后点击生成解决方案即可生成可执行文件。操作过程如图所示。

                                                                                                     新建项目

     

                                                                                                         导入test.cpp

     

                                                                           点击项目->Project 属性

     

                                                                     点击配置属性->VC++ 目录

                                                                                  添加头文件目录

     

                                                                                   添加库文件目录

     

                                                                                                      添加库文件

     

                                                                 

                                                                                                   选择解决方案平台

     

    4、运行结果。如下图所示。

                                                      

     

         能力有限,如有错误之处,还望海涵!

     

    展开全文
  • c语言编写单片机技巧

    2009-04-19 12:15:17
    答: MCU从生产出来到封装出货每个不同阶段会不同测试方法,其中主要会有两种:中测和成测。 所谓中测即是WAFER测试,它会包含产品功能验证及AC、DC测试。项目相当繁多,以HOLTEK-p....
  • 8.1.2 变量作用域和函数 297 8.2 函数 297 8.2.1 定义函数 298 8.2.2 return语句 301 8.3 按值传递机制 304 8.4 函数声明 305 8.5 指针用作参数和返回值 307 8.5.1 常量参数 310 8.5.2 从函数中返回指针...
  • 8.1.2 堆栈和函数调用 258 8.1.3 堆栈和袖珍计算器 259 8.2 定义堆栈ADT 259 8.2.1 定义堆栈抽象类型 260 8.2.2 不透明类型 261 8.2.3 定义stack.h接口 262 8.3 在应用程序中使用堆栈 265 8.4 实现堆栈...
  • 第二部分是高级主题,包括面向对象语言和函数语言、垃圾收集、循环优化、SSA(静态单赋值)形式、循环调度、存储结构优化等,适合于后续课程或研究生教学。书中专门为学生提供了一个用C语言编写实习项目,包括前端和...
  • 图示窗口显示广义表存储结构建立过程和算法执行过程中参数Sub当前值。 16. 遍历二叉树 图示窗口显示二叉树逻辑结构和遍历结果输出结点序列,图中指针 bt 指向当前遍历二叉树根结点。 17. 线索二叉树 ...
  • 17.3使用数据流分析结果 转换 17.3.1公共表达式删除 17.3.2常数传播 17.3.3复写传播 17.3.4死代码删除 17.4加快数据流分析 17.4.1位向量 17.4.2基本块 17.4.3结点排序 17.4.4使用一定值链和定值一...
  • 现代编译原理C语言描述-虎书中文版

    热门讨论 2010-04-11 16:47:52
    17.3 使用数据流分析结果转换 274 17.3.1 公共表达式删除 274 17.3.2 常数传播 275 17.3.3 复写传播 275 17.3.4 死代码删除 275 17.4 加快数据流分析 276 17.4.1 位向量 276 17.4.2 基本块 ...
  • Adams需要通过调用动态库的形式,来实现子程序的调用,支持C语言和Fortran 两种语言。以Visual Studio 2017 &Adams 2018 为例,需要注意的是: 1、ADAMS/oSvler以动态链接库(dll)的方式调用用户编制的子程序。...
  • C语言中在子函数,括号中传递是形参(意味着将该参数复制然后带入到函数中进行操作)本质上是无法改变实参值。所以有两种方法可以改变实参。 (1)return 将子函数中操作后结果带出。 (2)传地址 传递地址...
  • 文章标题

    2017-11-22 17:13:51
    虽然C中的函数和其他语言中的函数程序、过程作用相同,但是细节上略不同。一些函数执行某些动作,如printf()把数据打印到屏幕上;一些函数找出一些值供程序使用,如strlen()把指定字符串长度返回给程序...
  • 如果想要强行转换变量类型,可以使用与C语言相同的函数settype()。 2.5 变量与常量 可能你已经注意到,变量都一个美元符号($)前缀。所有变量都是局部变量,为了使得定义的函数中可以使用外部变量,使用...
  • 本书是作者结合教学科研实践经验编写而成,不仅详细介绍了Windows内核原理,而且介绍了编程技巧应用实例,兼顾了在校研究生工程技术人员实际需求,对教学、生产科研现实指导意义,是一本值得推荐...
  • c++ 程序设计

    2019-01-20 22:53:37
    C++上机操作,这部分介绍了在两种典型环境下运行C++程序方法,即Visual C++6.0GCC在DOS/Windows平台上版本DJGPP(以及与之配合使用集成软件开发环境RHIDE);上机实验内容与安排,这部分提出了上机实验...
  • 9.4.1 数据库存储过程和函数 214 9.4.2 SQL/PSM: 扩展SQL以指定持久存储模块 215 9.5 小结 216 复习题 216 练习题 216 实验题 217 选读文献 218 第三部分 数据库设计理论和方法学 219 第10章 ...
  • windows 程序设计

    2011-07-24 21:16:30
    但大多数情况下,您应非常熟悉该语言,特别是C语言的结构指针。了解标准C语言执行期链接库的一些相关知识是帮助的,但不是必要的。 第三,您应该在机器上安装一个适于进行Windows程序设计的32位C语言编译器...
  • Tcl_TK编程权威指南pdf

    热门讨论 2011-03-25 09:30:55
    函数库实现了基本解释器,它一套实现变量、流程控制和过程的核心脚本命令,而且还有一组用来存取操作系统服务以运行其他程序、存取文件系统使用网络套接字命令。TclTk提供了一台可以在UNIX、Windows...
  • 图像处理 相关资料

    2008-12-23 19:15:15
    采用两种不同包含格式理由在于,编译器是安装在公共目录下,而被编译应用程序是在它们自己私有目录下。一个应用程序既包含编译器提供公共头文件,也包含自定义私有头文件。采用两种不同包含...
  • 二叉排序树与平衡二叉树实现

    热门讨论 2010-12-26 15:25:31
    中序遍历二叉树也采用递归函数的方式,先访问左子树2i,然后访问根结点i,最后访问右树2i+1.先向左走到底再层层返回,直至所有结点都被访问完毕。 1.2.4 平均查找长度 计算二叉排序树平均查找长度时,采用类似...
  • CruiseYoung提供详细书签电子书籍目录 http://blog.csdn.net/fksec/article/details/7888251 计算机图形学算法基础(原书第2版) 基本信息 原书名: Procedural Elements for Computer Graphics (2E) 原...
  • C++程序员面试宝典

    热门讨论 2013-04-01 13:36:19
    面试题90 指针函数和函数指针区别 95 8.3 this指针 96 面试题91 什么是this指针 96 面试题92 何时使用this指针 96 8.4 引用与值传递 97 面试题93 什么是值传递 97 面试题94 引用与值传递区别 98 面试题95 指针和...
  • 8.5.7 打开两种键盘端口驱动寻找设备 131 8.5.8 搜索在KbdClass类驱动中地址 133 8.6 Hook键盘中断反过滤 135 8.6.1 中断:IRQINT 136 8.6.2 如何修改IDT 136 8.6.3 替换IDT中跳转地址 137 8.6.4 QQPS...
  • 8.5.7 打开两种键盘端口驱动寻找设备 131 8.5.8 搜索在KbdClass类驱动中地址 133 8.6 Hook键盘中断反过滤 135 8.6.1 中断:IRQINT 136 8.6.2 如何修改IDT 136 8.6.3 替换IDT中跳转地址 137 8.6.4 QQPS...

空空如也

空空如也

1 2 3 4 5
收藏数 82
精华内容 32
关键字:

c语言的子函数有过程和函数两种

c语言 订阅