В чем разница между статической и константной переменными? - PullRequest
58 голосов
/ 07 февраля 2010

Может кто-нибудь объяснить разницу между static и const переменной?

Ответы [ 16 ]

38 голосов
/ 07 февраля 2010

Постоянное значение не может измениться. Статическая переменная существует для функции или класса, а не для экземпляра или объекта.

Эти два понятия не являются взаимоисключающими и могут использоваться вместе.

24 голосов
/ 07 февраля 2010

Краткий ответ:

A const - это обещание, что вы не будете пытаться изменить значение после его установки.

Переменная static означает, что время жизни объекта - это полное выполнение программы, и его значение инициализируется только один раз перед запуском программы. Вся статика инициализируется, если вы не указали для них явное значение. Способ и время статической инициализации не указано .

C99 заимствовал использование const из C ++. С другой стороны, static был источником многих дискуссий (на обоих языках) из-за его часто сбивающей с толку семантики.

Кроме того, с C ++ 0x до C ++ 11 использование ключевого слова static не рекомендуется для объявления объектов в области имен. Это устаревание было удалено в C ++ 11 по различным причинам (см. здесь ).

Более длинный ответ: больше о ключевых словах, чем вы хотели знать (прямо из стандартов):

C99

#include <fenv.h>
#pragma STDC FENV_ACCESS ON

/* file scope, static storage, internal linkage */
static int i1; // tentative definition, internal linkage
extern int i1; // tentative definition, internal linkage

int i2; // external linkage, automatic duration (effectively lifetime of program)

int *p = (int []){2, 4}; // unnamed array has static storage

/* effect on string literals */
char *s = "/tmp/fileXXXXXX"; // static storage always, may not be modifiable
char *p = (char []){"/tmp/fileXXXXXX"}; // static, modifiable
const char *cp = (const char []){"/tmp/fileXXXXXX"}  // static, non-modifiable


void f(int m)
{
    static int vla[ m ]; // err

    float w[] = { 0.0/0.0 }; // raises an exception

    /* block scope, static storage, no-linkage */
    static float x = 0.0/0.0; // does not raise an exception
    /* ... */
     /* effect on string literals */
    char *s = "/tmp/fileXXXXXX"; // static storage always, may not be modifiable
    char *p = (char []){"/tmp/fileXXXXXX"}; // automatic storage, modifiable
    const char *cp = (const char []){"/tmp/fileXXXXXX"}  // automatic storage, non-modifiable

}

inline void bar(void)
{
     const static int x = 42; // ok
     // Note: Since an inline definition is distinct from the 
     // corresponding external definition and from any other
     // corresponding inline definitions in other translation 
     // units, all corresponding objects with static storage
     // duration are also distinct in each of the definitions
     static int y = -42; // error, inline function definition
}

// the last declaration also specifies that the argument 
// corresponding to a in any call to f must be a non-null 
// pointer to the first of at least three arrays of 5 doubles
void f(double a[static 3][5]);

static void g(void); // internal linkage

C ++

Имеет в основном ту же семантику, за исключением случаев, отмеченных в кратком ответе. Также нет параметров, квалифицирующих static s.

extern "C" {
static void f4(); // the name of the function f4 has
                  // internal linkage (not C language
                  // linkage) and the function’s type
                  // has C language linkage.
}

class S {
   mutable static int i; // err
   mutable static int j; // err
   static int k; // ok, all instances share the same member
};

inline void bar(void)
{
     const static int x = 42; // ok
     static int y = -42; // ok
}

Есть еще несколько нюансов C ++ static, которые я здесь опущу. Взгляните на книгу или стандарт.

7 голосов
/ 23 апреля 2016

Статические переменные:

  • Инициализируется только один раз.
  • Статические переменные для класса (не для объекта). Т.е. память выделяется только один раз для каждого класса, и каждый экземпляр использует ее. Таким образом, если один объект изменяет свое значение, то измененное значение будет видно и другим объектам. (Простая мысль. Чтобы узнать количество объектов, созданных для класса, мы можем поместить статическую переменную и сделать do ++ в конструкторе)
  • Значение сохраняется между вызовами различных функций

Переменные Const:

  • Переменные Const - это обещание, что вы не собираетесь изменять его значение где-либо в программе. Если вы сделаете это, он будет жаловаться.
5 голосов
/ 07 февраля 2010

Константы не могут быть изменены, статические переменные больше связаны с тем, как они расположены и где они доступны.

Проверьте этот сайт .

3 голосов
/ 24 декабря 2013

const эквивалентно #define, но только для операторов значений (например, #define myvalue = 2). Объявленное значение заменяет имя переменной перед компиляцией.

