⑴ 靜態變數是在編譯時分配內存空間,編譯時是什麼時候編譯時都做什麼東西啊
靜態變數在編譯時進行初始化,運行階段分配內存空間。靜態變數在整個程序生命周期都是存在的。
⑵ linux怎麼靜態編譯
關於在 Linux 環境下面對 C 語言源程序進行靜態編譯,關鍵是要看你的 C 語言源程序中都使用到了哪些系統庫函數?如果是標準的輸入、輸出庫函數,只要在命令行提示符 $ 下面執行:
gcc my_prog.c 即可(預設的可執行文件名是:a.out);如果在用戶的源程序中使用到了數學計算函數,那麼在命令行提示符 $ 下面必須執行:
gcc my_prog.c -IMATH.LIB(假設涉及到各種數學計算的數學庫的庫文件為:MATH.LIB)
如果不加上 -IMATH.LIB 選項,那麼即使你的源程序編寫得再正確,也無法正常編譯。
另外還有一個必須要注意的就是:在 Linux 的環境變數中,一定要把 INCLUDE、LIB 所在的路徑設置好(在 SHELL 文件中寫好),這樣在使用 Linux 系統時才能夠減少出錯的機會。
⑶ 靜態變數有何特點如何存取靜態變數
靜態變數的類型說明符是static。靜態變數當然是屬於靜態存儲方式,但是屬於靜態存儲方式的量不一定就是靜態變數,例如外部變數雖屬於靜態存儲方式,但不一定是靜態變數,必須由static加以定義後才能成為靜態外部變數,或稱靜態全局變數。
對於自動變數,它屬於動態存儲方式。但是也可以用static定義它為靜態自動變數,或稱靜態局部變數,從而成為靜態存儲方式。由此看來,一個變數可由static進行再說明,並改變其原有的存儲方式。
常量使用
靜態變數也可以用於存儲常數。具體來說,靜態變數(全局變數及匯編語言里定義的符號亦同)可用const,constant或final(根據語言決定)等關鍵字標識,這時其值就會在編譯時設定,並且無法在運行時改變。
編譯器通常將靜態常量與文本一起置於目標文件的文本區域,而非常量初始化數據則置於數據區;而如若有需要,有些編譯器還可選擇為其開辟專用區;為防止常數變數被錯誤的指針寫入覆蓋,亦可在這塊區域啟用內存保護機制。
以上內容參考:網路-靜態變數
⑷ C語言的中靜態變數
前面的答案都是錯的,正確的答案應該為
i=10,,j=1 解釋: 首先你要明確什麼是靜態定義static你理解「靜態變數只接受第一次賦值」說明你對static還有一點認知,但是不完全正確 本題的關鍵在於
「靜態全局變數
j
的定義」
還有你對
「賦初值」的理解 由於「如果在定義局部變數時不賦初值的話,對靜態局部變數來說,編譯時自動賦初值0」因此
static
int
j;
和
static
int
j=0;是完全等價的這樣
函數f2定義中的
j=0;只是純粹的賦值,則無論是第一次循環還是第10次循環,j=0;語句都不是一個初始化的語句,這點需要明確 我想你只要弄明白這點,本題的答案是怎樣得來的你就完全清楚了,你主要是對static的理解不完整而已 附帶一提,定義和聲明函數時,如果參數類型為空可以省略即void
f1(void){......}void
f2(void){......}中的void是完全多餘的,它和void
f1(){......}void
f2(){......}完全等價
⑸ java靜態變數怎麼聲明
個人的總結
1 靜態變數只有一份被類的所有實例共享
2 靜態變數的聲明在編譯時已經明確了內存的位置
3 延遲初始化是改變靜態變數的值
引用
Java靜態變數的初始化(static塊的本質)
在網上看到了下面的一段代碼:
1. public class Test {
2. static {
3. _i = 20;
4. }
5. public static int _i = 10;
6.
7. public static void main(String[] args) {
8. System.out.println(_i);
9. }
10. }
public class Test { static { _i = 20; } public static int _i = 10; public static void main(String[] args) { System.out.println(_i); } }
上述代碼會列印出什麼結果來呢?10還是20?本文將以此代碼為引子,著重討論一下靜態變數的初始化問題。 樓主可以找組織先記下175再來記下161最後填寫984就會出現扣裙問題1:靜態變數如何初始化
Java類中可以定義一個static塊,用於靜態變數的初始化。如:
1. public class Test {
2. public static int _i;
3. static {
4. _i = 10;
5. }
6. }
public class Test { public static int _i; static { _i = 10; } }
當然最常用的初始化靜態變數的操作是在聲明變數時直接進行賦值操作。如:
1. public class Test {
2. public static int _i = 10;
3. }
public class Test { public static int _i = 10; }
那麼上述兩例在本質上有什麼區別嗎?回答是沒有區別。兩例代碼編譯之後的位元組碼完全一致,通過 「javap -c」查看到的位元組碼如下:
public class Test extends java.lang.Object{
public static int _i;
public Test();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
static {};
Code:
0: bipush 10
2: putstatic #2; //Field _i:I
5: return
}
通過位元組碼還可以看出,當類的定義中不含有static塊時,編譯器會為該類提供一個默認的static塊。當然這是在含有靜態變數初始化操作的前 提下。如果靜態變數沒有初始化操作,則編譯器不會為之提供默認的static塊。如:
1. public class Test {
2. public static int _i;
3. }
public class Test { public static int _i; }
其位元組碼的表現形式為:
public class Test extends java.lang.Object{
public static int _i;
public Test();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
}
由於靜態變數是通過賦值操作進行初始化的,因此可以通過靜態函數返回值的方式為其初始化。如:
1. public class Test {
2. public static int _i = init();
3.
4. private static int init() {
5. return 10;
6. }
7. }
public class Test { public static int _i = init(); private static int init() { return 10; } }
其本質與下面的代碼相同:
1. public class Test {
2. public static int _i;
3. static {
4. _i = init();
5. }
6.
7. private static int init() {
8. return 10;
9. }
10. }
public class Test { public static int _i; static { _i = init(); } private static int init() { return 10; } }
問題2:JDK如何處理static塊
類定義中可以存在多個static塊嗎?回答是可以。如:
1. public class Test {
2. public static int _i;
3. static {
4. _i = 10;
5. }
6.
7. public static void main(String[] args) {
8. }
9.
10. static {
11. _i = 20;
12. }
13. }
public class Test { public static int _i; static { _i = 10; } public static void main(String[] args) { } static { _i = 20; } }
此類編譯之後的位元組碼為:
public class Test extends java.lang.Object{
public static int _i;
public Test();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: return
static {};
Code:
0: bipush 10
2: putstatic #2; //Field _i:I
5: bipush 20
7: putstatic #2; //Field _i:I
10: return
}
觀察static{}部分可以看出,上例的代碼與下面的代碼效果一致:
1. public class Test {
2. public static int _i;
3.
4. public static void main(String[] args) {
5. }
6.
7. static {
8. _i = 10;
9. _i = 20;
10. }
11. }
public class Test { public static int _i; public static void main(String[] args) { } static { _i = 10; _i = 20; } }
此例可以證明,不僅類定義中可以有多個static塊,而且在編譯時編譯器會將多個static塊按照代碼的前後位置重新組合成一個static 塊。
問題3:如何看待靜態變數的聲明
靜態變數存放在常量池之中。如何證明呢?如:
1. public class Test {
2. public static int _i = 10;
3. }
public class Test { public static int _i = 10; }
使用「javap -c -verbose」查看其位元組碼的內容如下:
public class Test extends java.lang.Object
SourceFile: "Test.java"
minor version: 0
major version: 49
Constant pool:
const #1 = Method #4.#14; // java/lang/Object."<init>":()V
const #2 = Field #3.#15; // Test._i:I
const #3 = class #16; // Test
const #4 = class #17; // java/lang/Object
const #5 = Asciz _i;
const #6 = Asciz I;
const #7 = Asciz <init>;
const #8 = Asciz ()V;
const #9 = Asciz Code;
const #10 = Asciz LineNumberTable;
const #11 = Asciz <clinit>;
const #12 = Asciz SourceFile;
const #13 = Asciz Test.java;
const #14 = NameAndType #7:#8;// "<init>":()V
const #15 = NameAndType #5:#6;// _i:I
const #16 = Asciz Test;
const #17 = Asciz java/lang/Object;
{
public static int _i;
public Test();
Code:
Stack=1, Locals=1, Args_size=1
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 2: 0
static {};
Code:
Stack=1, Locals=0, Args_size=0
0: bipush 10
2: putstatic #2; //Field _i:I
5: return
LineNumberTable:
line 3: 0
}
我們看到,常量池中const #2指向的就是Test._i,也就是靜態變數。靜態變數被保存到常量池中的工作原理這里不深入討論。在此需要注意的是:
* 靜態變數的聲明與初始化是兩個不同的操作;
* 靜態變數的聲明在編譯時已經明確了內存的位置。
如:
1. public class Test {
2. public static int _i = 10;
3. }
public class Test { public static int _i = 10; }
上述代碼的本質可以視為:
1. public class Test {
2. // 靜態變數的聲明
3. public static int _i;
4.
5. // 靜態變數的初始化
6. static {
7. _i = 10;
8. }
9. }
public class Test { // 靜態變數的聲明 public static int _i; // 靜態變數的初始化 static { _i = 10; } }
由於靜態變數的聲明在編譯時已經明確,所以靜態變數的聲明與初始化在編碼順序上可以顛倒。也就是說可以先編寫初始化的代碼,再編寫聲明代碼。如:
1. public class Test {
2. // 靜態變數的初始化
3. static {
4. _i = 10;
5. }
6.
7. // 靜態變數的聲明
8. public static int _i;
9. }
public class Test { // 靜態變數的初始化 static { _i = 10; } // 靜態變數的聲明 public static int _i; }
對初始問題的解答
解答了上述三個問題,讓我們再來看看開篇提到的問題。代碼如下:
1. public class Test {
2. static {
3. _i = 20;
4. }
5. public static int _i = 10;
6.
7. public static void main(String[] args) {
8. System.out.println(_i);
9. }
10. }
public class Test { static { _i = 20; } public static int _i = 10; public static void main(String[] args) { System.out.println(_i); } }
其本質可以用下面的代碼表示:
1. public class Test {
2. static {
3. _i = 20;
4. }
5. public static int _i;
6. static {
7. _i = 10;
8. }
9.
10. public static void main(String[] args) {
11. System.out.println(_i);
12. }
13. }
public class Test { static { _i = 20; } public static int _i; static { _i = 10; } public static void main(String[] args) { System.out.println(_i); } }
再簡化一下,可以表示為:
1. public class Test {
2. public static int _i;
3.
4. static {
5. _i = 20;
6. _i = 10;
7. }
8.
9. public static void main(String[] args) {
10. System.out.println(_i);
11. }
12. }
public class Test { public static int _i; static { _i = 20; _i = 10; } public static void main(String[] args) { System.out.println(_i); } }
至此,代碼已經明確告訴我們列印結果是什麼了!
⑹ C語言中的靜態變數
其實是這樣的。靜態變數在內存中存儲的位置,與全局變數是同一個區域。
所以,在編譯期間,它的存儲和大小就已經確定了,也就是已經分配了空間了。
而在c語言中,「分配內存」往往看做是變數被定義的一個標志。
所以,你在運行程序的時候,由於靜態變數已經分配過內存了,不會再次進行分配了,它的定義語句就不會再次被執行了。
⑺ c語言中靜態變數是怎麼用的
#include"stdio.h"
void
main()
{
int
f(int);
int
a=2,i;
for(i=0;i<3;i++)
printf("%d
",f(a));
}
int
f(int
a)
{
auto
int
b=0;
//aubo為自動變數的標志,則b為自動變數
static
int
c=3;//static
為靜態局部變數的標志,則c為靜態局部變數
b=b+1;
//b為自動變數,則b一直等於1
c=c+1;
//c為靜態局部變數,則c隨著for循環分別為4,5,6
return(a+b+c);
}
所以運行的結果為:7,8,9
註:靜態局部變數(靜態變數)是在編譯時賦初值的,即值賦初值一次,在程序運行時它已有初值,以後每次調用函數式不在重復賦初值而只在保留商城函數調用結束時的值。
⑻ java中的全局變數和靜態變數是在編譯時分配內存還是在載入時分配內存
全局變數是在創建對象的時候分配內存的 創建對象過程為
分配空間。
遞歸的創建父類對象。
初始化成員變數。
調用構造方法創建一個對象。
靜態變數是在類載入的時候分配空間的,靜態變數和對象沒有關系 是在JVM第一次讀到一個類的時候載入信息的過程中分配空間的 載入過程為
1 .載入父類(如果父類已經載入過,則不在載入)。
2.初始化靜態屬性 。
3 .按順序的初始化靜態代碼塊 初始化的前提就是分配空間 。
而且靜態變數在以後的創建對象的時候不在初始化 所以一般用靜態來保存共享信息
⑼ VC++ 靜態變數問題
如果你是在View裡面創建的對話框,你首先得在View類裡面創建對應的CPen對象,一般是使用private的,創建對話框前把這個參數按引用或傳指針方式傳入到對話框類中,然後對話框再DoModal()
⑽ 編譯器編譯高級語言為低級語言的時候,給全局變數或靜態變數是如何分配內存的
對於C和C++的編譯器,全局變數和靜態變數都是在專門的數據區保存的,更具體一點,一般是在.data和.bss段保存的,具體在哪個段,編譯器會根據代碼中是否對這些變數進行了初始化來決定,如果初始化過,並且初始化的值不為0,那麼這個這個變數一般就會被放在編譯結果的.data段中,否則就是放在.bss段中。
.data段中就保存變數的符號,還保存變數的初始化值,而在.bss段中,只保存變數的符號,而不保存值,這是因為這部分的變數都將被初始化為0,這也是為什麼static聲明的變數即使沒有初始化也會是0的原因。
這些段都會在程序被執行的時候由操作系統(或鏈接器)載入到指定的內存中,便完成相應的初始化。