導航:首頁 > 源碼編譯 > 編譯原理布爾判斷必須從左往右嗎

編譯原理布爾判斷必須從左往右嗎

發布時間:2023-04-23 18:15:38

『壹』 編譯原理 while 語句文法

while(條件)
{
.......;//語句
X++或者X--;//做自增或自減運算來達到循環的過程
}
while後面跟一堆小括弧,裡面的條件判斷,類似IF語句,當條件滿足時做以下語句的循環,條件不滿足後直接跳出循環;
例題:
int i=0;//初始化i=0
while(i<5)//i=0滿足判斷的條件,進入循環語句
{
i++;//做自增運算,當i+到5時跳出循環,因為i不小於5了
}
printf("%d",i);//此時i的值為5

『貳』 編譯器筆記34-中間代碼生成-布爾表達式的回填

基本思想:生成一個跳轉指令時,暫時不指定該跳轉指令的目標標號。這樣的指令都被放入由跳轉指令組成的列表中。同一個列表中的所有跳轉指令具有相同的目標標號。等到能夠確定正確的目標標號時,才去填充這些指令的目標標號。

B.truelist:指向一個包含跳轉指令的列表,這些指令最終獲得的目標標號就是當B為真時控制流應該轉向的指令的標號。

B.falselist:指向一個包含跳轉指令的列表,這些指令最終獲得的目標標號就是當B為假時控制流應該轉向的指令的標號。

為了處理衫芹跳轉指令的列表我們構造了三個函數

上述的布爾表達式將被翻譯成兩條跳轉指令。兩條跳轉指令的標號都不填寫因為這兩條跳轉指令的標號都在等待回填,因此我們要把它放到相應的列表中。

第一條跳轉指令的目標標號是B的真出口,因此我們把它放到B.truelist中。調用makelist函數生成一個只包含nextquad的列表,並把這個列表的指針賦值給truelist,這里的nextquad是指即將生成的下一條指令的標號或瞎畢,即gen('if' E1.addr relop E2.addr'goto_')這條指令的標號。

第二條跳轉指令的目標標號是B的假出口,因此把這條跳轉指令存放到B.falselist中。因此我們調用makelist函數生成一個只包含nextquad+1這樣一個標號的列表,nextquad+1標號就是gen('goto_')這條指令的標號。

這樣的話我們就將這兩條指令分別放入到B.truelist和B.falselist中。

問:list中存的是對應跳轉指令的標號?

當B定義為true時,此時可以確定布爾表達式的值為真,生成一條跳轉到B的真出口的一條指令。由於此真出口的標號不能確定有待回填,我們把它放入到B.truelist中。

當B定義為false時,此時可以確定布爾表達式的值為假,生成一條跳轉到B的假出口的一條指令。由於此真出口的標號不能確定有待回填,我們把它放入到B.falselist中。

對B的翻譯與其對應的子表達式B1的翻譯是相同的,因此B的屬性值等於B1的屬性值。

B的值與B1的值正好相反,因此將兩個非終結符的屬性進行對調。

B1.truelist中的這些指令都要跳轉到B1的真出口,當B1為真的時候整個表達式的值就是為真的,因此B1的真出口就是B的真出口。要跳轉到B1的真出口就是跳轉到B的真出口,因此B1.truelist中的指令都要放到B.truelist中。

B2.truelist的指令都要跳轉到真出口,當B2為真時整個表達式的值也為真,因此B2的真出口就是B的真出口。要跳轉到B2的真出口就是要跳轉到B的真出口,因此B2.truelist中的指令都要放到B.truelist中。

B1.falselist中的指令它們都是要跳轉到B1的假出口,當B1的值為假的時候我們要進一步判斷B2的值,因此B1的假出口就是B2的第一條指令,因此B1.falselist中的指令都要跳轉到B2的第一條指令。

B2.falselist中的指令都要跳轉到B2的假出口,當B2的值為假的時候那麼整個布爾表達式的值也是假的。因此B2的假出口就是B的假出口,要跳轉到B2的假出口也就是要跳轉到B的假出口。B2.falselist中的指令都要放置到B.falselist中。

