函式中能定義區域性static變數嗎,為什麼不行

時間 2021-08-30 10:38:46

1樓:凌培勇

為什麼你要在函式裡定義static呢,statis 是類變數,在類初始化的時候就要載入

2樓:匿名使用者

這跟jvm執行機制有關,定義static之後表明在執行程式前,就要自動對其進行初始化,你的static變數寫在了非static方法中,jvm不會在程式執行前就初始化這個方法,但是裡面又包含了需要初始化的變數,這是矛盾的,所以不會通過。

只有在函式內部定義的變數才是區域性變數。。。。。這句話對麼????為什麼??

3樓:安璐卡

不對,區域性變數又稱過程級變數,應該在過程中宣告(按你說的情況,若該函式出現在過程中,那麼在函式內部定義的變數也算區域性變數,但區域性變數不僅僅包括這種情況),所以這句話是錯的!

4樓:匿名使用者

這麼無聊的問題應該是考試題,嚴格來說是不對的,比如有名稱空間這種東西會限制變數的作用域,但是很多教科書裡面有這麼一句“區域性變數是指在函式內部定義的變數 作用域為定義區域性變數的函式”,所以對不對還是問你的老師比較好

5樓:魯步凝珍

函式內的static變數儲存在靜態記憶體裡。

為什麼定義的靜態全域性變數用在函式裡和在函式裡定義定義的靜態區域性變數輸出的值不一樣啊? 謝謝了!!!

6樓:手機使用者

保留字肯定就是關鍵字撒,

(1)auto

這個這個關鍵字用於宣告變數的生存期為自動,即將不在任何類、結構、列舉、聯合和函式中定義的變數視為全域性變數,而在函式中定義的變數視為區域性變數。這個關鍵字不怎麼多寫,因為所有的變數預設就是auto的。

(2)register

這個關鍵字命令編譯器儘可能的將變數存在cpu內部暫存器中而不是通過記憶體定址訪問以提高效率。

(3)static

常見的兩種用途:

1>統計函式被呼叫的次數;

2>減少區域性陣列建立和賦值的開銷.變數的建立和賦值是需要一定的處理器開銷的,特別是陣列等含有較多元素的儲存型別。在一些含有較多的變數並且被經常呼叫的函式中,可以將一些陣列宣告為static型別,以減少建立或者初始化這些變數的開銷.

詳細說明:

1>、變數會被放在程式的全域性儲存區中,這樣可以在下一次呼叫的時候還可以保持原來的賦值。這一點是它與堆疊變數和堆變數的區別。

2>、變數用static告知編譯器,自己僅僅在變數的作用範圍內可見。這一點是它與全域性變數的區別。

3>當static用來修飾全域性變數時,它就改變了全域性變數的作用域,使其不能被別的程式extern,限制在了當前檔案裡,但是沒有改變其存放位置,還是在全域性靜態儲存區。

使用注意:

1>若全域性變數僅在單個c檔案中訪問,則可以將這個變數修改為靜態全域性變數,以降低模組間的耦合度;

2>若全域性變數僅由單個函式訪問,則可以將這個變數改為該函式的靜態區域性變數,以降低模組間的耦合度;

3>設計和使用訪問動態全域性變數、靜態全域性變數、靜態區域性變數的函式時,需要考慮重入問題(只要輸入資料相同就應產生相同的輸出)

(4)const

被const修飾的東西都受到強制保護,可以預防意外的變動,能提高程式的健壯性。它可以修飾函式的引數、返回值,甚至函式的定義體。

作用:1>修飾輸入引數

a.對於非內部資料型別的輸入引數,應該將“值傳遞”的方式改為“const引用傳遞”,目的是提高效率。例如將void func(a a) 改為void func(const a &a)。

b.對於內部資料型別的輸入引數,不要將“值傳遞”的方式改為“const引用傳遞”。否則既達不到提高效率的目的,又降低了函式的可理解性。

例如void func(int x) 不應該改為void func(const int &x)。

2>用const修飾函式的返回值

a.如果給以“指標傳遞”方式的函式返回值加const修飾,那麼函式返回值(即指標)的內容不能被修改,該返回值只能被賦給加const修飾的同型別指標。

如對於: const char * getstring(void);

如下語句將出現編譯錯誤:

char *str = getstring();//cannot convert from 'const char *' to 'char *';

正確的用法是:

const char *str = getstring();

b.如果函式返回值採用“值傳遞方式”,由於函式會把返回值複製到外部臨時的儲存單元中,加const修飾沒有任何價值。 如不要把函式int getint(void) 寫成const int getint(void)。

3>const成員函式的宣告中,const關鍵字只能放在函式宣告的尾部,表示該類成員不修改物件.

說明:const type m; //修飾m為不可改變

示例:typedef char * pstr; //新的型別pstr;

char string[4] = "abc";

const char *p1 = string;

p1++; //正確,上邊修飾的是*p1,p1可變

const pstr p2 = string;

p2++; //錯誤,上邊修飾的是p2,p2不可變,*p2可變

同理,const修飾指標時用此原則判斷就不會混淆了。

const int *value; //*value不可變,value可變

int* const value; //value不可變,*value可變

const (int *) value; //(int *)是一種type,value不可變,*value可變

//邏輯上這樣理解,編譯不能通過,需要tydef int* newtype;

