静态,定义和用C常量 [英] Static, define, and const in C

查看:128
本文介绍了静态,定义和用C常量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我读过的静态变量用于内部功能时,一个不想要的变量值更改/每个函数被调用时初始化。但对之前的主例如。

在主程序中定义一个静态变量是什么

 的#include<&stdio.h中GT;静态双M = 30000;INT主要(无效)
{
值= M * 2 + 3;
}

下面的变量m具有不会得到在主程序后修饰的恒定值。在同样的思路又有什么区别有这些,而不是使用静态定义:

  const的双M = 30000;

 的#define米30000 // m或M

然后确保这里使用双操作的主要code,从而为M转换为正确的数据类型。


解决方案

 静态双M = 30000;双富(双X,双Y){
    返回X / M + Y;
}

这不赢你什么。 m的副本,必须做作了计算。
此外,如果你做的:

 双杆(双X,双Y){
     M + = X + Y;
     返回米;
}

然后,所有来电栏会改变米
函数(或类)外的静态变量与文件范围内真正的全局变量。其他文件无法被EXTERN在他们获得

在函数内部静态变量仍然像全局变量,除了在同一个文件中,即使其他功能不能直接看到它们。

  const的双M = 30000;

这是更好,而且在许多情况下,最好的。如果编译器看到这个全局常量,然后看向米的引用,然后它知道,而不是产生code加载从它在以往的价值(这可能需要加载文字地址到寄存器第一)到寄存器或堆叠位置做计算,它可以只是做一个寄存器是30000或有时就在那里产生与EN 30000 codeD的指令。

向下的一面来这是编译器必​​须假定其他烃源文件将要阅读米,具有对目标文件中的副本作为一个变量(但一个常数变量)实际存储。

我不知道,如果它是标准,但你有时可以做的extern const的双M = 30000; 和编译器将使用30000进行优化,并假定另一个文件实际上具有m的副本将存储在可执行。你也可以做静态常量双M = 30000; ,编译器可以假定没有人会想到,m的副本存储在生成的目标code从这个源文件。

 的#define米30000

的风险更高。如果previously有声明为一个变量,常量或函数另一个M,你不会得到警告或错误。此外,对于preprocessor宏这样很容易陷入困境。
例如:

 的#define BASE_ADDRESS 48
#定义MY_OFFSET 9
#定义MY_ADDRESS BASE_ADDRESS + MY_OFFSET
...
  返回MY_ADDRESS * 4;

是的,这是一个愚蠢的例子,但是这看起来像后,preprocessor得到它所做的就是

  ...
  回到48 + 9 * 4;

这是

 回48+(9 * 4);

这不是你想要的可能。

在哪里宏是不好的另一个地方是当你有大的常量,如字符串。串要求它们是由指针寻址和更难以优化掉比整数和浮点字面或常数。你可以轻松地做出一个非常大的项目,如果你有很多东西,如:

 的#define吉姆吉姆
#定义JOHN约翰

,然后用来JIM和约翰在你的程序,因为编译器可能无法看到你真的只需要字符串惦和约翰曾经在节目。

话虽这么说,这是并不少见,被宣告这样的常量,他们常常是由谁知道他们在做什么的人正确地那么做。

I've read that static variables are used inside function when one doesn't want the variable value to change/initialize each time the function is called. But what about defining a variable static in the main program before "main" e.g.

#include <stdio.h>

static double m = 30000;

int main(void)
{
value = m * 2 + 3;
}

Here the variable m has a constant value that won't get modified later in the main program. In the same line of thought what difference does it make to have these instead of using the static definition:

const double m = 30000;

or

#define m 30000  //m or M  

and then making sure here to use double operations in the main code so as to convert m to the right data type.

解决方案

static double m = 30000; 

double foo(double x, double y) {
    return x/m + y;
}

This doesn't win you anything. A copy of m has to be made to do the computation. Also if you do:

double bar( double x, double y) {
     m += x + y;
     return  m;
}

Then all calls to bar will change m. Static variables outside of functions (or classes) are really global variables with file scope. Other files can't get at them by extern

Static variables inside a function are still like global variables, except that even other functions in the same file can't see them directly.

const double m = 30000;

This is better and in many cases best. If the compiler sees this global const and then sees a reference to m then it knows that rather than generate code to load the value from where ever it is (which likely requires loading a literal address into a register first) to a register or stack position to do computations it can just make a register be 30000 or sometimes generate an instruction with 30000 encoded right in there.

The down side to this is that the compiler has to assume that other souce files will want to read m and has to actually store a copy as a variable (but a constant variable) in the object file.

I'm not sure if it is standard but you can sometimes do extern const double m = 30000; and the compiler will use 30000 to optimize and assume that another file actually has a copy of m that will be stored in the executable. You can also do static const double m = 30000; and the compiler can assume that no one else will expect that a copy of m is stored in the object code generated from this source file.

Doing

#define m 30000

is more risky. You will not get a warning or error if previously there was another m declared as a variable, constant, or function. Also, for preprocessor macros like this it is easy to mess up. For example:

#define BASE_ADDRESS 48
#define MY_OFFSET  9
#define MY_ADDRESS  BASE_ADDRESS+MY_OFFSET
...
  return MY_ADDRESS*4;

Yes, this is a stupid example, but what this looks like after the preprocessor gets done with it is

...
  return 48+9*4;

Which is

 return 48+(9*4);

And that's not what you probably wanted.

Another place where macros are bad is when you have large constants, such as strings. Strings require that they be addressable by pointer and are more difficult to optimize away than integers and floating point literal or constant numbers. You could easily make a very large program if you had lots of stuff like:

#define JIM "Jim"
#define JOHN "John"

and then used JIM and JOHN all over your programs because the compiler might not be able to see that you really only needed the strings "Jom" and "John" once in the program.

That being said, it is not uncommon to see constants being declared like that, and often they are properly done that way by people who know what they are doing.

这篇关于静态,定义和用C常量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