当前位置:文档之家› 关于堆栈和指针(指针例子解释很好)

关于堆栈和指针(指针例子解释很好)

关于堆栈和指针(指针例子解释很好)
关于堆栈和指针(指针例子解释很好)

关于堆栈和指针

堆栈是一种执行“后进先出”算法的数据结构。

设想有一个直径不大、一端开口一端封闭的竹筒。有若干个写有编号的小球,小球的直径比竹筒的直径略小。现在把不同编号的小球放到竹筒里面,可以发现一种规律:先放进去的小球只能后拿出来,反之,后放进去的小球能够先拿出来。所以“先进后出”就是这种结构的特点。

堆栈就是这样一种数据结构。它是在内存中开辟一个存储区域,数据一个一个顺序地存入(也就是“压入——push”)这个区域之中。有一个地址指针总指向最后一个压入堆栈的数据所在的数据单元,存放这个地址指针的寄存器就叫做堆栈指示器。开始放入数据的单元叫做“栈底”。数据一个一个地存入,这个过程叫做“压栈”。在压栈的过程中,每有一个数据压入堆栈,就放在和前一个单元相连的后面一个单元中,堆栈指示器中的地址自动加1。读取这些数据时,按照堆栈指示器中的地址读取数据,堆栈指示器中的地址数自动减1。这个过程叫做“弹出pop”。如此就实现了后进先出的原则。

堆栈是计算机中最常用的一种数据结构,比如函数的调用在计算机中是用堆栈实现的。

堆栈可以用数组存储,也可以用以后会介绍的链表存储。

下面是一个堆栈的结构体定义,包括一个栈顶指针,一个数据项数组。栈顶指针最开始指向-1,然后存入数据时,栈顶指针加1,取出数据后,栈顶指针减1。

#define MAX_SIZE 100

typedef int DATA_TYPE;

struct stack

{

DATA_TYPE data[MAX_SIZE];

int top;

};

堆栈是系统使用是临时存储区域。它是后进先出的数据结构。

C++主要将堆栈用于函数调用。当函数调用时,各种数据被推入堆栈顶部;函数终止后的返回地址、传递给函数的参数、函数返回的结果以及函数中声明的局部变量等等。因此当函数A调用函数B调用函数C,堆栈是增长了,但调用完成后,堆栈又缩小了。

堆是一种长期的存储区域。程序用C++的new操作符分配堆。对new的调用分配所需的内存并返回指向内存的指针。与堆栈不同,你必须通过调用new明确的分配堆内存。你也必须通过调用C++的delete 操作符明确的释放内存,堆不会自动释放内存。

如果C++中的一个类是定义在堆栈上的,就使用"."开访问它的成员。如果是定义在堆上的,就使用"->"指针来开访问。但在,"->"操作符也可以用在堆栈上的类。

什么是指针?

和其它变量一样,指针是基本的变量,所不同的是指针包含一个实际的数据,该数据代表一个可以找到实

际信息的内存地址。这是一个非常重要的概念。许多程序和思想依靠指针作为他们设计的基础。

开始

怎样定义一个指针呢?除了你需要在变量的名称前面加一个星号外,其它的和别的变量定义一样。举个例子,以下代码定义了两个指针变量,它们都指向一个整数。

int* pNumberOne;

int* pNumberTwo;

注意到两个变量名称前的前缀?p?了么?这是一个惯例,用来表示这个变量是个指针。

现在,让我们将这些指针实际的指向某些东西:

pNumberOne = &some_number;

pNumberTwo = &some_other_number;

…&?符号应该读作”什么什么的地址”,它返回一个变量在内存中的地址,设置到左侧的变量中。因此,在这个例子中,pNumberOne设置和some_number的地址相同,因此pNumberOne现在指向some_number。

现在,如果我们想访问some_number的地址,可以使用pNumberOne。如果我们想通过pNumberOne 访问some_number的值,那么应该用*pNumberOne。这个星号表示解除指针的参照,应该读作“什么什么指向的内存区域”。

到现在我们学到了什么?举个例子

哟,有许多东西需要理解。我的建议是,如果你有哪个概念没有弄清楚的话,那么,不妨再看一遍。指针是个复杂的对象,可能需要花费一段时间来掌握它。

这儿有一个例子示范上面所将的概念。这是用C写的,没有C++扩展。

#include

void main()

{

// 申明变量

int nNumber;

int *pPointer;

//赋值

nNumber = 15;

pPointer = &nNumber;

// 输出nNumber的值

printf("nNumber is equal to : %d\n", nNumber);

// 通过pPointer修改nNumber的值

*pPointer = 25;

// 证明nNumber已经被改变了

// 再次打印nNumber的值

printf("nNumber is equal to : %d\n", nNumber);

}

通读一遍,并且编译样例代码,确信你理解了它为什么这样工作。如果你准备好了,那么继续。一个陷阱!

看看你能否发现下面这段程序的毛病:

#include

int *pPointer;

void SomeFunction();

{

int nNumber;

nNumber = 25;

//将pPointer指向nNumber

pPointer = &nNumber;

}

void main()

{

SomeFunction(); //用pPointer做些事情

// 为什么会失败?

printf("Value of *pPointer: %d\n", *pPointer);

}

这段程序先调用SomeFunction函数,该函数创建一个叫做nNumber的变量,并将pPointer指向它。那么,问题是,当函数退出时,nNumber被删除了,因为它是一个局部变量。当程序执行到局部变量定义的程序块以外时,局部变量总是被删除了。这就意味着,当SomeFunction函数返回到main函数时,局部变量将被删除,因此pPointer将指向原先nNumber的地址,但这个地址已经不再属于这段程序了。如果你不理解这些,那么重新阅读一遍关于局部变量和全局变量的作用范围是明智的选择。这个概念也是非常重要的。

那么,我们如何解决这个问题呢?答案是使用大家都知道的一个方法:动态分配。请明白C和C++的动态分配是不同的。既然现在大多数程序员都使用C++,那么下面这段代码就是常用的了。

动态分配

动态分配可以说是指针的关键所在。不需要通过定义变量,就可以将指针指向分配的内存。也许这个概念看起来比较模糊,但是确实比较简单。下面的代码示范如何为一个整数分配内存:

int *pNumber;

pNumber = new int;

第一行申明了一个指针pNumber,第二行分配一个整数内存,并且将pNumber指向这个新内存。下面是另一个例子,这次用一个浮点数:

double *pDouble;

pDouble = new double;

动态分配有什么不同的呢?当函数返回或者程序运行到当前块以外时,你动态分配的内存将不会被删除。因此,如果我们用动态分配重写上面的例子,可以看到现在能够正常工作了。

