Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

An example Analysis of the programming of CumberCraft +

2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article is to share with you the content of the sample analysis of the programming of CAccord Clipper +. The editor thinks it is very practical, so share it with you as a reference and follow the editor to have a look.

Main () function

Anyone who has studied C and C++ a little bit knows that the main () function is essential to all C and C++ programs. It's called the main function. All programs should start with the main () function. But how much do you know about this function?

We all know that C and C++ is a functional language, almost most of the functions are achieved through a variety of function calls, C and C++ also provide a wealth of function libraries for programmers to call. But although main () function every C program must have a function, there is no function called main () in C or C++ function library, it is a function that needs to be implemented by programmers.

And, have you noticed that main is not a reserved word for C and C++. So in theory, you can use the name main elsewhere, such as variable names, class names, namespace names, and even member function names. However, even so, you cannot change the function name of the main () function itself, or the connector will report an error.

The main () function is the entrance to C and C++ programs, because C and C++ language implementations have a startup function. For example, the startup function of MS-C++ is called

MainCRTStartup () or WinMainCRT-Startup (). The main () function is called at the end of the startup function, and then the exit () function is called to end the program. If there is no main () function, of course there will be an error. So the main () function is actually a callback function in C and C++ development environments. It needs to be realized by us.

Some students may have learned some application frameworks, such as MFC. The main () function is often not found in these program code, because those application frameworks hide the implementation of the main () function, and the main () function has a fixed implementation pattern here, so we don't need to write it. During the connection phase, the framework automatically adds the library that contains the main () implementation to the connection.

The main () function also has a prototype. This prototype is already a standard, and the prototype of main () is defined in ISO/IEC14882.

Int main () {/ *. * /} and int main (int argc, char * argv []) {/ *. * /}

The above two forms are the most portable and correct way to write. Of course, different compilers may allow some extensions. For example, allow main () to return void, or have a third parameter char * env [] or something. This depends on the specific compiler documentation.

With regard to the return value, we know that main () returns of type int. Exactly what is returned has different meanings. In general, a return of 0 indicates that the program ends normally, and any non-0 indicates an error or abnormal exit. As mentioned earlier, the startup function ends up with a call to the exit () function. Then the return value of the main () function is returned to the operating system as the Operand of the exit () function.

There are some special restrictions on the main () function in C++. For example:

Cannot be overloaded

Cannot be inline

Cannot be defined as static

His address cannot be taken.

Cannot be called by the user himself

With regard to the parameters of the main () function, it gives the compiled executor the ability to handle command-line arguments. It is important to note here that "command-line arguments" are not confused with "function arguments" of the main () function, which are two different concepts. The command line arguments are intercepted by the launcher and packaged into a string array and passed to the formal parameter argv [] of main (), while the number of all parameters, including the command word (that is, the name of the execution file), is passed to the formal parameter argc. Give it a try. Let's simulate the copy command and write a simple file copy program.

/ / mycopy.c: file copy program. # include int main (int argCount, char* argValue []) {FILE * srcFile = 0; FILE * destFile = 0; int ch = 0; if (argCount! = 3) {printf ("usage:% s original file target file\ n", argValue [0]) } else {if ((srcFile = fopen (argValue [1], "r")) = = 0) {printf ("unable to open the original file! \ "% s\"!, argValue [1]);} else {if ((destFile = fopen (argValue [2], "w")) = = 0) {printf ("unable to open the target file!" \ "% s\"!, argValue [2]); fclose (srcFile);} else {while ((ch = fgetc (srcFile))! = EOF) {fputc (ch,destFile);} fclose (srcFile) Fclose (destFile); return 0;} return 1;} / / usage: mycopy C:\ file1.dat D:\ newfile.dat Internal name

If there is no main () function when writing a C program, the connector will report an error. General error message will prompt "unresolved external symbol_main". The "_ main" here is actually the internal name generated by the compiler for main. In fact, C and C++ languages will convert user-defined identifiers (functions, variables, types, namespaces, etc.) into corresponding internal names according to specific rules during compilation. These rules are also related to the specified connection specification. For example, in the C language, the internal name of main is _ main.

The C language does this by telling the connector that this thing is a function. In fact, the C language actually prefixes all function names with the prefix "_" to distinguish function names from other identifier names.

This kind of regulation is a different kind of thing in C++. This is because in C #, all functions are global functions with extern connection type and global scope as long as they are not static functions that are local to the compilation unit (file scope). Global functions cannot have the same name. But in C++, functions with the same name can be defined in different scopes, such as class,struct,union,namespace, and even in the same scope, that is, function overloading. Then the connection specification converted to an internal name is a little more complicated. For example:

Class Sample_1 {char m_name [16]; public: void foo (char * newName); void foo (int age);}; class Sample_2 {char m_name [16]; public: void foo (char * newName); void foo (bool sex);}

Elsewhere, generate two instances based on these two classes and do the following:

Sample_1 a; Sample_2 b; a.foo ("aaa"); a.foo (100); b.foo ("bbb"); b.foo (false)