根據此示意神前圖可以看出,在分析B2之前,要用B2的第一條指令的標號來回填B1.falselist中的各條指令。當然我們可以記錄下B2的第一條指令的標號在歸約時完成此回填動作。為了記下B2第一條指令的標號我們在非終結符B2之前插入一個標記非終結符M。與M關聯的語義動作它的任務就是記錄下B2的第一條語義動作的標號。我們給M設置一個綜合屬性quad,M.quad等於下一條指令的標號。因為我們把M放在B2之前,因此M.quad記錄的是第二條指令的標號。根據翻譯方案示意圖,我們要用M.quad來回填B1.falselist中的各條指令,因此調用backpatch用M.quad回填B1.falselist中的各條屬性。B.truelist是由B1.truelist和B2.truelist合並而成的,因此我們調用merge函數將B1.truelist和B2.truelist進行合並,將合並後的指針賦值給B.truelist。

註:因為這里我們定義的都是綜合屬性,從左向右掃描輸入串。makelist函數生成一個只包含下一條指令的列表,並把指針賦值給B.trulist。我們假設下一條指令從100開始。gen(『if 』 E 1 .addr relop E 2 .addr 『goto _』)中E1.address等於a,relop就是小於號,E2.address等於b,引號中的字元串按字面值傳遞。下劃線表示待回填的目標標號。

註:將棧頂中的空串歸約成一個標記非終結符M

註:有四條指令是等待回填的,在B的truelist中有兩條指令100和104,當B的真出口確定以後我們將用B的真出口的標號這兩條指令。同理當B的假出口確定以後將會用B的假出口的標號回填此兩條指令。

『叄』 含有默認參數的函數對其參數賦值時必須是從左至右嗎

這個說法有點問題吧?定義時,函數的默認形參必須運喊放在非默認形參的右邊,但「賦值」應該是指將實參的值對應拷貝給形參的過程,這個過程是從右至左進敗擾行的。旁枯野比如若有函數void f(int a,int b,int c,int d=3,int e=0);,假設這樣調用:int x=7;f(5,x,x+=1);,那麼函數中得到的是a==5,b==8,c==8,d==3,e==0。看代碼與結果:

『肆』 C語言布爾頭文件使用方法

1、ANSI C99標准規定C語言中有布爾類型(_Bool)。為了方便,使用布爾類型可以加入頭文件stdbool.h,該文件定義了bool=_Bool,true=1,false=0。使用布爾類型必須保證所使用的編譯器支持C99標准。

2、C語言的邏輯判斷只是判斷0或非0,只要能保存整型數據的變數類型都可以作為布爾型使用。 用特殊色彩標記關鍵字的功能是編輯器的功能而非編譯器的功能,因為C++有bool類型,因此bool會被編輯器標亮,但是C語言編譯隱輪隱器是不會認識這個關桐鏈鍵字的。灶廳
C語言中bool可以自定義,例如:
#define bool int
#define false 0
#define true 1

『伍』 c需要 a+=6=a 怎麼理解

正常理解是從右往左看悔仿,先碧弊纖判斷6 = a的布卜滾爾值,然後再自加到a。
但是我在GCC的C11標准下編譯沒有通過。

『陸』 布爾運算符的短路判斷的規則是什麼

預絕肆旦編譯處理,對於雙&&或雙||都是先判斷符號左邊的表達式為什麼,再決定是否要去判斷右邊的表達式(即執行),例如: 有int變數x=1,y=1,下面的代並擾碼:if(x==1&&++y==3),盡管右邊的是錯誤的,最後結果也是真,並且沒有執行++y這個操作,即執行完代碼後雹螞y的值依然為1,同理||也是如此,不同在於當左邊為假才短路。

『柒』 C語言中,如何定義一個布爾型變數

C語言中並沒有bool類型變數。這是C++中新增的系統類型。
要在C語言中使用bool類型,可以使用自簡猛定義的方式。
1 使吵咐手用整型做bool類型。
typedef int bool;

