下面的函数调用方式对不对(c语言随机函数)?

文档贡献者
该文档贡献者很忙,什么也没留下。
下载此文档
正在努力加载中...
C语言中函数形参与实参的结合方式
文档星级:
内容提示:道客巴巴文档,C语言中函数形参与实参的结合方式,c语言中实参和形参,c语言 形参 实参,c语言形参和实参,c语言形参,c语言 形参 为数组,函数的实参和形参,c语言 实参,形参和实参,实参 形参,实参和形参的区别,值得下载、分享、收藏。
文档格式:PDF|
浏览次数:6|
上传日期: 15:57:29|
下载积分:
该用户还上传了这些文档
官方公共微信
下载文档:C语言中函数形参与实参的结合方式.PDF采用汇编语言对C语言函数调用方法求平均数 - 下载频道 - CSDN.NET
&&&&采用汇编语言对C语言函数调用方法求平均数
&采用汇编语言对C语言函数调用方法求平均数
这是一个简单的例子,说明了C程序和汇编程序的关系。
若举报审核通过,可奖励20下载分
被举报人:
chenjun_dzlt
举报的资源分:
请选择类型
资源无法下载
资源无法使用
标题与实际内容不符
含有危害国家安全内容
含有反动色情等内容
含广告内容
版权问题,侵犯个人或公司的版权
*详细原因:
您可能还需要
Q.为什么我点的下载下不了,但积分却被扣了
A. 由于下载人数众多,下载服务器做了并发的限制。若发现下载不了,请稍后再试,多次下载是不会重复扣分的。
Q.我的积分不多了,如何获取积分?
A. 传优质资源可以获取积分,详细见。选择完成有奖的任务,可以获取积分。选择购买VIP会员服务,无需积分下载资源。评价资源返积分:第一次绑定手机,将获50下载积分及100论坛可用分。论坛可用分兑换下载积分。
下载资源意味着您已经同意遵守以下协议
资源的所有权益归上传用户所有
未经权益所有人同意,不得将资源中的内容挪作商业或盈利用途
CSDN下载频道仅提供交流平台,并不能对任何下载资源负责
下载资源中如有侵权或不适当内容,
本站不保证本站提供的资源的准确性,安全性和完整性,同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
开发技术下载排行
你下载资源过于频繁,请输入验证码
如何快速获得积分?
你已经下载过该资源,再次下载不需要扣除积分
采用汇编语言对C语言函数调用方法求平均数
所需积分:1
剩余积分:
VIP会员,免积分下载
会员到期时间:日
剩余下载次数:10001056人阅读
C语言和C++语言的函数调用
摘要:尽管C/C++函数缺省采用cdecl调用规范,但是二者在细节处理上还是有一些差别。使用VC++编译器默认为__cdecl调用规范,C语言函数严格遵守此规范,但是对于C++函数由于可以重载,即几个函数的函数名可以相同,但是参数类型或参数个数必须不同,因此C++的输出函数名要能反映函数的调用规范、参数个数甚至参数类型等。为了能够使C++函数被C语言或汇编语言以及C++的其他模块调用,则应在定义C++函数的模块进行外部函数声明:extern
&C& 返回值类型 函数名(形参表);。
&&& 这几天在研究混合编程的问题,尽管C/C++函数缺省采用cdecl调用规范,这种约定遵循以下3个原则:
(1)在函数名前自动加一个下划线;
(2)参数由右至左入栈;
(3)由函数的调用者负责平衡堆栈。
&&& 但是在使用Visual C++ 6.0编译系统,采用cdecl调用规范,测试函数名为qsum,在对输出的列表文件进行对比时发现:
对于C语言的函数(源文件扩展名为C),以上3个原则都符合,并且自动在函数名前加_,函数经编译后函数名为_qsum;但是对于C++的函数(原文件扩展名为CPP),只符合第(2)和第(3)个原则,对于函数名经编译后变为?qsum@@YAHPAFH@Z(并且不管什么调用规范函数名都采用类似的命名规则)。于是又在网上查了一些资料,发现C和C++的函数调用在细节处理上有些区别的。
一. C++的输出函数命名规则
&&& C++的输出函数名规则有些复杂,但是信息更充分,通过分析修饰名不仅能够知道函数的调用方式,返回值类型,参数个数甚至参数类型。不管__cdecl,__fastcall还是__stdcall调用方式,函数修饰都是以一个“?”开始,后面紧跟函数的名字,再后面是参数表的开始标识、函数返回值类型代号以及参数表参数类型代号。对于__stdcall方式,参数表的开始标识是&@@YG”,对于__cdecl方式则是&@@YA”,对于__fastcall方式则是&@@YI”。参数表的类型代号如下所示:
X--void&&&
D--char&&&
E--unsigned char&&&
F--short&&&
I--unsigned int&&&
J--long&&&
K--unsigned long(DWORD)
M--float&&&
N--double&&&
O--long double
PA--指针前缀
AA--引用前缀
V类名@@--类
&&& 指针的方式有些特别,用PA表示指针,用PB表示const类型的指针。后面的代号表明指针类型,如果相同类型的指针连续出现,以&0&代替,一个&0&代表一次重复。如果相同类型的引用连续出现,则以“1”代替,每个“1”都代表一次重复。U表示结构类型,通常后跟结构体的类型名,用“@@”表示结构类型名的结束。参数表后以&@Z”标识整个名字的结束,如果该函数无参数,则以“Z”标识结束。例如:
int qsum(short *ary, int num)----?qsum@@YAHPAFH@Z
void test()----?test@@YAXXZ
二. C/C++函数的定义和调用方式
1. C函数的定义和调用
(1)C的函数定义
/*c code*/
int qsum(short *ary, int num){...}
(2)C函数的调用
//c++ code
/*c code外部函数声明改为: extern int qsum(int *, int);*/
extern &C& {int qsum(short *, int);}
void test()
&&& qsum(ary, 10);
(3)extern &C&和#ifdef __cplusplus
&&& 在C++中调用C语言中的函数时,需要在使用extern &C&关键字声明C语言中定义的函数,目的是告诉编译器,在链接时该函数遵循C语言的约定。对于C语言头文件中的函数,可以使用extern &C& {#include &xxx.h&}对该头文件中的所有外部函数加以声明。
&&& 当然,比较好的方法是采用以下方法书写C语言的头文件:
&&& #ifdef __cplusplus
&&& extern &C& {
&&& #endif
&&&&&&& //C语言的函数声明
&&& #ifdef __cplusplus
&&& #endif
&&& 这样,就可以直接在源程序中加入头文件了,而不管是C或者C++源程序。
2. C++函数的定义和调用方式
(1)C++函数定义
//c++ code
extern &C& {int qsum(short *, int);}
int qsum(short *ary, int num){...}
如果有多个函数供C语言使用,则可以将函数声明放在头文件中。
(2)C++函数的调用
/*c code*/
//c++ code函数声明修改为:extern &C& int qsum(short *, int);
extern int qsum(short *, int);
void test()
&&& qsum(ary, 10);
&&& 因此,对于C++函数,如果要供C语言、汇编语言以及C++的其他模块,则应在定义函数的模块进行外部函数声明,格式:extern &C& 返回值类型 函数名(形参表);。这样,前面提到的3个原则都会遵守,函数名前会自动加下划线。
3. 如何使用C++中的类接口?
& & C++是面向对象的语言,支持类封装。但是对象的创建与操作只能在C++中实现。如果想在C语言中调用类中的接口,应该在C++中使用全局函数,即非类中的方法实现 ,在该全局函数中创建对象,并使用类中的方法对该对象进行操作。然后按照上述方法加以声明,就可以在C源程序中调用该全局方法,可见参考资料[6]。或者使用Mr. Stephen Clamage所建议的方法,见参考资料[5]。
&&& ANSI C++委员会主席Mr. Stephen Clamage的文章非常好,这里给出其最新链接“”,如链接失效,可以打开参考资料[5]的链接,或者直接到本文的附录阅读
参考资料:
1. 王成耀,80x86汇编语言程序设计(第2版),人民邮电出版社,2008
2. 星轨(oRbIt),C/C++函数调用约定与函数名称修饰规则探讨,,2006
3. Bjarne Stroustrup's homepage,,May 21, 2009&&
4. C++项目中的extern &C& {}, ,
5. Stephen Clamage, Mixing C and C++ Code in the Same Program, ,
(ANSI C++委员会主席Mr. Stephen
Clamage的原文附下)
6. C/C++混合编程, ,
下面附上Mr. Stephen Clamage的一篇文章,出自Oracle网站
Mixing C and C++ Code in the Same Program
Updated February 2011
By , Oracle Solaris Studio Engineering
The C++ language provides mechanisms for mixing code that is compiled by compatible C and C++ compilers in the same program. You can experience varying degrees of success as you port such code to different platforms and compilers. This article shows how
to solve common problems that arise when you mix C and C++ code, and highlights the areas where you might run into portability issues. In all cases we show what is needed when using Oracle Solaris Studio C and C++ compilers.
Using Compatible Compilers
The first requirement for mixing code is that the C and C++ compilers you are using must be compatible. They must, for example, define basic types such as int, float or pointer in the same way. The Oracle Solaris operating system specifies the Application
Binary Interface (ABI) of C programs, which includes information about basic types and how functions are called. Any useful compiler for Oracle Solaris must follow this ABI.
Oracle Solaris Studio C and C++ compilers follow the Oracle Solaris ABI and are compatible. Third-party C compilers for Oracle Solaris usually also follow the ABI. Any C compiler that is compatible with the Oracle Solaris Studio C compiler is also compatible
with the Oracle Solaris Studio C++ compiler.
The C runtime library used by your C compiler must also be compatible with the C++ compiler. C++ includes the standard C runtime library as a subset, although there are a few differences. If the C++ compiler provides its own versions of the C headers, the
versions of those headers used by the C compiler must be compatible.
Oracle Solaris Studio C and C++ compilers use compatible headers, and use the same C runtime library. They are fully compatible.
Accessing C Code from Within C++ Source
The C++ language provides a &linkage specification& with which you declare that a function or object follows the program linkage conventions for a supported language. The default linkage for objects and functions is C++. All C++ compilers also support C
linkage, for some compatible C compiler.
When you need to access a function compiled with C linkage (for example, a function compiled by the C compiler, or a function written in assembler), declare the function to have C linkage. Even though most C++ compilers do not have different linkage for
C and C++ data objects, you should declare C data objects to have C linkage in C++ code. With the exception of the pointer-to-function type, types do not have C or C++ linkage.
Declaring Linkage Specifications
Use one of the following notations to declare that an object or function has the linkage of language language_name:
extern &language_name& declaration ;
extern &language_name& { declaration ; declaration ; ... }
The first notation indicates that the declaration (or definition) that immediately follows has the linkage of language_name. The second notation indicates that everything between the curly braces has the linkage of language_name, unless
declared otherwise. Notice that you do not use a semicolon after the closing curly brace in the second notation.
You can nest linkage specifications, but the braces do not create scopes. Consider the following example:
extern &C& {
// C linkage
extern &C++& {
// C++ linkage
extern &C& void h(); // C linkage
void g2();
// C++ linkage
extern &C++& void k(); // C++ linkage
// C linkage
All the functions above are in the same global scope, despite the nested linkage specifiers.
Including C Headers in C++ Code
If you want to use a C library with its own defining header that was intended for C compilers, you can include the header in
extern &C& brackets:
extern &C& {
#include &header.h&
Warning: Do not use this technique for system headers on Oracle Solaris. Oracle Solaris headers, and all the headers that come with Oracle Solaris Studio C and C++ compilers, are already configured for use with C and C++ compilers. You can
invalidate declarations in Oracle Solaris headers if you specify a linkage.
Note: For other than system headers, check to see whether the header was written to work with C++ that is, whether it already has linkage specifications. If so, you should not enclose the header in
extern &C& brackets.
Creating Mixed-Language Headers
If you want to make a header suitable for both C and C++ compilers, you could put all the declarations inside extern &C& brackets, but the C compiler does not recognize the syntax. Every C++ compiler predefines the macro__cplusplus, so
you can use that macro to guard the C++ syntax extensions:
#ifdef __cplusplus
extern &C& {
... // body of header
#ifdef __cplusplus
} // closing brace for extern &C&
Adding C++ Features to C Structs
Suppose you want to make it easier to use a C library in your C++ code. And suppose that instead of using C-style access, you want to add virtual or non-virtual member functions, derive from the class, and so on. How can you accomplish this transformation
and ensure the C library functions can still recognize the struct? Consider the uses of the C
struct buf in the following example:
struct buf {
void buf_clear(struct buf*);
buf_print(struct buf*); // return status, 0 means fail
buf_append(struct buf*, const char*, unsigned count); // same return
You want to turn this struct into a C++ class and make it easier to use with the following changes:
extern &C& {
#include &buf.h&
class mybuf { // first attempt -- will it work?
mybuf() : data(0), count(0) { }
void clear() { buf_clear( (buf*)this ); }
bool print() { return buf_print( (buf*)this ); }
bool append(const char* p, unsigned c)
{ return buf_append( (buf*)this, p, c ); }
The interface to the class mybuf looks more like C++ code, and can be more easily integrated into an object-oriented style of programming -- if it works.
What happens when the member functions pass the this pointer to the
buf functions? Does the C++ class layout match the C layout? Does the this pointer point to the
data member, as a pointer to buf does? What if you add virtual functions to mybuf?
The C++ standard makes no promises about the compatibility of struct buf and class mybuf. This code, without virtual functions, might work, but you can't count on it. If you add virtual functions, the code will fail using compilers that
add extra data (such as pointers to virtual tables) at the beginning of a class.
The portable solution is to leave struct buf strictly alone, even though you would like to protect the data members and provide access only through member functions. You can guarantee C and C++ compatibility only if you leave the declaration unchanged.
You can derive a C++ class mybuf from the C struct buf, and pass pointers to the
buf base class to the mybuf functions. If a pointer to mybuf doesn't point to the beginning of the buf data, the C++ compiler will adjust it automatically when converting a mybuf* to a
buf*. The layout of mybuf might vary among C++ compilers, but the C++ source code that manipulates mybuf and
buf objects will work everywhere. The following example shows a portable way to add C++ and object-oriented features to a C struct.
extern &C& {
#include &buf.h&
class mybuf : public buf { // a portable solution
mybuf() : data(0), count(0) { }
void clear() { buf_clear(this); }
bool print() { return buf_print(this); }
bool append(const char* p, unsigned c)
{ return buf_append(this, p, c); }
C++ code can freely create and use mybuf objects, passing them to C code that expects buf objects, and everything will work together. Of course, if you add data to mybuf, the C code won't know anything about it. That's a general
design consideration for class hierarchies. You also have to take care to create and delete buf and mybuf objects consistently. It is safest to let C code delete (free) an object if it was created by C code, and not allow C code
to delete a mybuf object.
Accessing C++ Code from Within C Source
If you declare a C++ function to have C linkage, it can be called from a function compiled by the C compiler. A function declared to have C linkage can use all the features of C++, but its parameters and return type must be accessible from C if you want
to call it from C code. For example, if a function is declared to take a reference to an IOstream class as a parameter, there is no (portable) way to explain the parameter type to a C compiler. The C language does not have references or templates or classes
with C++ features.
Here is an example of a C++ function with C linkage:
#include &iostream&
extern &C& int print(int i, double d)
std::cout && &i = & && i && &, d = & &&
You can declare function print in a header file that is shared by C and C++ code:
#ifdef __cplusplus
extern &C&
int print(int i, double d);
You can declare at most one function of an overloaded set as extern &C& because only one C function can have a given name. If you need to access overloaded functions from C, you can write C++
wrapper functions with different names as the following example demonstrates:
double g(double);
extern &C& int
g_int(int i)
{ return g(i); }
extern &C& double g_double(double d) { return g(d); }
Here is the example C header for the wrapper functions:
int g_int(int);
double g_double(double);
You also need wrapper functions to call template functions because template functions cannot be declared as
extern &C&:
template&class T& T foo(T t) { ... }
extern &C& int
foo_of_int(int t) { return foo(t); }
extern &C& char* foo_of_charp(char* p) { return foo(p); }
C++ code can still call the overloaded functions and the template functions. C code must use the wrapper functions.
Accessing C++ Classes from C
Can you access a C++ class from C code? Can you declare a C struct that looks like a C++ class and somehow call member functions? The answer is yes, although to maintain portability you must add some complexity. Also, any modifications to the definition
of the C++ class you are accessing requires that you review your C code.
Suppose you have a C++ class such as the following:
virtual int foo(int);
You cannot declare class M in your C code. The best you can do is to pass around pointers to class M objects, like the way you deal with FILE objects in C Standard I/O. You can write extern &C& functions in C++ that access class
M objects and call them from C code. Here is a C++ function designed to call the member functionfoo:
extern &C& int call_M_foo(M* m, int i) { return m-&foo(i); }
Here is an example of C code that uses class M:
struct M; // you can supply only an incomplete declaration
int call_M_foo(struct M*, int); // declare the wrapper function
int f(struct M* p, int j) // now you can call M::foo
{ return call_M_foo(p, j); }
Mixing IOstream and C Standard I/O
You can use C Standard I/O from the standard C header &stdio.h& in C++ programs because C Standard I/O is part of C++.
Any considerations about mixing IOstream and Standard I/O in the same program therefore do not depend on whether the program contains C code specifically. The issues are the same for purely C++ programs that use both Standard I/O and IOstreams.
Oracle Solaris Studio C and C++ use the same C runtime libraries, as noted in the section about compatible compilers. Using Oracle Solaris Studio compilers, you can therefore use Standard I/O functions freely in both C and C++ code in the same program.
The C++ standard says you can mix Standard I/O functions and IOstream functions on the same target &stream&, such as the standard input and output streams. But C++ implementations vary in their compliance. Some systems require that you call the
sync_with_stdio() function explicitly before doing any I/O. Implementations also vary in the efficiency of I/O when you mix I/O styles on the same stream or file. In the worst case, you get a system call per character input or output. If the program
does a lot of I/O, the performance might be unacceptable.
The safest course is to use only one of Standard I/O or IOstream styles on any given file or standard stream. Using Standard I/O on one file or stream and IOstream on a different file or stream does not cause any problems.
Working with Pointers to Functions
A pointer to a function must specify whether it points to a C function or to a C++ function, because it is possible that C and C++ functions use different calling conventions. Otherwise, the compiler does not know which kind of function-calling code to generate.
Most systems do not have different calling conventions for C and C++, but C++ allows for the possibility. You therefore must be careful about declaring pointers to functions, to ensure that the types match. Consider the following example:
typedef int (*pfun)(int);
extern &C& void foo(pfun); // line 2
extern &C& int g(int)
foo( g ); // Error!
Line 1 declares pfun to point to a C++ function, because it lacks a linkage specifier.
Line 2 therefore declares foo to be a C function that takes a pointer to a C++ function.
Line 5 attempts to call foo with a pointer to g, a C function, a type mismatch.
Be sure to match the linkage of a pointer-to-function with the functions to which it will point. In the following corrected example, all declarations are insideextern &C& brackets, ensuring that the types match.
extern &C& {
typedef int (*pfun)(int);
void foo(pfun);
int g(int);
foo( g ); // now OK
Pointers to functions have one other subtlety that occasionally traps programmers. A linkage specification applies to all the parameter types and to the return type of a function. If you use the elaborated declaration of a pointer-to-function in a function
parameter, a linkage specification on the function applies to the pointer-to-function as well. If you declare a pointer-to-function using a typedef, the linkage specification of that typedef is not affected by using it in a function declaration.
For example, consider this code:
typedef int (*pfn)(int);
extern &C& void foo(pfn p) { ... }
// definition
extern &C& void foo( int (*)(int) ); // declaration
The first two lines might appear in a program file, and the third line might appear in a header where you don't want to expose the name of the private typedef. Although you intended for the declaration of foo and its definition to match, they do
not. The definition of foo takes a pointer to a C++ function, but the declaration of
foo takes a pointer to a C function. The code declares a pair of overloaded functions. You might find that the program fails to link to due an unresolved symbol.
To avoid this problem, use typedefs consistently in declarations, or enclose the typedefs in appropriate linkage specifications. For example, assuming you wanted foo to take a pointer to a C function, you could write the definition of foo
extern &C& {
typedef int (*pfn)(int);
void foo(pfn p) { ... }
Working with C++ Exceptions
Propagating Exceptions
What happens if you call a C++ function from a C function, and the C++ function throws an exception? The C++ standard is somewhat vague about whether you can expect exceptions to behave properly, and on some systems you have to take special precautions.
Generally, you must consult the user manuals to determine whether the code will work properly.
No special precautions are necessary with Oracle Solaris Studio C++. The exception mechanism in Oracle Solaris Studio C++ does not affect the way functions are called. If a C function is active when a C++ exception is thrown, the C function is passed over
in the process of handling the exception.
Mixing Exceptions with set_jmp and long_jmp
The best advice is not to use long_jmp in programs that contain C++ code. The C++ exception mechanism and C++ rules about destroying objects that go out of scope are likely to be violated by along_jmp, with unpredictable results. Some compilers
integrate exceptions andlong_jmp, allowing them to work together, but you should not depend on such behavior. Oracle Solaris Studio C++ uses the sameset_jmp andlong_jmp as the C compiler.
Some C++ experts believe that long_jmp should not be integrated with exceptions, due to the difficulty of specifying exactly how it should behave.
If you use long_jmp in C code that you are mixing with C++, ensure that along_jmp does not cross over an active C++ function. If you cannot ensure that, see if you can compile that C++ code with exceptions disabled. You still might have
problems if the destructors of local objects are bypassed.
Linking the Program
At one time, most C++ compilers required that function main be compiled by the C++ compiler. That requirement is not common today, and Oracle Solaris Studio C++ does not require it. If your C++ compiler needs to compile the main function but you
cannot do so for some reason, you can change the name of the C main function and call it from a wrapper version of C++ main. For example, change the name of the C main function to
C_main, and write this C++ code:
extern &C& int C_main(int, char**); // not needed for Oracle Solaris Studio C++
int main(int argc, char** argv) { return C_main(argc, argv); }
Of course, C_main must be declared in the C code to return an int, and it will have to return an int value. As noted above, you do not need to go to this trouble with Oracle Solaris Studio C++.
Even if your program is primarily C code but makes use of C++ libraries, you need to link C++ runtime support libraries provided with the C++ compiler into your program. The easiest and best way to do that is to use
CC, the C++ compiler driver, to do the linking. The C++ compiler driver knows what libraries to link, and the order in which to link them. The specific libraries can depend on the options used when compiling the C++ code.
Suppose you have C program files main.o, f1.o, and f2.o, and you use a C++ library helper.a. With Oracle Solaris Studio C++, you would issue the command.
CC -o myprog main.o f1.o f2.o helper.a
The necessary C++ runtime libraries like libCrun and libCstd are linked automatically. The documentation for helper.a might require that you use additional link-time options. If you can't use the C++ compiler for some reason, you can use the
-dryrun option of the CC command to get the list of commands the compiler issues, and capture them into a shell script. Since the exact commands depend on command-line options, you should review the output from -dryrun with any change of the
command line.
For More Information
for the latest information on the Oracle Solaris Studio C and C++ compilers and tools, including man pages and readme files.
About the Author
Steve Clamage has been at Sun (now Oracle) since 1994. He is currently technical lead for the C++ compiler and the Oracle Solaris Studio Compiler Collection. He has been chair of the ANSI C++ Committee since 1995.
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:156401次
积分:2497
积分:2497
排名:第5436名
原创:71篇
转载:56篇
评论:46条
(2)(2)(1)(1)(1)(1)(1)(3)(1)(1)(1)(1)(3)(1)(2)(8)(3)(7)(4)(1)(6)(4)(12)(10)(20)(1)(3)(1)(1)(2)(3)(21)}

我要回帖

更多关于 c语言随机函数 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信