const int* const value;//*value,value都不可變

(5)volatile

表明某個變數的值可能在外部被改變,優化器在用到這個變數時必須每次都小心地重新讀取這個變數的值,而不是使用儲存在暫存器裡的備份。它可以適用於基礎型別如:int,char,long......

也適用於c的結構和c++的類。當對結構或者類物件使用volatile修飾的時候,結構或者類的所有成員都會被視為volatile.

該關鍵字在多執行緒環境下經常使用,因為在編寫多執行緒的程式時,同一個變數可能被多個執行緒修改,而程式通過該變數同步各個執行緒。

簡單示例:

dword __stdcall threadfunc(lpvoid signal)

該執行緒啟動時將intsignal 置為2,然後迴圈等待直到intsignal 為1 時退出。顯然intsignal的值必須在外部被改變,否則該執行緒不會退出。但是實際執行的時候該執行緒卻不會退出,即使在外部將它的值改為1,看一下對應的偽彙編**就明白了:

mov ax,signal

label:

if(ax!=1)

goto label

對於c編譯器來說,它並不知道這個值會被其他執行緒修改。自然就把它cache在暫存器裡面。c 編譯器是沒有執行緒概念的,這時候就需要用到volatile。

volatile 的本意是指:這個值可能會在當前執行緒外部被改變。也就是說,我們要在threadfunc中的intsignal前面加上volatile關鍵字,這時候,編譯器知道該變數的值會在外部改變,因此每次訪問該變數時會重新讀取,所作的迴圈變為如下面偽碼所示:

label:

mov ax,signal

if(ax!=1)

goto label

注意:一個引數既可以是const同時是volatile,是volatile因為它可能被意想不到地改變。它是const因為程式不應該試圖去修改它。

(6)extern

extern 意為“外來的”···它的作用在於告訴編譯器:有這個變數,它可能不存在當前的檔案中,但它肯定要存在於工程中的某一個原始檔中或者一個dll的輸出中。

參考 另外:c語言中的關鍵字

auto :宣告自動變數 一般不使用

double :宣告雙精度變數或函式

int: 宣告整型變數或函式

struct:宣告結構體變數或函式

break:跳出當前迴圈

else :條件語句否定分支(與 if 連用)

long :宣告長整型變數或函式

switch :用於開關語句

case:開關語句分支

enum :宣告列舉型別

register:宣告積存器變數

typedef:用以給資料型別取別名(當然還有其他作用)

char :宣告字元型變數或函式

extern:宣告變數是在其他檔案正宣告(也可以看做是引用變數)

return :子程式返回語句(可以帶引數,也看不帶引數)

union:宣告聯合資料型別

const :宣告只讀變數

float:宣告浮點型變數或函式

short :宣告短整型變數或函式

unsigned:宣告無符號型別變數或函式

continue:結束當前迴圈,開始下一輪迴圈

for:一種迴圈語句(可意會不可言傳)

signed:生命有符號型別變數或函式

void :宣告函式無返回值或無引數,宣告無型別指標(基本上就這三個作用)

default:開關語句中的“其他”分支

goto:無條件跳轉語句

sizeof:計算資料型別長度

volatile:說明變數在程式執行中可被隱含地改變

do :迴圈語句的迴圈體

while :迴圈語句的迴圈條件

static :宣告靜態變數

if:條件語句

7樓:du瓶邪

例如:c/c++ code

void thefunc(void)}

8樓:段啟中

#include

static int j; //全域性靜態變數,一直佔記憶體,直到程式執行結束。

void fun1(void)

void fun2(void)

int main(void)

這是1

return 0;}

9樓:行行都不行

j因為先賦值為0,然後自加,所以值為1.

i為10的原因:函式靜態變數的記憶體空間只被分配一次,對函式的多次呼叫相當於多次作用於同一個靜態變數。因為每次呼叫都有i++,所以函式呼叫10次相當於i自加10次,所以為10。

在C 中,函式引數預設值為什麼不允許為區域性變數呢

小巷軒 區域性變數是你函式呼叫之後,才會被構造出來,而函式引數的值的存在,是在呼叫函式的時候就必須存在。一個是函式呼叫之後才存在,一個是函式呼叫之時就存在,你說,引數預設引數怎麼能為區域性變數呢! 什麼意思 都預設了肯定要是一個定值 區域性變數肯定不是定值 有些亂,既然是區域性變數就是在函式內部的,...

複變函式的定義域是什麼

墨汁諾 平面上的面域,並且要使函式有定義。0處其實就是r等於0,z r cos isin 0 是有定義的 唯一區別就是輔角無定義而已,也就是argz在0點不連續,這跟ln z 的性質是一樣的,但都不影響這些初等函式的解析性。定義域就是把在數學上沒有意義或者不可能實現的情況排除,例如最起碼的就是不論如...

虛擬函式的定義,C 中虛擬函式必須有定義嗎?

赫連巧山 1.虛擬函式的定義 虛擬函式用來表現基類和派生類的成員函式之間的一種關係.虛擬函式的定義在基類中進行,在需要定義為虛擬函式的成員函式的宣告前冠以關鍵字 virtual.基類中的某個成員函式被宣告為虛擬函式後,此虛擬函式就可以在一個或多個派生類中被重新定義.在派生類中重新定義時,其函式原型,...