C language programming skills on the difference between const and #define _C language

Source: Internet
Author: User

#define Aspect_ratio 1.653

The compiler will never see aspect_ratio this symbol name, because before the source code into the compiler, it will be removed by the preprocessor, so aspect_ratio will not be added to the list of symbols. If the code involved in this constant is wrong in compiling the times, it can be confusing because the error message refers to 1.653, not aspect_ratio. If Aspect_ratio is not defined in your own header file, you will wonder where the 1.653 comes from and even take the time to track it down. This problem will also appear in the symbol debugger, because similarly, the symbol name you write will not appear in the symbol list.
The solution to this problem is simple: without preprocessing macros, define a constant:

Const double aspect_ratio = 1.653;


This method works well. But there are two special circumstances to be noted.

First, defining pointer constants is a little different. Because a constant definition is generally placed in a header file (many source files contain it), it is important that pointers are often defined as const, in addition to the type to be defined as const by the pointer. For example, to define a string constant based on char* in a header file, you would write a const two times:


const char * Const AUTHORNAME = "Scott Meyers";

Refer to clause 21 for the meaning and usage of const, especially the questions associated with pointers.

In addition, it is generally convenient to define the constants of a class (class), only a little bit different. To limit a constant to a class, first make it a member of the class, and to ensure that a constant has at most one copy, define it as a static member:

Class Gameplayer {
Private
static const int num_turns = 5; Constant Eclaration
int Scores[num_turns]; Use of constant
...
};


Also, as you can see, the above statement is a num_turns declaration, not a definition, so you must also define the static members of the class in the class's implementation code file:


const int Gameplayer::num_turns; Mandatory definition;
Goes in class Impl.file


You needn't worry too much about such trifles. If you forget to define it, the linker will remind you.


The older compiler will not accept this syntax because it considers the static members of the class to be illegal to define the initial value at the time of declaration, and only allow the initialization of integer types (such as int, bool, char, and so on) and only constants.
When the above syntax is not available, you can assign an initial value when you define it:
Class Engineeringconstants {//This goes in the class
Private://Header file
static const double Fudge_factor;
...
};
This is goes in the class implementation file
Const double engineeringconstants::fudge_factor = 1.35;


In most cases you just have to do so much. The only exception is when your class needs to use constants of this class at compile time, such as the declaration of the Gameplayer::scores array above (the compiler must know the size of the array during compilation). Therefore, in order to make up for the deficiencies of those compilers that prohibit the initialization of integer class constants within the class, it can be solved by means of a method called "borrowing enum". This technique makes good use of the principle of using an enumeration type when an int type is required, so gameplayer can also be defined like this:
Class Gameplayer {
Private
enum {num_turns = 5}//"The Enum hack"-makes
Num_turns a symbolic name
for 5
int scores[num_turns];//Fine
};


You do not have to borrow an enum unless you are using the old compiler (which is written before 1995). Of course, it's worth knowing that this is the way to go, because the code that goes back a long time ago is not common.


Back to the topic of pretreatment. Another common use of #define instructions is to use it to implement macros that look like functions without causing a function call. A typical example is to compute the maximum value of two objects:
#define MAX (A,b) ((a) > (b)? (a): (b))


There are a lot of flaws in this statement, it's a headache to think about, and it's even more painful than driving on the freeway during rush hours.
Whenever you write a macro like this, you have to remember to add parentheses to each parameter when you write the macro body, otherwise, if you use an expression when someone calls your macro, it can cause a lot of trouble. But even if you do, there will be strange things like the following:


int a = 5, b = 0;
Max (++a, b);//A's value increased 2 times
Max (++a, b+10); The value of a was only increased 1 times.


In this case, what happens inside Max depends on what value it compares!
Luckily you don't have to put up with such stupid statements. You can use ordinary functions to achieve the efficiency of macros, coupled with predictable behavior and type safety, which is the inline function (see clause 33):
inline int max (int a, int b) {return a > b a:b;}
However, this is not the same as the macro above, because this version of Max can only handle int types. But the template can be very lightweight to solve this problem:
Template<class t>
Inline const t& MAX (const t& A, const t& b)
{return a > b a:b;}


This template produces a whole set of functions, each of which takes two comparisons that can be converted to objects of the same type and then returns a reference to a larger (constant) object. Because you do not know the type of T, passing a reference when you return can improve efficiency (see article 22).


By the way, when you're going to use a template to write a useful generic function like Max, check the standard library (see clause 49) to see if they already exist. For example, Max above, you will be pleasantly surprised to find that you can Horong: Max is part of the C + + standard library.
With the const and inline, your need for preprocessing is reduced, but it cannot be completely without it. The days of abandoning #include are still far away, #ifdef/#ifndef在控制编译的过程中还扮演重要角色. Pretreatment is not yet retired, but you must plan to give it a lot of vacations

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.