#include

int *pPointer;

void SomeFunction()

{

// make pPointer point to a new integer

pPointer = new int;

*pPointer = 25;

}

void main()

SomeFunction(); // make pPointer point to something

printf("Value of *pPointer: %d\n", *pPointer);

}

通读一遍,编译上面的代码,确信你已经理解它是如何工作的。当调用SomeFunction时,分配了一些内存,并且用pPointer指向它。这次,当函数返回时,新内存就完整无缺了。因此pPointer仍旧指向有用的东西。这是因为使用了动态分配。确信你已经理解它了。那么继续向下看,了解为什么上面的程序还会有一系列的错误。

内存分配和内存释放

这里有一个问题,可能会变得十分严重,虽然它很容易补救。这个问题就是,虽然你用动态分配可以方便的让内存完整无缺,确实不会自动删除,除非你告诉计算机,你不再需要这块内存了,否则内存将一直被分配着。因此结果就是,如果你不告诉计算机你已经使用完这块内存,那么它将成为被浪费的空间,因为其它程序或者你的应用程序的其它部分不能使用这块内存。最终将导致系统因为内存耗尽而崩溃。因此这个问题相当重要。内存使用完后释放非常容易:

delete pPointer;

需要做的就是这些。但是你必须确定,你删除的是一个指向你实际分配的内存的指针,而不是其它任何垃圾。尝试用delete已经释放的内存是危险的,并且可能导致程序崩溃。

这里再次举个例子,这次修改以后就不会有内存浪费了。

#include

int *pPointer;

void SomeFunction()

{

// make pPointer point to a new integer

pPointer = new int;

*pPointer = 25;

}

void main()

{

SomeFunction(); // make pPointer point to something

printf("Value of *pPointer: %d\n", *pPointer);

delete pPointer;

}

只有一行不同,但这行是要点。如果你不删除内存,就会导致“内存泄漏”,内存将逐渐减少,除非应用程序重新启动,否则将不能再生。

向函数传递指针

传递指针给函数非常有用,但不容易掌握。如果我们写一个程序,传递一个数值并且给它加上5,我们也许会写出如下的程序:

#include

void AddFive(int Number)

{

Number = Number + 5;

}

void main()

int nMyNumber = 18;

printf("My original number is %d\n", nMyNumber);

AddFive(nMyNumber);

printf("My new number is %d\n", nMyNumber);

}

但是,程序中函数AddFive的参数Number只是变量nMyNumber的一个拷贝,而不是变量本身,因此,Number = Number + 5只是为变量的拷贝增加了5,而不是最初的在main()函数中的变量。当然,你可以运行程序,以证明这一点。

为了将值传递出去,我们可以传递这个变量的指针到函数中,但我们需要修改一下函数,以便传递数值的指针而不是数值。因此将void AddFive(int Number)修改为void AddFive(int *Number),增加了一个星号。下面是修改了的函数,注意,我们必须确认传递了nMyNumber的地址,而不是它本身。这通过增加&符号来完成,通常读作“什么什么的地址”。

#include

void AddFive(int* Number)

{

*Number = *Number + 5;

}

void main()

{

int nMyNumber = 18;

printf("My original number is %d\n", nMyNumber);

AddFive(&nMyNumber);

printf("My new number is %d\n", nMyNumber);

}

大家可以试着自己做个例子来实验一下。注意在AddFive函数中Number变量前那个重要的星号。只是必须的,用来告诉编译器我们想将5加到变量Number指向的数值,而不是将5加到指针本身。

关于函数最后需要注意的是你也可以返回一个指针。比如:

int * MyFunction();

在这个例子中,MyFunction函数返回一个指向整数的指针。

类的指针

关于指针还有两个需要注意的问题。其中一个是结构或者类。你可以如下定义一个类:

class MyClass

{

public:

int m_Number;

char m_Character;

};

然后,你可以如下方式定义一个类变量:

MyClass thing;

你应该已经知道这些了,如果还不知道的话,那么再将上面的内容读一遍。定义MyClass的指针应该这么写:

MyClass *thing;

然后你需要分配内存,并将指针指向这个内存

thing = new MyClass;

问题来了,你如何使用这个指针呢?一般的,我们写thing.m_Number,但你不能对指针用?.?操作,因为thing 不是一个MyClass对象。只是指向一个MyClass对象的指针。因此,指针thing不包含m_Number这个变量。只是它指向的结构中包含这个变量。因此,我们必须使用一个不同的协定,用->取代?.?。以下是一个例子:

class MyClass

{

public:

int m_Number;

char m_Character;

};

void main()

{

MyClass *pPointer;

pPointer = new MyClass;

pPointer->m_Number = 10;

pPointer->m_Character = 's';

delete pPointer;

}

数组的指针

你也可以构造一个指向数组的指针,如下:

int *pArray;

pArray = new int[6];

将创建一个叫做pArray的指针,指向一个包含6个元素的数组。另一种构造的方法是使用动态分配,如下:

int *pArray;

int MyArray[6];

pArray = &MyArray[0];

注意,你这里也可以不用&MyArray[0],而直接使用&MyArray取代。当然,这仅仅适用于数组。

使用指向数组的指针

一旦你有了指向数组的指针,那么如何使用它呢?现在假设你有一个指向整数数组的指针,那么指针开始时将指向第一个整数。举例如下:

#include

void main()

{

int Array[3];

Array[0] = 10;

Array[1] = 20;

Array[2] = 30;

int *pArray;

pArray = &Array[0];

printf("pArray points to the value %d\n", *pArray);

}

将指针移到指向数组的下一个值,可以用pArray++。也许你也可以猜出来了,我们可以用pArray+2的方式将指针向后移动两个位置。要注意的问题是,你自己必须知道数组的上限是多少(例子中是3),因为编译器不能检查你是否将指针移到了数组以外,因此你可以很容易的将系统搞崩溃了。以下是个例子,显示我们设置的三个值:

#include

void main()

{

int Array[3];

Array[0] = 10;

Array[1] = 20;

Array[2] = 30;

int *pArray;

pArray = &Array[0];

printf("pArray points to the value %d\n", *pArray);

pArray++;

printf("pArray points to the value %d\n", *pArray);

pArray++;

printf("pArray points to the value %d\n", *pArray);

}

你也可以使用pArray-2这样的方式来向前移动2个位置。不管是加或者减,你必须保证不是对指针所指向的数据的操作。这种操作指针和数组的方式在循环中是最常用的。例如for和while循环。

