目录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]