typedef unsigned char bool;
只要是整型,都可以當做bool使用。
2 使用枚舉類型做bool類升嫌型。
typedef enum
{
false,

true

}bool;
實際應用中,枚舉類型較為普遍。

『捌』 請問C語言中 *x++ (*x)++ ++*x *++x的區別

先比較++和*(指針)的優先順序,++較高。

那麼*x++就是取x指向內存的值,然後x+=1;

(*x)++是x指向內存的值,然後其內存的值自增1。

++*x 是x指向內存的值先自增1,在取該值。

*++x 是x先+=1,在取其指向內存的值。

++跟*的優先順序一樣,兩個若一起出現,運算順序是從右往左(不是常規的從左往右),所以++*x即++(*x)是先取x的值,然後讓值自己加1;(地址沒變,指針指向的值變了。)

*++x即*(++x),先讓x的自己加1,就是x的地址加上這個指針類型的步長(比如說這個指針是int類型,那它的地址+4,),然後再取x的值。(地址變了,但是值沒變)

(8)編譯原理布爾判斷必須從左往右嗎擴展閱讀:

基本數據類型

void:聲明函數無返回值或無參數,聲明無類型指針,顯示丟棄運指襪螞算結果。(C89標准新增)

char:字元型類型數據,屬於整型數據的一種。(K&R時好滾期引入)

int:整型唯埋數據,表示範圍通常為編譯器指定的內存位元組長。(K&R時期引入)

float:單精度浮點型數據,屬於浮點數據的一種。(K&R時期引入)

double:雙精度浮點型數據,屬於浮點數據的一種。(K&R時期引入)

Bool:布爾型(C99標准新增)

Complex:復數的基本類型(C99標准新增)

Imaginary:虛數,與復數基本類型相似,沒有實部的純虛數(C99標准新增)

Generic:提供重載的介面入口(C11標准新增)

類型修飾關鍵字

short:修飾int,短整型數據,可省略被修飾的int。(K&R時期引入)

long:修飾int,長整型數據,可省略被修飾的int。(K&R時期引入)

long long:修飾int,超長整型數據,可省略被修飾的int。(C99標准新增)

signed:修飾整型數據,有符號數據類型。(C89標准新增)

unsigned:修飾整型數據,無符號數據類型。(K&R時期引入)

restrict:用於限定和約束指針,並表明指針是訪問一個數據對象的唯一且初始的方式。

『玖』 用C++實現布爾表達式的真值問題

#include <stdio.h>

#include <string.h>


bool eval(const char*s){ if(!s) return 0;

if(*s==0 || *s==')') return 0;


if(*s=='(') return eval(s+1);


const char*p=s;

char c=*p++; if(c!='T' && c!='F') printf("Invalid expression. "); return 0;

bool v=(c=='T')?1:0;


if(*p=='!') v!=eval(p+1);

else if(*p=='|') v|=eval(p+1);

else if(*p=='&')v&=eval(p+1);

else if(*p!=0 && *p!=')')printf("Invalid expression... ");


return v;

}


int main(){

char*s="(T|T)&F&(F|T)";


printf("eval( %s )=%c Press Enter to quit... ", s, (eval(s)==0)?'F':'T');

getchar();

return 0;

}


『拾』 編程學習

Java語言適合初學者學習,
Java語言由語法規則和類庫兩部分組成,其中語法規則確定了Java程序的書寫規范,學習好語法規則是Java語言,也是所有編程語言的基本功。本文主要向大家簡單介紹一下Java的語法規則。 Java語言與C/C++語言有著緊密的聯系,Java中的許多術語來自於C++,起語法也來自於C++。因此Java的語法和c++的語法計劃一模一樣。下面簡單介紹一下Java的具體語法。