There are four functions, but they are the same name. How should the compiler distinguish? Distinguished by the member identifiers of their respective objects? That is distinguished in the code, but from the connector's point of view, all functions are actually global functions, and global functions cannot be renamed. So in order to avoid ambiguity, there is a name modification rule in C++. That is, add the name of the scope at all levels and the encoded parameter information of the overloaded function before the function name. For example, the above four calls to the foo function, in fact, they will call four functions with global names, which are Sample_1_foo@pch@1,Sample_1_foo@int@1,Sample_2_foo@pch@1,Sample_2_foo@int@1.

However, this standard is not mandatory, so C++ compilers developed by different manufacturers may be slightly different, which is the reason why different manufacturers of C++ compilers and connectors are not compatible.

Well, when you use different programming languages for joint development, you need to define a unified specification, which is called a connection specification. This is easy to understand, because if the same identifier uses different join specifications in different compilation units, it will result in inconsistent internal names, and the connection will certainly fail.

Therefore, be sure to make it clear which connection specification you want to use when developing libraries. For example, to write a C program is to specify the C connection specification: extern "C". There are about several situations:

Specify the connection specification for only one type, function, variable, or constant

Extern "C" void WinMainCRTStartup (); extern "C" const CLSID CLSID_DataConverter; extern "C" struct Student {/ *.... * /}; extern "C" Student g_Student

Define the connection specification for a piece of code

# ifdef _ cplusplus extern "C" {# endif const int MAX_AGE = 200; # pragma pack (push,4) typedef struct _ Person {char * PersonPtr; name; int masked Age;} Person, * PersonPtr; # pragma pack (pop) Person glossy Me; int _ cdecl memcmp (const void*, const void*, size_t); void* _ cdecl memcpy (void*, const void*, size_t) Void* _ _ cdecl memset (void*, int, size_t); # ifdef _ _ cplusplus} # endif

Currently uses the C++ compiler, and uses extern "C" to define the connection specification of a piece of code, but wants to maintain the connection specification of C++ in a line or piece of code.

# ifdef _ _ cplusplus extern "C" {# endif const int MAX_AGE = 200; # pragma pack (push,4) typedef struct _ Person {char * PersonPtr; _ cdecl memcmp (const void*, const void*, size_t);} Person, * PersonPtr; # pragma pack (pop) Person gourmet; # if _ SUPPORT_EXTERN_CPP_ extern "C++" {# endif int _ cdecl memcmp (const void*, const void*, size_t) Void* _ _ cdecl memcpy (void*, const void*, size_t); # if _ SUPPORT_EXTERN_CPP_} # endif void* _ cdecl memset (void*, int, size_t); # ifdef _ cplusplus} # endif

If the connection specification for an identifier specified in a declaration is extern "C", the corresponding definition should also specify extern "C":

# ifdef _ _ cplusplus extern "C" {# endif memcmp (const void*, const void*, size_t); # ifdef _ cplusplus} # endif # ifdef _ cplusplus extern "C" {# endif memcmp (const void* p, const void* a, size_t len) {/ / function implementation} # ifdef _ cplusplus} # endif

In fact, if it is interface-oriented programming, you don't have to think so much about it. Because even if the internal names of the two ends of the interface are different, as long as you use a consistent member to it and arrange it, and follow a consistent calling specification, a consistent function implementation. That is, C++ consistent object model, then basically there will be no problem.

Variable and its initialization

In C and C++, global variables (extern or static) are stored in the static data area of the program. These variables are created before the program enters main () and destroyed after main (). C and C++ provide a default global initializer 0. That is, the compiler initializes them with 0 by default. The static variable inside the function and the static member of the class are also in the static store, so it is also initialized to 0 by default. Unless you provide the initial value when you create it. This is how the compiler treats static variables. For other automatic variables, we need to initialize them. Don't expect the compiler to initialize them automatically.

Therefore, the declaration and definition of global variables should be placed at the beginning of the source file.

There is a difference between the initialization of a variable and its assignment. Initialization occurs when the variable is created, and assignment is done after the variable is created in the program.

As mentioned earlier, initialization of variables in static storage (such as global variables, static variables, etc.) is automatically performed by the compiler, but initialization of local variables does require programmers to do so manually.

Also, in one programming unit, the initial value of a global variable does not depend on the global variable of another compilation unit. What does it mean? For example:

/ / file1.cint Groux = 100Tracacap file2.cextern int gourmx nbsp; double glossd = Groux + 10

After the two compilation units are compiled, they are connected. It is uncertain which of the two global variables should be initialized first, and the connector cannot guarantee this. Initialize groomx first, then groomd can be initialized smoothly, and vice versa, gexpand is not necessarily much.

In addition, both C and C++ have off-the-shelf libraries. These are the * .h files included at the beginning of the file. Note that C library can be multi-threaded version and single-threaded version, the development of multithreaded programs should use multi-threaded version of the library. In addition, in multi-person development software, the version of the library must be unified.

Compile time and run time

Some of the features written by source code files work at runtime and some at compile time. This matter needs to be distinguished. For example, precompiled directives, class definitions, external object declarations, function prototypes, modifier symbols (const,static those), class member access description symbols (public, private those), and connection specifications play a role at compile time, which do not exist in executable programs. Container cross-boundary access, dynamic resolution of virtual functions, dynamic join, dynamic memory allocation, exception handling, and RTTI play a role at run time. For example:

Int* pInt = new int [10]; pInt + = 100th cout

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report