當前位置:首頁 » 編程軟體 » 編譯期常量技術如何避免

編譯期常量技術如何避免

發布時間: 2022-07-09 07:06:03

A. 關於C++編譯期間類里的常量問題

cout <<那句 你把(const string) 這個去掉呢 或者直接把cp聲明成string* 然後直接cout << *cp 好了

B. c語言 為什麼編譯器提示必須有常量值,到底哪錯了

matrix是一個數組,而定義一個數組的長度必須得是一個常量,也就是N,而你的N不是常量,所以將N定義為常量即可

C. C語言中系統既然不給常量分配存儲空間,那麼編譯系統又是如何"記憶"和使用常量的呢

耐心看完,你應該能明白了:
C語言中,常量和變數是放在不同的"段"(section)里,程序一旦載入,常量/變數自然都在內存里了。
常量和全程變數,放在初始化段。
局部變數,通常在棧里。
常量在程序載入時同時載入。

D. java如何優化編譯呢

#java編譯器對`String常量表達式`的優化:
- 1.String+String 可以被編譯器識別為常量表達
String a="ab" ;
String b="a"+"b";//編譯後:b="ab"
System.out.println(a==b);//true
分析:
編譯器將"a"+"b"當做常量表達式,在編譯時期進行優化,直接取"ab". 在運行時期
並沒有創建新的對象,而是從jvm字元串常量池中獲取之前已經存在的"ab"對象.

- 2.String+基本類型 可以被編譯器識別為常量表達式

String a="a1";
String b="a"+1; //"a1"
String c="a"+true;//"atrue"
String d="a"+3.14;//"a3.14"

#java編譯器對`常量`優化:
* 它是編譯時的一項優化技術,將代碼的常量計算在編譯期完成,節約了運行時的計算量.

1.常量替換
//編譯前:
final int x=10;
int y=x;

//編譯後
int x=10;
int y=10;//編譯時,常量替換了

2.數學恆等式的模式匹配替換

//編譯前:
int x=10+10;

//編譯後
int x=20;//編譯時,模式匹配替換了

3.常量折疊

//編譯前:
boolean flag=true||(a || b && c);

//編譯後
boolean flag=true;//編譯時,常量折疊了

E. java中編譯期常量所指的是什麼

classInitalizedClass{
static{
System.out.println("!");
}
publicstaticintinititalize_varible=1;

}

{
publicstaticvoidmain(String[]args){
System.out.println(InitalizedClass.inititalize_varible);

}

}
上面的結果是:
!
1

classInitalizedClass{
static{
System.out.println("!");
}
//和上面的例子唯一的差異就是此處的變數INITIALIZED_VARIBLE被聲明為final
_VARIBLE=1;

}

{
publicstaticvoidmain(String[]args){
System.out.println(InitalizedClass.INITIALIZED_VARIBLE);

}

}

上面的結果是:
1

為什麼兩個例子執行結果不一樣,原因是第二個例子中的INITIALIZED_VARIBLE為編譯期常量,它不會導致類的初始化的

F. 如何防止JAVA程序源代碼被反編譯

我們都知道JAVA是一種解析型語言,這就決定JAVA文件編譯後不是機器碼,而是一個位元組碼文件,也就是CLASS文件。而這樣的文件是存在規律的,經過反編譯工具是可以還原回來的。例如Decafe、FrontEnd,YingJAD和Jode等等軟體。下面是《Nokia中Short數組轉換演算法
類中Main函數的ByteCode:0 ldc #162 invokestatic #185 astore_16 return其源代碼是:short [] pixels = parseImage("/ef1s.png");
我們通過反編譯工具是可以還原出以上源代碼的。而通過簡單的分析,我們也能自己寫出源代碼的。
第一行:ldc #16
ldc為虛擬機的指令,作用是:壓入常量池的項,形式如下ldc index這個index就是上面的16,也就是在常量池中的有效索引,當我們去看常量池的時候,我們就會找到index為16的值為String_info,裡面存了/ef1s.png.
所以這行的意思就是把/ef1s.pn作為一個String存在常量池中,其有效索引為16。
第二行:2 invokestatic #18
invokestatic為虛擬機指令,作用是:調用類(static)方法,形式如下
invokestatic indexbyte1 indexbyte2
其中indexbyte1和indexbyte2必須是在常量池中的有效索引,而是指向的類型必須有Methodref標記,對類名,方法名和方法的描述符的引用。
所以當我們看常量池中索引為18的地方,我們就會得到以下信息:
Class Name : cp_info#1
Name Type : cp_info#19
1 和19都是常量池中的有效索引,值就是右邊<中的值,再往下跟蹤我就不多說了,有興趣的朋友可以去JAVA虛擬機規范。
這里我簡單介紹一下parseImage(Ljava/lang/String;)[S 的意思。
這就是parseImage這個函數的運行,我們反過來看看parseImage的原型就明白了
short [] parseImage(String)
那麼Ljava/lang/String;就是說需要傳入一個String對象,而為什麼前面要有一個L呢,這是JAVA虛擬機用來表示這是一個Object。如果是基本類型,這里就不需要有L了。然後返回為short的一維數組,也就是對應的[S。是不是很有意思,S對應著Short類型,而「[」對應一維數組,那有些朋友要問了,兩維呢,那就「[[」,呵呵,是不是很有意思。
好了,調用了函數,返回的值要保存下來吧。那麼就是第三行要做的事情了。

G. c語言定義常量為什麼不建議用#define

1、盡量用const和inline而不用#define
這個條款最好稱為:「盡量用編譯器而不用預處理」,因為#define經常被認為好象不是語言本身的一部分。這是問題之一。
2、再看下面的語句:
#define ASPECT_RATIO 1.653
編譯器會永遠也看不到ASPECT_RATIO這個符號名,因為在源碼進入編譯器之前,它會被預處理程序去掉,於是ASPECT_RATIO不會加入到符號列表中。如果涉及到這個常量的代碼在編譯時報錯,就會很令人費解,因為報錯信息指的是1.653,而不是ASPECT_RATIO。如果ASPECT_RATIO不是在你自己寫的頭文件中定義的,就會奇怪1.653是從哪裡來的,甚至會花時間跟蹤下去。這個問題也會出現在符號調試器中,因為同樣所寫的符號名不會出現在符號列表中。
解決這個問題的方案很簡單:不用預處理宏,定義一個常量:
const double ASPECT_RATIO = 1.653;
這種方法很有效。但有兩個特殊情況要注意。
首先,定義指針常量時會有點不同。因為常量定義一般是放在頭文件中(許多源文件會包含它),除了指針所指的類型要定義成const外,重要的是指針也經常要定義成const。例如,要在頭文件中定義一個基於char*的字元串常量,要寫兩次const:
const char * const authorName = "Scott Meyers ";

熱點內容
erp系統搭建備用伺服器 發布:2025-02-09 04:07:38 瀏覽:943
戴爾伺服器在bios怎麼配置管理ip 發布:2025-02-09 04:01:53 瀏覽:548
小魚易連雲存儲 發布:2025-02-09 03:59:47 瀏覽:87
正在限制訪問 發布:2025-02-09 03:47:17 瀏覽:901
架設資料庫 發布:2025-02-09 03:41:29 瀏覽:964
imacpro哪個配置最好 發布:2025-02-09 03:32:29 瀏覽:251
用編程對話 發布:2025-02-09 03:23:43 瀏覽:86
自助解壓球 發布:2025-02-09 03:17:37 瀏覽:319
linux進程的退出 發布:2025-02-09 03:00:22 瀏覽:814
淘寶上傳時間 發布:2025-02-09 02:42:13 瀏覽:638