一、Java的詞法
1、標識符
標識符是類、變數和方法等的名字,作用是讓編譯器能夠識別它們。在Java語言中,標識符可以包含數字、字母、下劃線(_)和美圓符號($),但是不能以數字作為開頭。與C/C++語言不同的是,Java語言還可以將一些非拉丁字母包含在標識符中,這是因為Java語言使用的是Unicode字元,所有的十六進制00C0以上的Unicode字元都可以用在標識符中。但是Java語言的關鍵字是不能用來作為標識符的。

我們在使用標識符的時候應該盡量表達所要表示的類、變數、方法等的含義。另外,標識符中可以使用下劃線,我們應該充分利用這一點以提高程序的可讀性。

2、關鍵字

以下是Java的全部關鍵字:
abstract double int strictfp**
boolean else interface super
break extends long switch
byte final native synchronized
case finally new this
catch float package throw
char for private throws
class goto* protected transient
const* if public try
continue implements return void
default import short volatile
do instanceof static while
* 尚未使用的關鍵字
** 為Java 2增加的關鍵字

3、注釋

Java有三種形式的注釋:

第一種是C語言的傳統注釋方式,即將「/*」和「*/」之間的文本都視為注釋,這種注釋可以跨越多行。

第二種是C++風格的注釋,即將「//」之後直到行尾的文本都視為注釋,這種注釋只能包含一行。

第三種是Java新增加的注釋方式,即將「/**」和「*/」之間的文本都視為注釋,這種注釋也可以誇耀多行。注意,這種注釋方式生成的注釋將作為Javadoc文檔保存。

二、操作符
1、算術操作符

操作符 用途 優先順序 結合性
++,-- 自動遞增,自動遞減 2(僅次於括弧) 從右到左
+,- 一元加,一元減 2 從右到左
*,/ 乘,除 3 從左到右
% 取余(求模) 3 從左到右
+,- 加,減 4 從左到右

2、布爾運算與關系運算符
操作符 用途 優先順序 結合性
>,<,>=,<= 測試相對大小 6 從左到右
== 測試相等性 7 從左到右
!= 測試不等性 7 從左到右
?: 根據第一個操作數返回後兩個操作數之一 13 從左到右
! 非 2 從右到左
& 布爾與 8 從左到右
^ 異或 9 從左到右
| 布爾或 10 從左到右
&& 條件與 11 從左到右
|| 條件或 12 從左到右

3、位操作符
操作符 用途 優先順序 結合性
~ 非(位求補) 2 從右到左
<<,>> 左移,右移 5 從左到右
>>> 當作無符號右移 5 從左到右
& 位和 8 從左到右
^ 位異或 9 從左到右
| 位或 10 從左到右

4、賦值操作符
操作符 用途 優先順序 結合性
= 賦值 14 從右到左
*= 操作同時賦值 14 從右到左
/= 操作同時賦值 14 從右到左
%= 操作同時賦值 14 從右到左
+= 操作同時賦值 14 從右到左
-= 操作同時賦值 14 從右到左
>>= 操作同時賦值 14 從右到左
<<= 操作同時賦值 14 從右到左
>>>= 操作同時賦值 14 從右到左
^= 操作同時賦值 14 從右到左
|= 操作同時賦值 14 從右到左
&= 操作同時賦值 14 從右到左

5、特殊操作符
cast操作符將一種數據類型轉換成為另一種數據類型,cast應寫成把要校正操作數的類型名放在括弧中。

例如: int i; long l; l=7876547; i=(int)l; 如果給高精度的變數賦予一個低精度值,則不需校正。類型校正操作符的優先順序為2,結合性為從右到左結合。

將以上講到的操作符的優先順序總結如下:

優先順序 運算符 結合順序
1 []數組運算 .點運算符 ()調用方法 從左到右
2 ! ~ ++ -- +(一元加) -(一元減) ()強制類型轉換 new 從右到左
3 * / % 從左到右
4 +(二元加) -(二元減) 從左到右
5 >> << >>> 從左到右
6 < <= > >= instanceof 從左到右
7 == != 從左到右
8 & 從左到右
9 ^ 從左到右
10 | 從左到右
11 && 從左到右
12 || 從左到右
13 ?: 從左到右
14 = += -= *= /= %= &= |= ^= <<= >>= >>>= 從右到左