static является переменной. Значение может измениться, но переменная будет сохраняться на протяжении всего выполнения программы , даже если переменная объявлена ​​в функции . Это эквивалентно глобальной переменной, область использования которой является областью блока, в которой они были объявлены, но область их значения является глобальной.

Таким образом, статические переменные инициализируются только один раз . Это особенно важно, если переменная объявлена ​​в функции, поскольку она гарантирует, что инициализация будет происходить только при первом вызове функции .

Другое использование статики связано с объектами. Объявление статической переменной в объекте приводит к тому, что это значение одинаково для всех экземпляров объекта. Как таковой, он не может быть вызван с именем объекта, но только с именем класса.

public class Test 
{ 
    public static int test;
}
Test myTestObject=new Test();
myTestObject.test=2;//ERROR
Test.test=2;//Correct

В таких языках, как C и C ++, бессмысленно объявлять статические глобальные переменные, но они очень полезны в функциях и классах. В управляемых языках единственный способ получить эффект глобальной переменной - объявить ее статической.

3 голосов
/ 07 февраля 2010

Статические переменные в контексте класса являются общими для всех экземпляров класса.

В функции она остается постоянной переменной, так что вы можете, например, подсчитать, сколько раз была вызвана функция.

При использовании вне функции или класса, она гарантирует, что переменная может использоваться только кодом в этом конкретном файле, и нигде больше.

Однако постоянные переменные не могут изменяться. Общее использование const и static вместе в определении класса для обеспечения некоторой константы.

class myClass {
public:
     static const int TOTAL_NUMBER = 5;
     // some public stuff
private:
     // some stuff
};
2 голосов
/ 07 февраля 2010

Статическая переменная может получить начальное значение только один раз. Это означает, что если у вас есть код, такой как "static int a=0" в примере функции, и этот код выполняется при первом вызове этой функции, но не выполняется при последующем вызове функции; переменная (a) по-прежнему будет иметь свое текущее значение (например, текущее значение 5), поскольку статическая переменная получает начальное значение только один раз.

Постоянная переменная имеет значение константы во всем коде. Например, если вы установите постоянную переменную, например "const int a=5", то это значение для "a" будет постоянным во всей вашей программе.

2 голосов
/ 07 февраля 2010

Статические переменные являются общими для всех экземпляров типа.

константные переменные специфичны для каждого отдельного экземпляра типа, но их значения известны и исправлены во время компиляции, и их нельзя изменить во время выполнения.

в отличие от констант, значения статических переменных могут быть изменены во время выполнения.

2 голосов
/ 07 февраля 2010

static означает локальный для единицы компиляции (то есть один файл исходного кода C ++), или другими словами, это означает, что он не добавлен в глобальное пространство имен. Вы можете иметь несколько статических переменных в разных файлах исходного кода c ++ с одинаковым именем и без конфликтов имен.

const просто константа, то есть не может быть изменено.

0 голосов
/ 21 октября 2018

статические

используется для того, чтобы сделать переменную переменной класса. Вам не нужно определять статическую переменную при объявлении.

Пример:

#include <iostream>

class dummy
{
        public:
                static int dum;
};


int dummy::dum = 0; //This is important for static variable, otherwise you'd get a linking error

int main()
{
        dummy d;
        d.dum = 1;

        std::cout<<"Printing dum from object: "<<d.dum<<std::endl;
        std::cout<<"Printing dum from class: "<<dummy::dum<<std::endl;

        return 0;
}

Это напечатало бы: Печать дум с объекта: 1 Печатная бумага из класса: 1

Переменная dum является переменной класса. Попытка получить к нему доступ через объект просто сообщает компилятору, что это переменная какого класса. Рассмотрим сценарий, в котором вы можете использовать переменную для подсчета количества созданных объектов. статика пригодится.

сопзЬ

используется, чтобы сделать его доступной только для чтения. Вам нужно сразу определить и объявить переменную const.

В той же программе, упомянутой выше, давайте сделаем также dum-константу:

class dummy
{
        public:
                static const int dum; // This would give an error. You need to define it as well
                static const int dum = 1; //this is correct
                const int dum = 1; //Correct. Just not making it a class variable

};

Предположим, в основном, я делаю это:

int main()
{
        dummy d;
        d.dum = 1; //Illegal!

        std::cout<<"Printing dum from object: "<<d.dum<<std::endl;
        std::cout<<"Printing dum from class: "<<dummy::dum<<std::endl;

        return 0;
}

Несмотря на то, что static был понятен, const испорчен в c ++. Следующий ресурс помогает лучше понять это: http://duramecho.com/ComputerInformation/WhyHowCppConst.html

...