符號引用 typeglob,別名 與全域性變數的修改

2022-05-08 11:57:12 字數 2904 閱讀 9033

不能以為在子函式裡修改了乙個和全域性變數同名的變數就會修改全域性變數:

#!/usr/bin/perl

$glov = "hello";

change;

print $glov;

sub change

雖然在子程式 change 裡的 $glov 變數和全域性變數 $glov 名字相同,但兩個並不是同乙個變數,子程式裡的變數為區域性變數。

在子程式裡修改全域性變數的一種方法是利用「符號引用」。

符號引用類似與 linux 裡的軟連線概念,它又稱為別名。建立乙個變數的別名的方法是在實際變數的前面加上乙個"*"符號。星號("*") 適用於任意型別的變數,包括標量,陣列,雜湊,檔案控制代碼,子函式等。

別名是符號表中針對同名識別符號的另乙個名稱,比如 *name 可以表示 $name, @name 以及 %name, &name 等。

當通過別名按引用傳遞方式將別名傳遞到函式中時,需要用 local 函式宣告乙個私有變數用以接收傳遞進來的別名,該私有變數也就是另外乙個別名,然後修改該私有變數也就等效於修改了傳遞進來的全域性變數。如下程式所示:

#!/usr/bin/perl

$glov = "hello";

&change(*glov);

print $glov, "\n";

sub change

執行輸出:

$ ./changeglobv.pl

hello

world

上面,不能用 my 來宣告這個私有變數,因為 my 函式所建立的變數名稱並不儲存在符號表中,而是位於臨時緩衝區中。由於 typeglob 僅能關聯到特定的符號表上,因此 my 不能對它進行私有化,所以要讓 typeglob 本地化就必須使用 local 函式。

測試**2

#!/usr/bin/perl

$colors = "rainbow";

@colors = ("red", "green", "yellow");

&printit(*colors);         #傳遞進 colors 陣列的別名

sub printit

執行輸出:

$ ./alias.pl

*main::colors             #告知 *whichone 是 main 中 colors 的別名

out of subroutine.

$colors is hello world.

@colors is blue green yellow.

測試**3

#!/usr/bin/perl

@n = split(' ', );

¶ms(*n);

sub params

}print "back in main\n";

print "the new values are @n.\n";

執行輸出:

$ ./alias2.pl

1 2 3 4 5       #輸入命令列引數

the values of the @arr array are 12345

the first value is 1

the last value is 5

the value is 6.

the value is 7.

the value is 8.

the value is 9.

back in main

the new values are 6 7 8 9.

測試**4

該例子演示通過引用傳遞檔案控制代碼。如果要直接把檔案控制代碼傳遞給子函式,唯一的途徑就是通過引用(注意,還有個硬引用,這裡不涉及)。

#!/usr/bin/perl

open (hd, ")

}

在上面,別名可以同時匹配多種型別。如果你只想匹配特定的一種,那麼此時需要用反斜槓運算子,perl 的引用機制允許對某類特定變數而不是所有變數型別使用別名,如:

*array = \@array;   # *array只引用陣列

*scalar = \$scalar;    # *saclar 只引用變數

*hash = \%assoc_array;    # *hash 只引用雜湊表

*func = \&subroutine;   # *func 只引用子函式

測試**5

#!/usr/bin/perl

@list = (1, 2, 3, 4, 5);

*arr = \@list;  #*arr 此時只對 @list 陣列引用

print @arr, "\n";

print "$arr\n";         #arr 已經只能引用陣列而不能引用普通變數,這裡內容為空

sub alias

&alias(*arr);

print "@list\n";

$num = 5;

*alnum = \$num; # scalar 只引用變數而不能引用陣列

print "@alnum\n";

執行輸出:

$ ./chalias.pl

12345

7 2 3 4

弱符號與強符號,弱引用與強引用

對c c 而言,編譯器預設函式和初始化了的全域性變數為強符號。未初始化的全域性變數為弱符號。此處弱符號與強符號均是針對定義來說的,不是針對符號的引用。也可以通過gcc的 attribute weak 來定義任何乙個強符號為弱符號。cpp view plain copy extern in ext i...

bash 命令列 歷史命令 命令別名 引用符號

bash 一些用法 shell 子shell bash 1.命令歷史 命令不全 2.管道 重定向 3.命令別名 4.命令列編輯 5.命令名展開 6.檔名通配 7.變數 8.程式設計,指令碼游標跳 ctrl a 跳到命令列首 ctrl e 跳到命令行尾 ctrl u 刪除游標至命令列首的內容 ctrl...

C 之引用與符號「 」

一 的意思 1.取位址符,這時候它用於資料的前面,比如int a b 2.c 裡還使用 作為引用符,如果你確認程式是標準的c而非c 的話,那麼可以排除是引用了。引用也用於資料前面,它只在定義和宣告時使用,如int othername name int a b 定義時使用在等號左側,是引用。相當於a是...