目錄node
區分這些名詞須要兩個概念,做用域(scope)和存儲持續時間(storage duration),前者定義了在何處能夠訪問變量,後者定義了在什麼時候能夠訪問變量。linux
例如:在如下的systemverilog代碼中,global_int被聲明爲類成員,而且在整個類中具備全局做用域,而當取消引用該類的對象時,其生命期結束。global_static變量被聲明爲靜態變量並具備全局做用域整個類以及整個程序的生命週期,即便取消引用類的對象也存在。sum變量對於函數compute()是局部的,而且僅在函數內部可見,而且僅在compute執行時存在, count變量在函數compute()中是局部變量,僅在函數範圍內可見,但因爲它是靜態的,所以即便在屢次執行函數compute()以後,它也只有單個副本並保留該值.ios
class test_class; int global_int; //automatic by default static global_static; //global static variable void function compute() begin static int count; //local static variable local int sum; //local automatic variable sum = sum +1; count = count +sum; end endfunction endclass
內聯函數時調用時會進行展開內聯的函數,即編譯器會將函數調用替換爲相應函數代碼。若是函數很是小而且在多個地方使用,使用內聯函數會更有優點。這麼作會提升運行速度,沒有調用函數和從函數返回的開銷。程序員
例如:在C語言中,定義一個名爲max的內聯函數,在main內部的每次調用都會經過替換代碼實現,而不是函數調用實現。正則表達式
inline int max(int a, int b) { return a > b ? a : b; } main () { int a1,a2,a3,b1,b2,b3; int c1,c2,c3; c1 = max(a1,b1); c2 = max(a2,b2); c3 = max(a3,b3); }
正則表達式是特殊的字符序列,可使用特殊的語法幫助用戶匹配或查找其餘字符串(或字符串集)。 它是用於字符串內模式匹配的最強大的概念之一,普遍用於Perl,Python,Tcl等語言。算法
棧是內存的一塊特殊區域,用於存儲由函數建立的臨時變量。每次函數聲明一個新的自動變量時,它將被壓入棧,而且每次函數退出時,會刪除壓入棧的全部變量。全部局部變量都使用棧進行存儲,而且時自動管理的,也有大小限制。若是棧的空間不足,則會出現棧溢出錯誤。shell
堆則是須要管理的內存區域,程序員須要分配和釋放內存,某些語言中是自動完成的。堆一般用於存儲靜態變量和對象。與棧相比,堆略慢,而且是經過指針應用的,而且能夠在任何位置應用堆的變量。堆的大小也是能夠更改的,當可用內存是不連續的塊時,堆可能會出現碎片問題。編程
++a首先「a」自增,而後返回引用「a」的值。 所以,若是將「++ a」分配給變量,則將使用遞增值「a」。數組
a++首先返回值「a」(當前值爲「a」),而後「a」自增。所以,若是將「a ++」分配給變量,則將在分配中使用舊值「a」。緩存
當咱們動態分配內存但以某種方式失去到達該內存的方式時,這稱爲內存泄漏。 在某些編程語言(如C ++)中,應釋放(經過調用析構函數)完成的每一個內存分配(例如,建立對象),不然,這些內存將泄漏且再也不可用。 在某些其餘語言(例如SystemVerilog,Java等)中,語言內部機制負責清理內存,而且內存泄漏的可能性較小。
機器(例如計算機)理解代碼是經過二進制的,機器能夠理解的二進制代碼稱之爲「機器碼」。程序員一般使用高級編程語言(C,C++,Perl,Python)變寫計算機程序或者代碼。編譯器和解釋器就是將這些源代碼轉換爲機器代碼的程序。
編譯器 | 解釋器 |
---|---|
掃描整個程序並將整個源代碼轉換爲機器代碼 | 一次掃描並轉化一行源代碼 |
須要大量的時間去分析源代碼 | 只須要少許時間用於分析源代碼 |
輸出機器專用的二進制碼 | 輸出代碼是某種中間代碼,由另外一個程序解釋 |
執行速度更快(計算機硬件運行) | 執行更慢(由另外一個程序執行) |
掃描整個程序後報告錯誤 | 一直運行,直到遇到第一個錯誤,而且中止程序 |
靜態語言:靜態語言是一種在編譯時固定類型的語言。 這意味着您須要在使用它們以前聲明全部變量及其數據類型。 例如:Java,C和SystemVerilog是靜態類型的語言。
動態語言:動態語言是一種在執行時肯定類型的語言。這與靜態類型的語言相反。 例如:VBScript和Python是動態類型的,所以在使用以前不須要聲明全部變量及其數據類型。 他們會在首次爲變量分配值時弄清楚變量的類型。
選項2是錯的,棧是LIFO而非FIFO,先入後出。
靜態內存分配 | 動態內存分配 |
---|---|
內存在編譯時分配 | 內存在運行時分配 |
內存被分配到棧上或者程序的其餘部分 | 內存分配到堆上 |
不須要釋放內存,靜態變量的生命週期就是程序的生命週期 | 須要及時釋放內存 |
固定大小,一旦分配之後內存大小就不能改變 | 可以改變大小 |
執行更加快 | 執行更加慢 |
在代碼中,預處理器指令是以#開頭的行。它們充當預處理程序的指令,預處理程序在代碼編譯開始以前檢查代碼。其結果就是替換了源代碼中的某些代碼。例如:預處理程序指令的常規語法爲:#define標識符值每當預處理程序在源代碼中遇到「標識符」時,它將用「值」替換,並在編譯以前生成新的源代碼。
namespace是指標識符的各類可見範圍。命名空間用關鍵字namespace 來定義。命名空間是C++的一種機制,用來把單個標識符下的大量有邏輯聯繫的程序實體(例如類、對象和函數)組合到一塊兒。"std"是"standard"一詞的縮寫。 standard namespace (std namespace)是一種特殊類型的名稱空間,其中保留了全部內置的C ++庫(例如字符串,cin,cout,vector等)。 所以,"using namespace std"告訴C ++編譯器使用標準C ++庫。
const關鍵字告訴編譯器,該變量或對象一旦進行初始化便不可更改。因此,int a 聲明後,後續能夠對變量a進行更改,而const int a,後續不可更改
volatile提醒編譯器它後面所定義的變量隨時都有可能改變,所以編譯後的程序每次須要存儲或讀取這個變量的時候,都會直接從變量地址中讀取數據。若是沒有volatile關鍵字,則編譯器可能優化讀取和存儲,可能暫時使用寄存器中的值,若是這個變量由別的程序更新了的話,將出現不一致的現象。volatile關鍵字主要在與內存映射的輸入輸出(硬件)接口時使用。 變量聲明爲volatile以後,編譯器將沒法執行任何優化,例如:刪除內存分配,將變量緩存在寄存器中或更改分配的執行順序。
指針是一個變量,其值是另外一個變量的地址。星號*表示指針,int * p 告訴編譯器變量「p」是一個指針,其值是存儲整數變量的存儲位置的地址。 一樣,float * f; 告訴編譯器變量「 f」是一個指針,其值是存儲浮點變量的存儲位置的地址。如下列代碼爲例
int a = 10; int *b; int c; b = &a; c = *b; printf(「b=%d and c=%d\n」,b,c);
其中a是一個變量,他的值是10,b是一個指針,經過語句 b = &a 將a的地址傳給了指針b。而經過c = *b 將指針b內地址所指向的值,即a的值賦予c。
void Exchg1(int x, int y) { int tmp; tmp = x; x = y; y = tmp; printf("x = %d, y = %d\n", x, y); } main() { int a = 4,b = 6; Exchg1(a, b); printf("a = %d, b = %d\n", a, b); return(0); }
void Exchg2(int *px, int *py) { int tmp = *px; *px = *py; *py = tmp; printf("*px = %d, *py = %d.\n",*px, *py); } main() { int a = 4,b = 6; Exchg2(&a, &b); printf("a = %d, b = %d.\n", a,b); return(0); }
void Exchg3(int &x, int &y) { int tmp = x; x = y; y = tmp; printf("x= %d,y = %d\n", x, y); } main() { int a = 4,b =6; Exchg3(a, b); printf("a= %d, b = %d\n", a, b); return(0); }
NULL指針能夠定義爲:int * a = NULL; NULL指針的值爲0。指針是一個變量,其值是另外一個變量的地址。 因爲指針的值是地址,因此指針的大小會因機器而異。 若是是32=4*8位計算機,則指針大小爲4個字節,若是計算機大小爲64=8*8位,則指針大小爲8個字節。
鏈表是一種物理存儲單元上非連續、非順序的存儲結構,數據元素的邏輯順序是經過鏈表中的指針連接次序實現的。鏈表由一系列結點(鏈表中每個元素稱爲結點)組成,結點能夠在運行時動態生成。每一個結點包括兩個部分:一個是存儲數據元素的數據域,另外一個是存儲下一個結點地址的指針域。
一共有三種不一樣類型的鏈表:
算法的時間複雜度表明了算法的運行時間,n表明輸入算法的參數數量。一般使用big O算法進行評估,例如某算法隱形時間爲5n^4 + 6n^2 + 1,取最高階爲n^4,那麼其算法複雜度爲O(n^4)。因此以上算法的算法複雜度爲:
空間複雜度的概念相似於時間複雜度,可是衡量的值是算法運行時所須要的內存空間。以上算法的空間複雜度爲:
&是按位與運算符,而&&是邏輯與運算符。 邏輯運算符使用布爾值-真(1)和假(0),並返回布爾值。 按位運算符對每一個位執行位操做並返回位值。
按位運算符:若是a = 10而b = 6,則a&b將返回2(4'b1010&4'b0110 = 4'b0010)
邏輯運算符:若是a = 10而b = 6,則如下表達式將返回true,由於對兩個布爾值進行操做,則爲true c =(a == 10)&&(b == 6);
Struct分配足夠的空間來存儲結構中的全部字段/成員。 第一個存儲在Struct的開頭,第二個存儲在Struct的開頭,依此類推。
Union僅分配足夠的空間來存儲列出的最大字段,而且全部字段都存儲在同一空間中。 這是由於在Union中,一次只能使用一種類型的封閉變量,而不是能夠引用全部封閉變量的struct。
struct ID { int IntID; char CharID[8]; };
須要12個字節,int須要4個字節,char數組須要8個字節。
union ID { int IntID; char CharID[8]; };
須要8個字節,數組CharID須要8個字節。
內核是一種計算機程序,它用於管理來自軟件的輸入/輸出請求,並將這些請求轉換爲CPU指令或其餘指令。
Practical Extraction and Reporting Language。
Cron Job是操做系統中基於時間的做業調度程序。 它容許在指定的時間,日期,間隔等自動按期運行做業。例如:假設用戶具備Shell或Perl腳本,該腳本計算UNIX / Linux中磁盤的人均磁盤空間使用狀況。 在UNIX / Linux中爲此腳本以指定的頻率(或時間)設置Cron Job將確保該腳本在計劃的時間(或頻率)下自動運行,而用戶無需每次都手動運行它。
「 rsync」表明「Remote Sync(遠程同步)」,它是在磁盤,網絡,服務器和機器之間複製或同步文件/目錄的經常使用命令。 rsync僅移動文件中已更改的那些部分,所以能夠將須要複製的數據量減至最少。 「 rsync」在發送和接收數據時使用某些壓縮和解壓縮方法,進步減少帶寬消耗。 「 rsync」命令最多見的用途之一是在兩臺計算機之間執行數據備份和鏡像磁盤等操做。
字符串老是以'\0'做爲串的結束符。所以當把一個字符串存入一個數組時,也把結束符 '\0'存入數組,並以此做爲該字符串是否結束的標誌。
二叉樹是鏈表概念的擴展。 一個二叉樹的節點有兩個指針:「一個左指針」和「一個右指針」。 每個節點能夠進一步分支以造成另外的節點,每一個節點也具備兩個指針。
類是能夠組合在一塊兒的一組屬性和相關行爲。 對象是類的實例,表示具備屬性和行爲的真實實體。 可使用類數據成員來表示屬性,而可使用方法來表示行爲。 例如:能夠將動物表示爲一類,而不一樣的動物(如狗,貓等)能夠是該動物的對象。
最初,在C中定義了一個「結構體」,以將不一樣的數據類型組合在一塊兒以執行某些已定義的功能。 可是,在C++中,這種結構體也擴展爲包括函數的結構。 「類」也是一種數據類型,能夠將不一樣的數據類型和其對應的方法進行分類。 C++中二者的區別之一是,類的全部成員默認狀況下都是私有的,而結構的全部成員默認狀況下都是公共的。
在SystemVerilog中,基於要執行的某些功能,類和結構都用於定義一堆數據類型。 可是,結構是總體式的類型,在聲明結構時會分配必要的內存。 類是動態類型,一旦聲明瞭一個類,就只能將一個類句柄引用爲null。 內存分配僅在建立該類的實際對象時發生。
這三者是類成員的不一樣訪問屬性
多態性是指具備多種形式的能力。 在OOP上下文中,這是指實體在運行時引用各類類的對象的能力。 這能夠經過SystemVerilog中的繼承和虛函數的概念(以及C++中存在的函數和運算符重載的概念)來實現。根據對象的類型,將從相應的類中調用適當的方法。
在面向對象的編程中,運算符重載是多態的一種特殊狀況,能夠從新定義或重載可用的不一樣內置運算符。 所以,程序員也能夠將運算符與用戶定義的類型一塊兒使用。 C++支持此功能,而SystemVerilog不支持此功能。 如下示例顯示了一個Testclass,其中運算符+被重載,從而能夠把兩個類型爲「Testclass」的類對象相加。 而後,實現未來自兩個對象的數據成員相加,並將其分配給結果類的數據成員。
#include <iostream> class Testclass{ public: int a; int b; Testclass operator+(const Testclass& obj); } Testclass Testclass::operator+(const Testclass& obj2){ Testclass tmp_obj = *this; tmp_obj.a = tmp_obj.a + obj2.a; tmp_obj.b = tmp_obj.b + obj2.b; return tmp_obj; } int main(void){ Testclass obj1, obj2, obj3; obj1.a = 1; obj1.b = 1; obj2.a = 2; obj2.b = 2; obj3.a = 0; obj3.b = 0; obj3 = obj1 + obj2; std::cout<<obj3.a<<" "<<obj3.b<<"\n"; return 0; }
構造函數是類的特殊成員函數,每當建立該類的實例時,構造函數就會自動調用。 在C++中,它與類具備相同的名稱。 在SystemVerilog中,它做爲new()函數實現。
與構造函數相反,當對象結束其生命週期,如對象所在的函數已調用完畢時,系統會自動執行析構函數。 在C++中,它與類具備相同的名稱,並帶有波浪號字符前綴,而在SystemVerilog中,因爲該語言支持自動垃圾收集,所以沒有析構函數。
組合使兩個類之間具備「has - a」關係。 當一個類實例化另外一個類的對象時,該關係爲「 has-a」,而且此屬性稱爲composition。
繼承使兩個類之間具備「is - a」關係。 當一個類從另外一個類派生時,該關係爲「 is-a」,而且此屬性稱爲繼承。
下圖說明了這一點。 基類汽車中派生出福特類,則該關係爲「is-a」,這意味着福特類爲汽車類。 若是福特類內部具備引擎類的對象,則關係爲「has - a」,如圖所示。
在淺拷貝中,將建立一個新對象,該對象具備與原始對象中的值徹底相同的副本。 若是對象的任何字段是對其餘對象的引用,則僅複製引用地址(句柄)。在深拷貝中,將建立一個新對象,該對象具備與原始對象相同的值的精確副本。 若是任何對象都引用了其餘對象,則還將複製屬於該對象的全部值的副本,而不只僅是內存地址或句柄。所以,稱爲深拷貝。
例如,對好比下兩個類。
class A; int a; int b; endclass class B; int c; A objA; endclass
若是在類B中實現了淺拷貝方法,則當咱們將B複製到新對象時,僅複製「 objA」的內存句柄。 在深度複製的狀況下,還將複製A的全部值(即其數據成員a和b),而不是「objA」的內存句柄。
虛方法是在基類中聲明的成員方法,而且能夠由派生類從新定義。 要建立虛方法,在基類中的方法聲明以前要加上關鍵字virtual。 在派生類中從新定義基類方法的這種方式也稱爲方法重寫。使得調用方法時,是根據對象類型而不是句柄類型調用函數。
多重繼承是某些面向對象的計算機編程語言的功能,其中對象或類能夠從多個父對象或父類繼承特徵和功能。 它不一樣於單一繼承,在單一繼承中,一個對象或類只能從一個特定的對象或類繼承。注意:C++支持多重繼承,而SystemVerilog語言則不支持。
抽象類是包含一個或多個抽象方法的類。 抽象方法是已聲明但不包含任何實現的方法。 抽象類可能沒法實例化,而且須要子類爲抽象方法提供實現。 在SystemVerilog中,類名前面帶有虛擬關鍵字,以使其成爲抽象類。 如下是如何使用函數定義爲virtual定義抽象類的示例。 而後派生的類能夠實現此功能。至關於一個模板類。
靜態方法是使用static關鍵字在類內部定義的方法。 能夠在不建立類對象的狀況下使用它們。 一樣,若是有多個此類建立的對象,則仍然只有一個靜態方法成爲全部對象的一部分。
該指針是一個特殊的指針,可用於在類範圍內引用該類的當前對象。
type conversion 和 type casting的最大區別就是,type conversion有編譯器自動(隱式)轉換的,而type casting是顯式完成的。
比較內容 | type casting | type conversion |
---|---|---|
意義 | 一個數據類型由用戶分配給另外一個數據類型,使用強制轉換運算符,稱爲"type casting"。 | 編譯器自動將一種數據類型轉換爲另外一種數據類型稱爲"type conversion"。 |
應用 | 類型強制轉換也能夠應用於兩個"不兼容"的數據類型。 | 僅當兩個數據類型"兼容"時,才能實現類型轉換。 |
算子 | 要將數據類型強制轉換到另外一個數據類型,須要強制轉換運算符"()"。 | 無需操做符。 |
實現 | 它在程序設計過程當中完成。 | 它在編譯時顯式完成。 |
下面第一個例子是type casting,第二個是type conversion
int a; byte b; ... ... b= (byte) a; //////////////////////////////////////// int a=3; float b; b=a; // value in b=3.000.
經過man <command-name> ,例如man grep
任意一種: a) head -10 file.txt b) cat file.txt | head -10 c) sed 「11,$ d」 file.txt head -10 file.txt | tail -1 sed -i 「13 d」 file.txt sed -i 「$ d」 file.txt echo 「Hello」 | rev echo $? cat file.txt | wc -l cat file.txt | wc -c head -17 file.txt | tail -1 | wc -c head -17 file.txt | tail -1 | cut -f3 -d’ ‘ chmod 555 file.txt chgrp new_group file.txt cat file1.txt file2.txt > file.txt ps -aef sort -u file1.txt > file2.txt whoami ssh username@remote-server
grep 「cat」 file.txt grep -w 「cat」 file.txt grep -v -w 「cat」 file.txt grep -i 「cat」 file.txt grep 「^cat」 file.txt grep 「cat$」 file.txt grep 「cat.*123」 file.txt
grep -ilr 「I am preparing for Interview」 /usr/bin/dir/*
foreach x (`cat /usr/home/file.txt`) foreach> cd $x foreach> script.pl foreach> end
grep -v 「^$」 file1.txt > file2.txt
find . -name 「file.txt」 OR find -name 「file.txt」 find /usr/bin/DIR -name 「file.txt」 find -maxdepth 1 -name 「file.txt」 find . -name 「*dummy*」 find . -iname 「file」 find -not -name 「file.txt」 ! find
crontab -l crontab -u <user_name> -l crontab -r crontab -u <user_name> -r crontab -e 30 18 * * * <command_to_invoke_your_process> * * * * * <command_to_invoke_your_process> 30 6 1-20 * * <command_to_invoke_your_process> 30 6 18 * * 6 <command_to_invoke_your_process> (assuming Sunday is represented by 0)
什麼是大小端請參考問題[32]
#include <stdio.h> int main() { unsigned int i = 1; char *c = (char*)&i; if (*c) printf("Little Endian \n"); else printf("Big Endian \n"); return 0; }
a = 10; b = a++; c = ++a;
b等於10,而c等於12。後置自增運算符僅在賦值後才進行自增,所以b獲得的是自增前的值。 前置增量運算符將首先進行自增,所以a將從11(在b = a++後變爲11)增長到12
#include<stdio.h> int xyz=10; int main() { int xyz=20; printf("%d",xyz); return 0; }
變量xyz定義了全局變量和局部變量,而在函數中,優先調用的是局部變量,因此將爲打印出20.
int main() { int x=4; float y = * (float *) &x; return 0; }
一個很小的值。 一些編譯器可能會將答案顯示爲0。「(float *)&x」,告訴編譯器指針指向存儲在內存位置的浮點數。 浮點數的存儲方式不一樣於整數(對於浮點數,位[31]表示帶符號的位,位[30:23]表示指數,位[22:0]表示分數)。 所以,當解釋爲浮點數(00000000000000000000000000000100)時,值將爲很是小。
#include<stdio.h> int main() { int i=0; for(i=0;i<20;i++) { switch(i) { case 0:i+=5; case 1:i+=2; case 5:i+=5; default: i+=4; break; } printf("%d\n",i); } return 0; }
輸出是16,21。
注意兩點,i在循環內進行了修改,case後沒有跟着break。第一次進入循環,i將一次加5 2 5 4,而後打印輸出16,最後再加1。第二次直接進入default,加4,而後輸出21。
int factorial (int x) { if ( (x==0) || (x==1) ) return 1; else return (x*factorial(x-1)); }
int fibonacci (int num){ if( (num==0) || (num==1) ) return num; else return (fibonacci(num-1) + fibonacci(num-2)); }
#include <stdio.h> int main() { int x = 10000; double y = 56; int *p = &x; double *q = &y; printf("p and q are %d and %d", sizeof(p), sizeof(q)); return 0; }
輸出是p and q are 8 and 8 。
因爲「p」和「q」是指針,所以它們只不過是64位計算機中的地址。 不管它們指向整數仍是雙精度數據類型,二者的大小均爲64位(8字節)。
鏈表是由一組節點組成的數據結構,這些節點一塊兒表明一個序列。鏈表是由一組節點組成的數據結構,這些節點一塊兒表明一個序列。若是咱們不知道要存儲的數據量,則首選鏈表。 例如:咱們能夠在員工管理系統中使用連接列表,在這裏咱們能夠輕鬆地添加新員工的記錄(添加新節點-動態內存分配),刪除舊員工的記錄(刪除節點),編輯 員工記錄(在節點中編輯數據)。
在[136]-[140]中,使用下列變量和定義:
struct node; typedef struct node NODE; typedef int Element; // A pointer to a node structure typedef NODE *LINK; // A node defined as having an element of data // and a pointer to another node struct node { Element elem; LINK next; }; // The Head or start of the List typedef struct { int size; LINK start; } ListHead;
要建立單鏈表,咱們須要:
建立鏈表的HEAD(h)
初始化鏈表的大小(爲零)
將起始指針指向NULL(在建立時爲空)。
請參考如下函數來建立單鏈表:
ListHead createList() { ListHead h; h.size = 0; h.start = NULL; return h; }
在鏈表(h)的頭部插入元素(e)時,咱們須要:
爲新節點動態分配內存。
爲新節點中的元素分配值。
將新節點中的「next」指針指向HEAD先前指向的節點。
在連接列表HEAD中,增大「size」變量(隨着添加了新節點),而後將「start」指針指向新節點。
ListHead InsertElementAtHead(Element e, ListHead h) { LINK nl= (LINK) malloc (sizeof(NODE)); nl->elem = e; nl->next = h.start; h.start= nl; h.size++; return h; }
在連接列表(h)的末尾插入元素(e)時,咱們須要:
爲新節點動態分配內存。
爲新節點中的元素分配值。
將新節點中的「next」指針指向NULL(由於新節點表明鏈表的尾部)。
若是鏈表最初爲空,則將HEAD中的「start」指針指向新節點,不然遍歷連接列表以找出連接列表中的最後一個節點,並將最後一個節點中的「next」指針指向新節點。
在鏈表HEAD中增大「size」變量(隨着添加了新節點)。
ListHead InsertElementAtTail(Element e, ListHead h) { LINK temp; LINK nl; nl=(LINK) malloc (sizeof(NODE)); nl->elem=e; nl->next=NULL; if(h.start==NULL) h.start=nl; else { temp=h.start; while(temp->next!=NULL) temp=temp->next; temp->next=nl; } h.size++; return h; }
在鏈表(h)中的pos處插入元素(e)時,咱們須要:
爲新節點動態分配內存,
爲新節點中的元素分配值。
若是「pos」大於鏈表的大小,則返回錯誤消息(由於這是不可能的)。 不然,若是「 pos」爲「 0」,則將元素插入頭部(如上所示)。 不然,將鏈表遍歷到「 pos」以前的節點。 將新節點中的「next」指針指向「pos-1」處的節點所指向的節點,並將節點中「pos-1」處的「next」指針指向新節點。
在鏈表HEAD中增大「size」變量(隨着添加了新節點)。
ListHead InsertAtPos(Element e, ListHead h, int pos) { LINK temp; LINK nl; nl=(LINK)malloc(sizeof(NODE)); nl->elem=e; int count=0; if(pos>h.size) { printf("Error: Wrong position \n"); return h; } if(pos==0) { nl->next=h.start; h.start=nl; } else { for (temp = h.start; count<(pos-2); temp = temp->next, count++) ; nl->next=temp->next; temp->next=nl; } h.size++; return h; }
從鏈表(h)中刪除元素(e)時,咱們須要:
1.檢查鏈表是否爲空。 若是爲空,則無需刪除任何內容。
2.若是鏈表不爲空,則須要遍歷鏈表以找到包含元素(e)的節點。 找到節點以後,咱們須要在要刪除的節點以前更改節點中的「next」指針,以指向要刪除的節點的「next」指針中存的值。
3.減少鏈表HEAD中的「size」變量(由於刪除了節點)。
ListHead DeleteElement(Element e, ListHead h) { LINK cur, prev; cur=h.start; if(cur==NULL) { printf ("Empty List \n"); return h; } while(cur!=NULL) { if(cur->elem==e) { if(cur==h.start) h.start=cur->next; else prev->next=cur->next; free(cur); h.size--; break; } prev=cur; cur=cur->next; } return h; }
my @value_array = ("Index0","Index1"); my $value; foreach $value (@value_array){ $value =~ s/Index//; } print "@value_array\n";
結果:0 1
在foreach中使用$value索引,將會改變數組的值
my @value_array = ("Index0","Index1"); my $value; for(my $i=0; $i<@value_array; $i++) { $value = $value_array[$i]; $value =~ s/Index//; } print "@value_array\n"
$value對於for循環來講是局部的,不會影響數組內容
-w是用於標記warning,對潛在的歧義代碼進行警告。
use strict是Perl中編譯指令,是提供給Perl編譯器的指令,告訴編譯器,若是perl代碼中有很差的編碼風格,那麼提示編譯失敗。也就是說,加上use strict後,咱們的Perl代碼的編寫必須遵循一些規範,不然編譯器會報錯。
my $line_in_a_file = "I am preparing for an Interview"; my $line_in_a_file =~ s/a/A/; print "$line_in_a_file\n";
匹配第一個a,替換爲A。所以輸出爲「I Am preparing for an Interview」
my $line_in_a_file = "I am preparing for an Interview"; my $line_in_a_file =~ s/a/A/g; print "$line_in_a_file\n";
g表明global,進行全局匹配,將全部的a都替換爲A。所以輸出爲「I Am prepAring for An Interview」
my $string1 = "I am preparing "; my $string2 = "for an Interview"; my $string = __?__
Perl使用「.」進行填充。所以空白處應該填寫$string1.$string2
#!/usr/bin/perl use warnings; use strict; my $scalar =0; my @array = ("A","B","C","D"); $scalar = @array; print "Scalar is $scalar\n";
標量會存儲數組的元素數量,所以打印出來的值是4
在[151]-[155]中使用以下代碼,針對問題再下面的空白處填空
#!/usr/bin/perl use warnings; use strict; my $input_file = "input_file.txt"; my $output_file = "output_file.txt"; my @input_array; open(OUTPUT_FILE,'>',$output_file) or die "Cannot Open $output_file file for writing\n$!\n"; open(INPUT_FILE,'<',$input_file) or die "Cannot Open $input_file for reading\n$!\n"; while(<INPUT_FILE>){ if($_ =~ /__?__/){ print OUTPUT_FILE $_; } } close INPUT_FILE; close OUTPUT_FILE;
^([a-z]+)$
^([a-zA-Z]+)$
^([a-zA-Z0-9]+)$
\$
^([\\\$]+)$
chop:刪除字符串的最後一個字符,並返回該字符
chomp:刪除字符串結尾的換行符,並返回刪除的字符數
#!/usr/bin/perl use warnings; use strict; my $example_1 = "chop_example"; my $example_2 = "chop_example"; chop($example_1); my $b = chop($example_2); print "$example_1 AND $b\n";
chop_exampl AND e
參考[157]
#!/usr/bin/perl use warnings; use strict; my $example_1 = "chomp_example\n"; my $example_2 = "chomp_example\n"; chomp($example_1); my $b = chomp($example_2); print "$example_1 AND $b\n";
chomp_example AND 1
參考[157]