三、常量
1、整型常量

在Java語言中,整型常量有三種形式,它們分別是:十進制、八進制、十六進制。
需要注意的是十進制數不能以0開頭,這是因為八進制的數是以0開頭的,而十六進制數以0x或0X開頭。

2、浮點型常量

浮點數只能表示十進制數。浮點數有兩種表示方法,即標准表示法和科學記數法。浮點數又分為單精度數和雙精度數。

3、布爾型常量

布爾型常量有兩個值:ture(或TURE)和false(或FALSE)它們分別表示真和假,這兩個值用來表示事物的狀態,它們必居其一。通過測量布爾值可以判斷是否執行某個步驟。

4、字元型常量

字元型常量是一個單一的字元,其形式是由兩個單引號引起來的一個字元。但是兩個單引號引起來的不能是單引號和反斜杠,即『』和『\』是不正確的寫法。

大家一定要記住,Java語言中的字元是16位的Unicode字元,這與C/C++等語言是不一樣的。

同C/C++語言一樣,Java語言也有轉意序列。Java中的轉意序列的功能見下表:

轉義序列 標准形式 功能描述
\ 繼續
\n NL 回車換行
\t HT 水平製表符
\b BS 後退一格
\r CR 回車不換行
\f FF 換頁
\ 單引號
\\ \ 反斜杠
\" " 雙引號
\ddd 0ddd 八進制模式
\xddd 0xddd 十六進制模式
\udddd 0xdddd Unicode雙位元組字元

字元串常量
字元串常量是由雙引號引起來的一系列字元,與C/C++語言中不同的是,Java語言中的字元串不是通過字元數組來實現的,而是通過字元串類(即String類)來實現的。

四、變數和數據類型
在Java中,數據的類型可以分為四種:基本數據類型、數組類型、類和介面類型。任何數據都一定是上述數據類型的一種。
其中基本數據類型可以分為四大類:布爾型、字元型、整數型和浮點型。這些類型的數據與前面介紹的常量的類型基本相同,在此不再多說。下面將整數型和浮點型變數的取值范圍列出:

表一、

類型 寬度 取值范圍
byte 8位 -256到256
short 16位 -32768到32767
int 32位 -2147483648到2147483647
long 64位 -9223372036854775808到9223372036854775807

表二、

進制 整數 長整數
十進制 最大正整數 2147483647(2的31次方減1) 923372036854775807L(2的63次方減1)
八進制 最大正整數 077777777777(2的31次方減1) 07777777777777777777L(2的63次方減1)
最小負整數 020000000000(-2的31次方) 04000000000000000000L(-2的63次方)
十六進制 最大正整數 0x7fffffff(2的31次方減1) 0x7fffffffffffffffL(2的63次方減1)
最小負整數 0x80000000(-2的31次方) 0x8000000000000000L(-2的63次方)

浮點數能表示的數值從小到大分別是:負無窮大、負有限值、負零、正零、正有限值及正無窮大。其中正零和負零在進行數值比較的時候是相等的,但仍有辦法分辨這兩個值,例如在進行1.0/0.0的時候會得到正無窮大的結果。其它非零非無窮大的有限值是以s*m*(2^e)來表示的,s和m的取值范圍見下表:
表三、

類型 s m e
float +1或-1 小於2的24次方的正整數 149到104的整數
double +1或-1 小於2的53次方的正整數 1045到1000的整數

表四、float 最大值 3640282347e+38f
非零最小值 1.40239846e-45f
double 最大值 1.79769313486231570e+308
非零最小值 4.940656458412465334e-324

另外浮點數還有一些特殊值,見下表:float 最大值 Float.MAX_VALUE
最小值 Float.MIN_VALUE
正無窮大 Float.POSITIVE_INFINITY
負無窮大 Float.NEGATIVE_INFINITY
NaN Float.NaN
double 最大值 Double.MAX_VALUE
最小值 Double.MIN_VALUE
正無窮大 Double.POSITIVE_INFINITY
負無窮大 Double.NEGATIVE_INFINITY
NaN Double.NaN