另外要提的是,如果你有一个指针比如int pNumberSet,你也可以把它当成数组。例如pNumberSet[0]等于*pNumberSet,并且pNumberSet[1]等于*(pNumberSet+1)。

对于数组,还有一点要注意的,如果你用new为数组分配内存,比如:

int *pArray;

pArray = new int[6];

你必须用以下方式进行删除:

delete[] pArray;

注意delete后的[],它告诉编译器,这是删除整个数组,而不仅仅是第一个元素。对于数组你必须使用这种方法,否则就会有内存泄漏。

总结

一条要注意的:你不能删除不是用new分配的内存。比如以下例子:

void main()

{

int number;

int *pNumber = number;

delete pNumber; // wrong - *pNumber wasn't allocated using new.

}

函数指针

方法 指针函数和函数指针的区别 关于函数指针数组的定义 为函数指针数组赋值 函数指针的声明方法为: 数据类型标志符 (指针变量名) (形参列表); 注1:“函数类型”说明函数的返回类型,由于“()”的优先级高于“*”,所以指针变量名外的括号必不可少,后面的“形参列表”表示指针变量指向的函数所带的参数列表。例如: int func(int x); /* 声明一个函数 */ int (*f) (int x); /* 声明一个函数指针 */ f=func; /* 将func函数的首地址赋给指针f */ 赋值时函数func不带括号,也不带参数,由于func代表函数的首地址,因此经过赋值以后,指针f就指向函数func(x)的代码的首地址。 注2:函数括号中的形参可有可无,视情况而定。 下面的程序说明了函数指针调用函数的方法: 例一、 #include int max(int x,int y){ return(x>y?x:y); } void main() { int (*ptr)(int, int); int a,b,c; ptr=max; scanf("%d%d",&a,&b); c=(*ptr)(a,b); printf("a=%d,b=%d,max=%d",a,b,c); } ptr是指向函数的指针变量,所以可把函数max()赋给ptr作为ptr的值,即把max()的入口地址赋给ptr,以后就可以用ptr来调用该函数,实际上ptr 和max都指向同一个入口地址,不同就是ptr是一个指针变量,不像函数名称那样是死的,它可以指向任何函数,就看你想怎么做了。在程序中把哪个

C指针函数习题

C++指针函数习题 一、选择题 1.以下程序的运行结果是()。 sub(int x, int y, int *z) { *z=y-x; } void main() { int a,b; sub(10,5,&a); sub(7,a,&b); cout< #include<>

指向函数的指针详解

指向函数的指针 函数指针是指指向函数而非指向对象的指针。像其他指针一样,函数指针也指向某个特定的类型。函数类型由其返回类型以及形参表确定,而与函数名无关: bool (*pf)(const string &,const string &); 这个语句将pf声明为指向函数的指针,它所指向的函数带有两个const string &类型的形参和bool 类型的返回值。 注意:*pf两侧的括号是必需的。 1.typedef简化函数指针的定义: 函数指针类型相当地冗长。使用typedef为指针类型定义同义词,可将函数指针的使用大大简化: Typedef bool (*cmpfn)(const string &,const string &); 该定义表示cmpfn是一种指向函数的指针类型的名字。该指针类型为“指向返回bool类型并带有两个const string 引用形参的函数的指针”。在要使用这种函数指针类型时,只需直接使用cmpfcn即可,不必每次都把整个类型声明全部写出来。 2.指向函数的指针的初始化和赋值 在引用函数名但又没有调用该函数时,函数名将被自动解释为指向函数的指针。假设有函数: Bool lengthcompare(const string &,const string &); 除了用作函数调用的左操作数以外,对lengthcompare的任何使用都被解释为如下类型的指针:

bool (*)(const string &,const string &); 可使用函数名对函数指针初始化或赋值: cmpfn pf1=0; cmpfn pf2=lengthcompare; pf1=legnthcompare; pf2=pf1; 此时,直接引用函数名等效于在函数名上应用取地址操作符: cmpfcn pf1=lengthcompare; cmpfcn pf2=lengthcompare; 注意:函数指针只能通过同类型的函数或函数指针或0值常量表达式进行初始化或赋值。 将函数指针初始化为0,表示该指针不指向任何函数。 指向不两只函数类型的指针之间不存在转换: string::size_type sumLength(const string &,const string &); bool cstringCompare(char *,char *); //pointer to function returning bool taking two const string& cmpFcn pf;//error:return type differs pf=cstringCompare;//error:parameter types differ pf=lengthCompare;//ok:function and pointer types match exactly 3.通过指针调用函数 指向函数的指针可用于调用它所指向的函数。可以不需要使用解引用

学生用毛细现象解释酒精灯燃烧

④学生用毛细现象解释酒精灯燃烧、树枝插在红色水中插久了变色的原因。 “科学是探求意义的过程”(爱因斯坦)。作为一种学生的学习方式,探究活动关注的重点是围绕解决问题,采用一定的方法问题进行学习。学生的探究是需要方法引导的,这种引导将经历 究”的过程,逐步放开。 一位外国教育专家观看了这堂课后,兴奋地说:“我终于看到了儿童真实的探究。这里真是课堂改进的天堂。” 照片:外国专家在课堂上 如果文章要分两部分的话,下面为第二部分,题目不变。 3. 在“变式”体验中建构原理 ----中学物理《杠杆》 杠杆是一种简单的机械,形状各异,但都绕一个点转动,这个点称为支点。杠杆受的力分为动力和阻力,支点到动力或阻力的作用线的距离叫做力臂,杠杆平衡的条件是:动力×动力臂=阻力×阻力臂。 杠杆是阿基米德发现力学规律的得意之作,他得出了著名的杠杆原理。让学生在过程体验中建构概念、原理,是当前理科课程改革的主要思想之一。可是一到现实的课堂,杠杆原理与认知建构理论就怎么也不能相映成趣: ①力臂的定义比较抽象,总是由教师给出、学生记住; ②杠杆平衡的条件还是教师演示,学生验证。 那么能否通过适当的教学处理,让学生能生动地体验知识的发生过程,有效地建构物理概念呢?物理研究小组对杠杆这堂课的教学内容做了如下的调整。 ● 从“扁担挑物”到水平杠杆的平衡条件 最简单的杠杆是水平杠杆。学生早就有了扁担挑东西的生活经验,只要稍作概括,就可以简化成如图所示的水平杠杆。 扁担挑物 水平杠杆:支点、水平力臂、重力

在水平杠杆模型中,力臂是“具体”的,与生活经验完全一致,因此不会成为学习的难点。这样,学生就可以避开难点,集中探索支点两侧力臂、重力这4个物理量的关系,下面是学生在课堂上做物理实验填写的记录单: 实验序次 重力F1力臂L1重力F2力臂L2 ① 3 2 ② 2 3 ③ ④ ⑤ ⑥ 学生经过亲自实验,获得一批数据,然后相互合作探讨这些数据之间的关系,得出水平杠杆平衡的条件,即重力与力臂之间两两乘积相等( F1 L1=F2 L2)或反比例(F1 :L2 = F2 :L1)。 在新设计的教学过程中,师生行为出现了明显的变化。改进前,先是由教师口头讲解或实验演示,得出上述平衡条件,然后让学生根据实验手册的要求验证这个规律。改进后,学生变得主动起来,从直觉感知出发,通过简化设计了的实验,变验证为自觉探求,亲身体验了科学家(如阿基米德)发现客观规律的过程,这样的科学加工的方法(图6),在自然科学的学习与研究中很具普遍意义和思想的价值。 扁担挑物 水平杠杆 符号表征 (生活经验) (因素简约化) F1 L1=F2 L2 图6 体验科学家发现规律的过程 ● 杠杆原理与力臂定义的修正 水平杠杆是个简单的模型,把其中一端的重物换为弹簧秤竖直往下拉,结果仍然符合前述的杠杆原理。改变弹簧秤的方向,如下图所示斜拉。这时学生会

生活中的毛细现象

生活中常见的毛细现象 摘要:毛细作用,是液体表面对固体表面的吸引力。毛细管插入浸润液体中,管内液面上升,高于管外,毛细管插入不浸润液体中,管内液体下降,低于管外的现象。毛巾吸水,地下水沿土壤上升都是毛细现象。在洁净的玻璃板上放一滴水银,它能够滚来滚去而不附着在玻璃板上。把一块洁净的玻璃板浸入水银里再取出来,玻璃上也不附着水银。生活中有很多这种毛细现象。 关键词:毛细;生活;应用 一、毛细现象及其相关概念 1.1毛细现象 毛细现象,又称毛细管作用,是指液体在细管状物体内侧,由于内聚力与附着力的差异、克服地心引力而上升的现象。植物根部吸收的水分能够经由茎内维管束上升,即是毛细现象最常见的例子。当液体和固体或管壁之间的附着力大于液体本身内聚力时,就会产生毛细现象。液体在垂直的细管中时液面呈凹或凸状、以及多孔材质物体能吸收液体皆为此现象所致。 1.2 浸润液体 在洁净的玻璃上放一滴水,它会附着在玻璃板上形成薄层。把一块洁净的玻璃片浸入水中再取出来,玻璃的表面会沾上一层水.这种液体附着在固体表面上的现象叫做浸润。对玻璃来说,水是浸润液体。同一种液体,对一种固体来说是浸润的,对另一种固体来说可能是不浸润的。水能浸润玻璃,但不能浸润石蜡.水银不能浸润玻璃,但能浸润锌。

1.3 毛细现象产生原因 产生毛细现象原因之一是由于附着层中分子的附着力与内聚力的作用,造成浸润或不浸润,因而使毛细管中的液面呈现弯月形。原因之二是由于存在表面张力,从而使弯曲液面产生附加压强。由于弯月面的形成,使得沿液面切面方向作用的表面张力的合力,在凸弯月面处指向液体内部;在凹弯月面处指向液体外部。由于合力的作用使弯月面下液体的压强发生了变化——对液体产生一个附加压强,凸弯月面下液体的压强大于水平液面下液体的压强,而凹弯月面下液体的压强小于水平液面下液体的压强。根据在盛着同一液体的连通器中,同一高度处各点的压强都相等的道理,当毛细管里的液面是凹弯月面时,液体不断地上升,直到上升液柱的静压强抵消了附加压强为止;同样,当液面呈凸月面时,毛细管里的液体也将下降。 1.4 水和汞的毛细现象 由于表面张力与附着力的差异,水在毛细管中,中央较四周凹下;汞在毛细管中,中央较四周凸起。毛细管常被用来说明毛细现象,当垂直的细玻璃管底部臵于液体中(例如水)时,管壁对水的附着力便会使液面四周稍比中央高出一些;直到液体表面张力已经无法克服其重量时,才会停止继续上升。在毛细管中,液柱重量与管径的平方成正比,但是液体与管壁的接触面积只与管径成正比;这使得较窄的毛细管吸水会比较宽的毛细管来得高。例如,一根管径0.5毫米的玻璃细管,理论上能够将水抬升2.8厘米,但实际观察时其高度会略低些。 在某些液体与固体的组合中,与毛细管吸水的状况略为不同,例如细玻璃管与汞,汞柱本身的原子内聚力大于汞柱与管壁之间的附着力,故汞柱液面中央会稍比四周凸起,这和毛细管吸水的状况恰为相反。

指针函数与函数指针的区别

指针函数与函数指针的区别 一、 在学习arm过程中发现这“指针函数”与“函数指针”容易搞错,所以今天,我自己想一次把它搞清楚,找了一些资料,首先它们之间的定义: 1、指针函数是指带指针的函数,即本质是一个函数。函数返回类型是某一类型的指针 类型标识符 *函数名(参数表) int *f(x,y); 首先它是一个函数,只不过这个函数的返回值是一个地址值。函数返回值必须用同类型的指针变量来接受,也就是说,指针函数一定有函数返回值,而且,在主调函数中,函数返回值必须赋给同类型的指针变量。 表示: float *fun(); float *p; p = fun(a); 注意指针函数与函数指针表示方法的不同,千万不要混淆。最简单的辨别方式就是看函数名前面的指针*号有没有被括号()包含,如果被包含就是函数指针,反之则是指针函数。来讲详细一些吧!请看下面 指针函数: 当一个函数声明其返回值为一个指针时,实际上就是返回一个地址给调用函数,以用于需要指针或地址的表达式中。 格式: 类型说明符* 函数名(参数) 当然了,由于返回的是一个地址,所以类型说明符一般都是int。 例如:int *GetDate(); int * aaa(int,int); 函数返回的是一个地址值,经常使用在返回数组的某一元素地址上。 int * GetDate(int wk,int dy); main() { int wk,dy; do { printf(Enter week(1-5)day(1-7)\n); scanf(%d%d,&wk,&dy); } while(wk<1||wk>5||dy<1||dy>7); printf(%d\n,*GetDate(wk,dy));

毛细现象

毛细现象大班18人 活动目标: 1.知道带缝隙的物体使水向上走是毛细现象原理,体验和探究发现的乐趣(感知毛细现象原理) 2.能与同伴合作探究,乐于与他人交流自己的猜想、探究和发现。 3.能够探索可以发生毛细现象的物体,学习记录和描述自己的实验过程和结果。 重点:能够探索可以发生毛细现象的物体, 难点:观察出让水移动的物体都有细缝 活动准备: 物质准备:毛巾,清水,容器,尼龙绳,筷子,报纸,棉布,卫生纸,记录表,带颜色的水 经验准备:有记录表格的经验 场地准备: 活动过程: (一)创设问题情境,鼓励幼儿大胆猜想 经验迁移:“我们平时看到的水都是往哪个方向流的呢?谁能够给我举出几个例子(洗手、喝水、下雨)” 引发幼儿猜想:“水会往低处流,还会往其他方向移动吗?” 现象演示:将毛巾的下端浸在水中,一段时间后,为什么毛巾的上端也湿了?那是不是所有的东西都能够让水往上移动呢? 你们觉得有哪些东西可以让水往上移动?出示材料,让幼儿猜想,并在白板上画出表格,用“正”字记录数据,最后进行验证。 (二)引导幼儿进行试验验证,并记录自己的观察和发现 “每个人都说出了不一样的看法,现在我们三个人为一组,到身后的材料台拿材料,然后去操作台进行实验,在实验的过程当中有个要求,你们组的成员要自行分配好任务,有做记录的,有做观察,还有人一会要说出来你们组都发现了什么,每个人都有自己的任务哦!” 幼儿实验操作,进行个别指导。(在实验过程当中注意容器的水和记录表) (三)鼓励幼儿进行交流分享,梳理提升经验

实验结束后让孩子拿着记录表坐到椅子上,“你们谁看见水往上移动了?你们都选取的哪些材料,有哪些可以让水移动呢?”,与实验之前记录的表格相对比,看看猜想与实验结果是否一致。 提升:“你们刚才都做实验了,那能让水移动的物品都有什么共同点,或者说和其他的相比有什么不同点?”拿出材料,让幼儿仔细观察,发现物品特征,“能让水向上移动的物品摸起来和看起來有什么不同?” 结论:原来带缝隙的物品能让水往上移动。 提出问题,猜想与假设,观察、实验与制作,搜集、记录信息,思考、解释与得出结论,表达、分享与交流 对身边的科学现象感兴趣,学习用多种方法进行探究和实验,常使用语言、图表等多种方式表达探索的过程和结果,并乐于与同伴分享探索和发现的乐趣。 产生疑问猜想假设实验验证

生活中的毛细现象之欧阳家百创编

生活中常见的毛细现象 欧阳家百(2021.03.07) 摘要:毛细作用,是液体表面对固体表面的吸引力。毛细管插入浸润液体中,管内液面上升,高于管外,毛细管插入不浸润液体中,管内液体下降,低于管外的现象。毛巾吸水,地下水沿土壤上升都是毛细现象。在洁净的玻璃板上放一滴水银,它能够滚来滚去而不附着在玻璃板上。把一块洁净的玻璃板浸入水银里再取出来,玻璃上也不附着水银。生活中有很多这种毛细现象。 关键词:毛细;生活;应用 一、毛细现象及其相关概念 1.1 毛细现象 毛细现象,又称毛细管作用,是指液体在细管状物体内侧,由于内聚力与附着力的差异、克服地心引力而上升的现象。植物根部吸收的水分能够经由茎内维管束上升,即是毛细现象最常见的例子。当液体和固体或管壁之间的附着力大于液体本身内聚力时,就会产生毛细现象。液体在垂直的细管中时液面呈凹或凸状、以及多孔材质物体能吸收液体皆为此现象所致。 1.2 浸润液体 在洁净的玻璃上放一滴水,它会附着在玻璃板上形成薄层。把一块洁净的玻璃片浸入水中再取出来,玻璃的表面会沾上一层水.这种液体附着在固体表面上的现象叫做浸润。对玻璃来说,水是浸

润液体。同一种液体,对一种固体来说是浸润的,对另一种固体来说可能是不浸润的。水能浸润玻璃,但不能浸润石蜡.水银不能浸润玻璃,但能浸润锌。 1.3 毛细现象产生原因 产生毛细现象原因之一是由于附着层中分子的附着力与内聚力的作用,造成浸润或不浸润,因而使毛细管中的液面呈现弯月形。原因之二是由于存在表面张力,从而使弯曲液面产生附加压强。由于弯月面的形成,使得沿液面切面方向作用的表面张力的合力,在凸弯月面处指向液体内部;在凹弯月面处指向液体外部。由于合力的作用使弯月面下液体的压强发生了变化——对液体产生一个附加压强,凸弯月面下液体的压强大于水平液面下液体的压强,而凹弯月面下液体的压强小于水平液面下液体的压强。根据在盛着同一液体的连通器中,同一高度处各点的压强都相等的道理,当毛细管里的液面是凹弯月面时,液体不断地上升,直到上升液柱的静压强抵消了附加压强为止;同样,当液面呈凸月面时,毛细管里的液体也将下降。 1.4 水和汞的毛细现象 由于表面张力与附着力的差异,水在毛细管中,中央较四周凹下;汞在毛细管中,中央较四周凸起。毛细管常被用来说明毛细现象,当垂直的细玻璃管底部置于液体中(例如水)时,管壁对水的附着力便会使液面四周稍比中央高出一些;直到液体表面张力已经无法克服其重量时,才会停止继续上升。在毛细管中,液柱重量与管径的平方成正比,但是液体与管壁的接触面积只与管径成

指向函数的指针

指向函数的指针 c/c++ 2010-11-20 13:17:02 阅读41 评论0 字号:大中小订阅首先看这个程序: #include using namespace std; void max(int a, int b) { cout<<"now call max("<b?a:b; cout<

我曾经写过一个命令行程序,有很多命令,于是构着了一个结构的数组,大概是这样 struct{ char *cmd_name; bool (*cmd_fun)(); }cmd_info_list[MAX_CMD_NUM]; 程序中得到一个用户输入的命令字符串后,就匹配这个数组,找到对应的处理函数。 以后每次添加一个命令,只需要加个函数,然后在这个数组中加一个记录就可以了,不需要修改太多的代码。 这可以算是一种用法吧。呵呵。 Windows 中,窗口的回调函数就用到了函数指针。 用VC向导 New Projects ----> Win32 Application ----> A typical "Hello World!" application 其中的WndProc 是WNDPROC 类型的函数typedef LRESULT (CALLBACK* WNDPROC)(HWND, UINT, WPARAM, LPARAM); WndProc 作为窗口的回调函数,用来填充WNDCLASSEX 结构。 WNDCLASSEX wcex; wcex.lpfnWndProc = (WNDPROC)WndProc; void ListTraverse(LinkList L,void (*visit)(int)) { Link p; p=L->next; while(p) { visit(p->data); p=p->next; } return OK; } void print(int c) { printf("%d",c); } ListTraverse(L,print); 这算是个例子吧??? #include #include #include double Add (double x, double y) { return x+y; } double Sub (double x, double y) { return x-y; } double Mul (double x, double y)

函数及指针练习题

函数练习题 【1.54】对函数形参的说明有错误的是____。 A) int a(float x[],int n) B) int a(float *x,int n) C) int a(float x[10],int n) D) int a(float x,int n) 【1.55】如果一个变量在整个程序运行期间都存在,但是仅在说明它的函数内是可见的,这个变量的存储类型应该被说明为____。 A)静态变量B) 动态变量C) 外部变量D) 内部变量 【1.56】在一个C源程序文件中,?若要定义一个只允许在该源文件中所有函数使用的变量,则该变量需要使用的存储类别是。 A) extern B) register C) auto D) static 【1.57】在C语言中,函数的数据类型是指____。 A)函数返回值的数据类型B) 函数形参的数据类型 C) 调用该函数时的实参的数据类型D) 任意指定的数据类型 【1.58】已知如下定义的函数: fun1(a) { printf("\n%d",a); } 则该函数的数据类型是____。 A)与参数a的类型相同B) void型 C) 没有返回值D) 无法确定 【1.59】定义一个函数实现交换x和y的值,并将结果正确返回。能够实现此功能的是____。 A) swapa(int x,int y) B) swapb(int *x,int *y) { int temp;{ int temp; temp=x;x=y;y=temp;temp=x;x=y;y=temp; } } C) swapc(int *x,int *y) D) swapd(int *x,int *y) { int temp;{ int *temp; temp=*x;*x=*y;*y=temp;temp=x;x=y;y=temp; } } 【1.60】求一个角的正弦函数值的平方。能够实现此功能的函数是____。 A) sqofsina(x) float x; { return(sin(x)*sin(x)); } B) double sqofsinb(x) float x; { return(sin((double)x)*sin((double)x)); } C) double sqofsinc(x) { return(((sin(x)*sin(x)); } D) sqofsind(x) float x;

生活中的毛细现象

生活中的毛细现象 准备材料:一块纯棉布、一块化纤布、一次性纸杯、一小块报纸、铅笔、塑料勺子、雪糕棍周末妈妈给我买了几件衣服,回家后让我试了一件又一件,还说这件是纯棉,那件是60%的棉,还有什么速干面料的;还说这件比较凉快,那件出汗以后比较容易干。我问妈妈,各种衣服的作用都不同吗?妈妈说,准确的说,衣服的质地不一样穿上的感觉的一样,尤其是在夏天,选择合适的衣服会感觉很凉爽,有的衣服却感觉很热。哦,原来是这样,怪不得妈妈每次买衣服都要先翻吊牌,是看衣服的质地啊。妈妈看我还是有些不太明白,说我们一起做个简单的小实验我就会很快明白的。一听做实验,太高兴了,我赶紧把实验装备全都搬出来。 需要的材料:一个盘子、一块纯棉布、一块化纤布 实验过程:把纯棉布和化纤布浸泡在水中,观察它们被浸湿情况。

实验结果:发现纯棉布很快湿了一大片,而化纤布湿的很少。 实验原理:棉布是用有空隙的细纤维织成的,由于毛细作用,汗液可以通过这些空隙跑出去,所以大部分人喜欢在夏天穿棉、麻等天然纤维制成的衣服。如果用化纤做内衣会感觉很热,这是因为化纤纤维缝隙较少,难以产生毛细现象,所以不宜吸汗,会使你感到汗在衣服里流淌。因此,夏天穿纯棉或者天然纤维的衣服最凉爽。 实验延伸: 为了对毛细现象有更深入的理解,我们采用了其它两种实验: (一)通过手工纸折成花朵状,放入水中,观察“花朵”,说明纸也有毛细现象。

妈妈让我做这个实验的时候,我还心中有疑问,“花朵”会盛开吗?实验证明,纸也有毛细现象。因为纸的主要材料是植物纤维,它们也有极细的管道,水渗入这些毛细管中,纸开始膨胀,纸做的“花朵”就盛开了。 (二)利用家中的一些材料做比试,看看它们是否都有毛细现象?材料:塑料勺、冰糕棍、铅笔、粉笔。 通过比试,我发现并不是所有的物质都有毛细现象。将这些材料放入水中几分钟后,粉笔全部都变湿了,铅笔的笔尖处已被水浸湿,冰糕棍的一头由于水的浸泡颜色开始变深,而塑料小勺没有变化。 实验后的感想:

毛细管长度的试验方法 将工艺管打开,高压管连接压力表,毛细管的一端连接干燥过滤器,另一端暂不焊接,启

1 . 毛细管长度的试验方法 将工艺管打开,高压管连接压力表,毛细管的一端连接干燥过滤器,另一端暂不焊接,启动压缩机,如果压力表的压力稳定在0.98-----1.177Mpa左右,可以认为合适,压力过高就要割断一小段,压力过小时就加一小段,反复试验直到合适为止,然后将毛细管和蒸发器连接好。再抽真空、充注制冷剂。 2.工厂大部分采用测试的方法来判定毛细管的长短,需要的设备有:高压瓶、流量计、液压测量和气压测量等条件,而在维修当中由于条件的制约,就有些困难; 下面介绍一种方便的测量方法:在需要更换毛细管的冰箱的冷凝器输出端换一个双尾干燥过滤器,焊接好冷凝器的接头和工艺管(工艺管选择直径5毫米的铜管和三通压力表架,在选择一条基本上与原毛细管差不多直径的毛细管,长度在可根据压缩机的功率估计,一般在2.0米-2.8米之间,一端焊接到干燥过滤器的输出端,插入深度一般在0.5~1厘米左右不能太深,过深会触到干燥过滤器的过滤网上造成堵塞,也不能过短,太短会使赃物堵住毛细管的口径,焊接无误后,切开压缩机的工艺口,开启压缩机观查接在干燥过滤器上的压力表的压力,根据所用的制冷剂的不同选择压力的大小,如压力过高可截短一些毛细管,反之要加长,当基本上符合下面提供的压力范围内即可。下面提供不同的制冷剂的压力范围: R12 11.5~12.5KG/CM2 R134 10.5~11.5KG/CM2 R22 15.5~18KG/CM2 R600 9.6~10.5KG.CM2 在实际维修当中不断的测试及可得出标准的长度可供以后无需测试及可知道长度,但是必须和测试的毛细管的直径一致 3 . 自制冰箱、冰柜蒸发器和毛细管的速算方法!!! 在维修制冷设备时,如遇到冰箱、冰柜的蒸发器出现内漏时,一般可以不用拆动原蒸发器的盘管,在内包装皮的基础上可认重新盘管。然而计算所用铜管的长度,会使许多维修员感到头痛。下面介绍一种速算方法给大家,供参考。 一、速算方法 1.电冰箱蒸发器新管长度计算公式 管子总长度=冷冻室长度+冷藏室长度 冷冻室长度=1/3总容积(升)×0.148米/升 冷藏室长度=2/3总容积(升)×0.03米/升 2.电冰柜蒸发器新管长度计算公式 铜管总长度=1/3总容积×0.148米/升+2/3总容积×0.03米/升 注意:公式中介绍的铜管长度的计算方法,适合于直径为∮6mm和∮8mm的紫铜管 4.电冰箱要求压缩比达到1:10,才能使制冷系统达到设计规范。 电冰箱的压缩机是高压压缩机,本身的压缩比远远满足要求,所以1:10的压缩比就要有节流毛细管来控制了,毛细管加长可以增加压缩比,毛细管减短可以降低压缩比。 以制冷系统的低压压力0.06MPa为基准,则其绝对压力为0.16MPa,由于压缩比为1:10,所以高压压力是低压压力的10倍,则高压压力为1.6MPa,用压力表读数为1.5MPa。 实际调试毛细管的时候,是将压缩机的低压端开口放置在大气中,大气压力在表上的读数为0,实际的压力为0.1MPa。 在压缩机高压端接压力表和毛细管,由于毛细管的阻流产生了高压压力读数,高压压力也应该是低压压力的10倍,所以高压压力的只是1MPa,读数为0.9MPa。 其实一台好的电冰箱其压缩比可以达到1:12的,因此调试毛细管的长度高压读数为1.1MPa

函数指针的使用方法

对指针的应用是C语言编程的精髓所在,而回调函数就是C语言里面对函数指针的高级应用。简而言之,回调函数是一个通过函数指针调用的函数。如果你把函数指针(函数的入口地址)传递给另一个函数,当这个函数指针被用来调用它所指向的函数时,我们就说这个函数是回调函数。 为什么要使用回调函数呢?我们先看一个小例子: Node * Search_List (Node * node, const int value) { while (node != NULL) { if (node -> value == value) { break; } node = node -> next; } return node; } 这个函数用于在一个单向链表中查找一个指定的值,返回保存这个值的节点。它的参数是指向这个链表第一个节点的指针以及要查找的值。这个函数看上去很简单,但是我们考虑一个问题:它只能适用于值为整数的链表,如果查找一个字符串链表,我们不得不再写一个函数,其实大部分代码和现在这个函数相同,只是第二个参数的类型和比较的方法不同。 其实我们更希望令查找函数与类型无关,这样它就能用于查找存放任何类型值的链表了,因此必须改变比较的方式,而借助回调函数就可以达到这个目的。我们编写一个函数(回调函数),用于比较两个同类型的值,然后把一个指向这个函数的指针作为参数传递给查找函数,查找函数调用这个比较函数来执行比较,采用这个方法,任何类型的值得都可以进行比较。 我们还必须给查找函数传递一个指向待比较的值的指针而不是值本身,也就是一个void *类型的形参,这个指针会传递给回调函数,进行最终的比较。这样的修改可以让我们传递指向任何类型的指针到查找函数,从而完成对任何类型的比较,这就是指针的好处,我们无法将字符串、数组或者结构体作为参数传递给函数,但是指向它们的指针却可以。 现在,我们的查找函数就可以这样实现: NODE *Search_List(NODE *node, int (*compare)(void const *, void const *) , void const *desired_value); { while (node != NULL) { if (compare((node->value_address), desired_value) == 0) { break; } node = node->next; } return node; }

毛细现象

理论上细管中的水会上升,但实际上你几乎看不到,水受热膨胀的幅度是非常小的,除非细管特别特别细,但当管非常非常细的时候就算你不用手捂住瓶子,你也会看到细管中有一点水上升,这叫毛细现象。 现象: 液体表面类似张紧的橡皮膜,如果液面是弯曲的,它就有变平的趋势.因此凹液面对下面的液体施以拉力,凸液面对下面的液体施以压力。浸润液体在毛细管中的液面是凹形的,它对下面的液体施加拉力,使液体沿着管壁上升,当向上的拉力跟管内液柱所受的重力相等时,管内的液体停止上升,达到平衡。同样的分析也可以解释不浸润液体在毛细管内下降的现象。 毛细作用,是液体表面对固体表面的吸引力。毛细管插入浸润液体中,管内液面上升,高于管外,毛细管插入不浸润液体中,管内液体下降,低于管外的现象。毛巾吸水,地下水沿土壤上升都是毛细现象。在洁净的玻璃板上放一滴水银,它能够滚来滚去而不附着在玻璃板上。把一块洁净的玻璃板浸入水银里再取出来,玻璃上也不附着水银。这种液体不附着在固体表面上的现象叫做不浸润。对玻璃来说,水银是不浸润液体。 在自然界和日常生活中有许多毛细现象的例子。植物茎内的导管就是植物体内的极细的毛细管,它能把土壤里的水分吸上来。砖块吸水、毛巾吸汗、粉笔吸墨水都是常见的毛细现象。在这些物体中有许多细小的孔道,起着毛细管的作用。 有些情况下毛细现象是有害的。例如,建筑房屋的时候,在砸实的地基中毛细管又多又细,它们会把土壤中的水分引上来,使得室内潮湿。建房时在地基上面铺油毡,就是为了防止毛细现象造成的。 水沿毛细管上升的现象,对农业生产的影响很大。土壤里有很多毛细管,地下的水分经常沿着这些毛细管上升到地面上来。如果要保存地下的水分,就应当锄松地面的土壤,破坏土壤表层的毛细管,以减少水分的蒸发。 实验 不同液体的毛细现象 用三种液体进行比较:肥皂液、风油精、水。 拉伸的同一根尖嘴玻璃管,分别插入到三种液体中,上升的高度各不相同。风油精上升的高度最小,肥皂液其次。风油精实验,直接将玻璃管的尖端插入风油精的瓶中即可。

《神奇的水》说课稿

《神奇的水》说课 我今天说课的内容是苏教版《科学》三年级上册第三单元3课《神奇的水》,本课与《观察水》共同组成对水的认识。 教材分析: 本科以新课标为依据,通过一系列动手实践活动,让学生体会到水的神奇本领。在教学课程中,不但追求学科知识的严密性、完整性、逻辑性,更突出学科知识的整合,强调探究过程中的体验引导。学生从多角度看待水,将有关学习置于生命之源的广阔背景下,使学生体会到联系生活的教育所带来的魅力。本节课我将带领学生研究水的毛细现象和表面张力,并了解水的两个神奇本领在生活中的现象。 学情分析: 三年级的孩子刚刚接触到科学,对科学充满兴趣,但是没有掌握学习科学的方法,还需要老师细致的指导。三年级的孩子在此阶段主要是学会观察,学会动手做,学会记录。要培养良好的科学习惯,为以后科学学习打下基础。 教学目标: 1、了解水有毛细现象。 2、了解水有表面张力。 3、亲自动手完成实验并用自己擅长的方式记录。 教学重点: 认识水有毛细现象和表面张力现象。 教学难点: 寻找水在生活中的毛细现象和表面张力现象。 教学设计: 首先激发学生的兴趣,调动学生兴趣,爱玩是三年级孩子的天性,所以我在课的开始从学生日常生活中见过的水和怎么玩水入手,告诉他们老师会教他们新的玩法大大的调动学生的好奇心和探究欲望。 第二个环节,老师教孩子用纸棒做实验,让学生猜纸棒浸泡在红水里会发生什么现象,猜了以后让学生亲自动手做,通过实验发现水会爬上去。接下来比较,水能沿着纸爬上去,能不能沿着其他材料爬上去,课前我准备了纱布条,粉笔,塑料棒和玻璃棒,通过不同材料的比较来发现水是沿着有孔的材料爬上

去的,引出毛细现象的概念,接下来又准备了两个演示实验,红水滴在纸上和玻璃上,让学生辨析是不是毛细现象,为什么是和为什么不是,进一步加深了学生对毛细现象的认识。 认识了毛细现象之后,第三个环节设计的任务就是认识水的表面张力。同样先教会孩子滴管的使用,然后让孩子们猜一元硬币上能滴多少滴水水才会溢出来,同时用画图的方法把从侧面观察到的硬币上的水即将溢出来前的样子画在纸上。汇报的时候把各个小组画的图作比较会发现虽然画的有差异,但是共同点都是水面都会鼓起。发现这个现象以后,让孩子分组讨论为什么水鼓起来都不会溢出来,通过讨论更加深孩子对“团结的水”这一概念的形象认识,最后教师总结出水面张力。然后多媒体展示生活中的水面张力现象,把科学知识延伸到生活中去。 最后,为了更加深孩子的兴趣和对科学的热爱,我设计了一个游戏环节,利用水面张力让回形针浮在水面上,并让孩子上台试一试,没试的孩子就作为回家之后的兴趣活动。将课堂教学推向高潮。这时,学生的脑子就会冒出许许多多的问题,让孩子带着问题走出教室,从而激发学生课后探究的欲望。

实验四:函数与指针

陕西理工大学 《高级语言程序设计(C)》 实验报告 院系: 班级: 学号: 姓名:

目录 实验一:C开发环境与顺序结构程序设计 (2) 1.实验目的: (2) 2.实验环境: (2) 3.实验步骤: (2) 4.实验内容: (2) 5.实验总结 (9) 实验二:分支结构与循环结构程序设计 (10) 1.实验目的: (10) 2.实验环境: (10) 3.实验内容: (10) 4.实验总结 (18) 实验三数组及数组的应用 (19) 1.实验目的: (19) 2.实验环境: (19) 3.实验内容: (19) 4.实验总结: (20) 实验四:函数与指针 (20) 1.实验目的: (21) 2.实验内容: (21) 3.实验总结 (24)

实验一:C开发环境与顺序结构程序设计 1.实验目的: (1) 了解集成开发环境VC++6.0的使用方法,理解相关命令的含义,掌握编辑、编译、连接以及运行调试的方法,掌握程序的基本结构,掌握输入输出的方式。 (2) 掌握程序设计的基本要素中的数据类型、变量、运算符以及表达式的运用。 (3) 学会正确使用逻辑运算符和逻辑表达式以及关系运算符与关系表达式,掌握在程序设计中灵活使用顺序结构。 2.实验环境: (1) 硬件环境 CPU:Inter Pentium(R)4 CPU 3.00GHz 以上 内存:2GByte (2) 软件环境 操作系统:Microsoft Windows 7 编译系统:Microsoft Visual C++ 6.0 3.实验步骤: 按如图所示流程进行实验内容的 调试。 (1) 在XP操作系统中,启动 VC++6.0编译环境; (2) 在VC++6.0编译界面输入C源 程序; (3) 选择编译、组建、执行命令进 行编译、链接和运行,并记录实验 数据; (4) 按以上方法依次输入其他源程 序并调试、运行和记录实验数据。 4.实验内容: 4.1 输入并运行下列程序,查看程序运行的结果。 #include

C# 如何跨平台调用C++的函数指针

C# 如何跨平台调用C++的函数指针! 函数指针搞C++的人应该都知道,效率高,易用性强,隐蔽代码等。在C++里面调用C++写的dll的函数指针那是在容易不过了。使用C#就稍微麻烦点了!那怎么掉呢?通过上面的第一篇文章我们知道应该使用委托 delegate。如果再高级点,定义一个函数指针结构(有点像linux的内核),也同样可以用C#调用。 提示:委托就和C++中的函数指针一样 借用一下别人的列子:在C++的一个标准Win32 api 库ccLic.dll中有一个函数void* WINAPI GetFunctionAddress(unsigned int sn);此函数通过传sn序号得到函数指针即一个函数的地址.之后再通过返回回来的地址进行其它函数的调用那么我们必须知道.一个sn号对应的函数结构如 sn=1 -> bool WINAPI CCAskServerLicenseInfo(const char* server_address,unsigned short port,PCcLic_Info plicenseinfo) 在其中 typedef struct _CcLic_Info { char ower[64]; unsigned short manage_ip; unsigned short ramained_ip; unsigned short useable_time; unsigned char type; } CcLic_Info,*PCcLic_Info; 此列的目的就是通过C#调用 CCAskServerLicenseInfo 函数. [DllImport(@"ccLic.dll")] public static extern System.IntPtr Matrix(System.UInt32 sn);//声名入口函数 //定义函数指针模型 public delegate System.Int32 CCAskServerLicenseInfoHandle(Syste m.String servername, System.UInt16 port, System.IntPtr ptr); public static LicenseInfo GetLicentInfo(String server, System.UInt16

相关主题
文本预览
相关文档 最新文档