與C/C++語言中不同的是,在Java語言中,所有的基本數據類型都有預設值,就是說當我們聲明一個變數時,即使我們沒有對它賦值,它的值也是一定的,而不像在C/C++中那樣是不可預測的。具體個類型的預設值見下表:

基本數據類型 預設值
Boolean false
Char \u000
Byte (byte)0
Short (short)0
Int 0
Long 0L
Float 0.0L
Double 0.0d

五、Java與C/C++的比較
由於Java的語法直接來源於C/C++,所以Java的程序控制語句與C/C++一模一樣,在此不再多說。以下重點介紹一下Java與C/C++的不同。
指針

大家在使用C語言編程的時候想必都曾經因為指針的復雜計算而煩惱,在C/C++語言編程過程中,指針可能引起許多錯誤,這些復雜的指針演算法所產生的錯誤常常讓人迷惑不解,導致C/C++程序員在此浪費了大量的時間。考慮到這種原因,Java中取消了指針。指針的功能由參考(reference)所取代,這使得Java中對復雜數據結構的實現更加容易,因為用對象和對象數組實現復雜的數據結構更可靠。

函數

在Java中沒有C/C++中應用廣泛的函數,C/C++中通過函數實現的功能在Java中都是通過類和方法來實現的。

繼承

C++支持多重繼承,這是一個從多個父類中派生一個類的有效辦法,但這種派生很復雜,也很容易產生問題。因此,Java中沒有採用多重繼承,但Java的Objective C協議介面能完成C++中多重繼承的所有功能。

goto語句

大家知道,在使用高級語言編程時過多的使用goto語句會使程序變得十分混亂,因此Java中也沒有使用goto語句。但是不可否認,當程序比較容易控制的時候,適當使用goto語句能使程序的運行更快捷,因此Java中使用了多重break和continue語句(允許break和continue語句使用標簽)實現C++種goto語句的功能。

聯合和結構

在C++中有三種數據結構:聯合、結構和類;Java中只有類,它可以實現上述三者的功能。

字元串

在C/C++中,字元串是通過字元數組實現的,但是由於數組的空間不是動態分配的,這容易出現越界錯誤,例如:常有預先設定的字元數組不能容納後輸入的字元串。在Java中,字元串是一類特定的對象,這使得字元串更具有一致性和可預見性。

Typedef、Define和預處理器

Java中不需要#define語句、預處理器或者typedef,但需要頭文件。在Java中一個類的信息必須包含在一個文件中,而C/C++中有關類的信息可能分散在多個文件中。

數據類型的自動強制轉換

在Java中強制一種類型的數據元素變成一種不太精確的數據類型需要編程人員採用預測方法。

閱讀全文

與編譯原理布爾判斷必須從左往右嗎相關的資料

熱點內容
怎麼使用access的命令按鈕 瀏覽:897
有點錢app在哪裡下載 瀏覽:832
博途v15解壓後無法安裝 瀏覽:203
什麼是根伺服器主機 瀏覽:436
安卓手游怎麼申請退款 瀏覽:553
安卓系統如何分享網頁 瀏覽:278
ad如何編譯pcb工程 瀏覽:412
除了滴滴app哪裡還能用滴滴 瀏覽:399
截圖怎麼保存文件夾然後壓縮 瀏覽:8
幻影伺服器怎麼樣 瀏覽:27
具體哪些廣東公司招程序員 瀏覽:870
嵌入式編譯器教程 瀏覽:306
ssl數據加密傳輸 瀏覽:86
51單片機定時器方式2 瀏覽:331
命令行查看開機時間 瀏覽:813
python微博復雜網路分析 瀏覽:550
rf3148編程器 瀏覽:505
浙江標准網路伺服器機櫃雲主機 瀏覽:589
設置網路的伺服器地址 瀏覽:600
java圖形界面設計 瀏覽:751