Reference/pointers in the 12th chapter PERL5
by Flamephoenix
I. INTRODUCTION of citation
Ii. use of references
Third, use the backslash (\) operator
Iv. References and Arrays
V. Multidimensional arrays
Vi. references to sub-programs
Sub-Program templates
Vii. Arrays and subroutines
Viii. references to file handles
I. INTRODUCTION of citation
A reference is a pointer, which can point to a variable, an array, a hash table (also called an associative array), or even a subroutine. A Pascal or C programmer should be familiar with the concept of a reference (that is, a pointer), where the reference is the address of a value, and its use depends on the programmer's and language's requirements. In Perl, references can be referred to as pointers, which are generic and non-discriminatory. References are useful for creating complex data.
The two types of references in PERL5 are hard references and symbolic references. The symbolic reference contains the name of the variable, which is useful for creating variable names and positioning at run time, and basically, symbolic references are like filenames or soft links in Unix systems. Hard references are like hard links in the file system.
Perl4 only allows symbolic references, which creates some difficulties for use. For example, it is only allowed to index the symbolic name hash table (named _main{}) of the package by name. PERL5 allows hard references to data for more convenience.
The count of hard reference tracking references, when the number is zero, Perl automatically releases the referenced item, and if the item is an object, the destruction is released into the memory pool. Perl itself is an object-oriented language, because everything in Perl is an object, and packages and modules make objects easier to use.
A hard reference to a simple variable is simple, and for a reference to a non-simple variable, you must explicitly dereference and tell it what to do, as described in Chapter Perl, Object-oriented programming.
Ii. use of references
In this chapter, simple variables refer to variables like $pointer, $pointer contain only one data item, which can be numeric, string, or address.
Any simple variable can hold a hard reference. Because arrays and hash tables contain multiple simple variables, multiple complex data structures can be constructed, such as array of arrays, arrays of hash tables, hash tables of subroutines, and so on. As long as you understand that you are only working with simple variables, you should be able to correctly dereference in the most complex structure.
First look at some basic points.
If the value of $pointer is a pointer to an array, the elements in the array are accessed through the form @ $pointer. The meaning of the form @ $pointer is "Remove the address value from the $pointer as an array." Similarly, the% $pointer is a reference to the first element in the hash table.
There are several ways to build references that can be used to make references to almost any data, such as arrays, simple variables, subroutines, file handles, and references that--C programmers will be interested in. Perl gives you the ability to write extremely complex code that confuses yourself. :)
Here's a look at the methods used to create and use references in Perl.
Third, use the backslash (\) operator
The backslash operator is similar to the operator & function for passing addresses in the C language. It is generally a new reference to create a variable with \. The following is an example of a reference to creating a simple variable:
$variavle = 22;
$pointer = \ $variable;
$ice = "Jello";
$iceprt = \ $ice;
Reference $pointer points to the location where the $variable value is stored, and the reference $iceptr points to "jello". Even if the original reference $variable is destroyed, the value can still be accessed through $pointer, which is a hard reference, so both $pointer and $variable must be destroyed so that the space is freed into the memory pool.
In the above example, the reference variable $pointer the address of the $variable, not the value itself, to get the value, in the form of two $ symbols, as follows:
#!/usr/bin/perl
$value = 10;
$pointer = \ $value;
printf "\ Pointer Address $pointer of $value \ n";
printf "\ Pointer * ($pointer) points to $ $pointer \ n";
The resulting output is as follows:
Pointer Address SCALAR (0x806c520) of 10
What Pointer * (SCALAR (0x806c520)) points
to
At each run, the address in the output will change, but you can see that $pointer gives the address, and $ $pointer gives the value of $variable.
Look at the display of the address, the scalar followed by a string of hexadecimal, scalar indicates that the address points to a simple variable (that is, scalar), the following number is the actual storage value of the address.
Note: The pointer is the address, and the data stored at that address can be accessed by pointers. If the pointer points to an invalid address, it gets incorrect data. Typically, Perl returns a null value, but should not rely on it, be sure to initialize all pointers correctly in the program, pointing to valid data items.
Iv. References and Arrays
Perhaps the most important thing to remember about the Perl language is that arrays and hash tables in Perl are always one-dimensional. Therefore, arrays and hash tables only hold scalar values, not directly storing arrays or other complex data structures. The members of an array are either numbers (or strings) or references.
Arrays and hash tables can use the backslash operator just like a simple variable, and the array is referenced as follows:
1 #!/usr/bin/perl
2 #
3 # Using Array references
4 #
5 $pointer = \ @ARGV;
6 printf "\ Pointer Address of ARGV = $pointer \ n";
7 $i = scalar (@ $pointer);
8 printf "\ n number of arguments: $i \ n";
9 $i = 0;
(@ $pointer) {
printf "$i: $ $pointer [$i + +]; \ n ";
--}
The results of the operation are as follows:
$ Test 1 2 3 4
Pointer Address of ARGV = ARRAY (0x806c378)
Number of Arguments:4
0:1;
1:2;
2:3;
3:4; The 5th row references $pointer to the array @argv, and the 6th line outputs the address of the ARGV. $pointer returns the address of the first element of the array, which is similar to the array pointer in the C language. The 7th line calls the function scalar () to get the number of elements of the array, which can also be @argv, but with a pointer you must specify its type as an array in the form of @ $pointer, $pointer give the address, and the @ symbol indicates the address of the first element of the group passed. Line 10th is similar to line 7th, and the 11th line lists all elements in the form $ $pointer [$i].
Using the backslash operator for associative arrays is the same--replace all associative array names with reference $poniter. Note that arrays and simple variable (scalar) references are displayed with type--array and scalar, hash tables (associative arrays) and functions, respectively, hash and code. The following is an example of a hash table reference.
#!/usr/bin/perl
1 #
2 # Using Associative Array references
3 #
4%month = (
5 ' A ', ' Jan ',
6 ' A ', ' Feb ',
7 ' in ', ' Mar ',
8 ', ' APR ',
9 ' to ', ' may ',
' June ',
One ' ', ' Jul ',
' A ', ' an ', '
' In ', ' Sep ',
"Ten", ' Oct ',
' One ', ' Nov ',
"A", "Dec",
17);
18
$pointer = \%month;
20
printf "\ Address of hash = $pointer \ n";
22
23 #
The following lines would is used to print out the
# contents of the associative array if%month was used.
26 #
# foreach $i (sort keys%month) {
# printf "\ n $i $ $pointer {$i}";
29 #}
30
31 #
The reference to the associative array via $pointer
33 #
foreach $i (sort keys% $pointer) {
printf "$i is $ $pointer {$i} \ n";
36}
The resulting output is as follows:
$ mth
Address of hash = hash (0x806c52c)
The IS Jan
Is Feb
Geneva is Mar
Is APR
are May
is June
Is Jul
Geneva
Is Sep
Is OCT
One is Nov
Dec
Like an array, the element that accesses the hash table by reference is $ $pointer {$index}, of course, $index is the key value of the hash table, not just the number. There are several forms of access, in addition, a hash table can be built with the = = operator for better readability. Let's look at an example below:
1 #!/usr/bin/perl
2 #
3 # Using Array references
4 #
5%weekday = (
6 ' + ' Mon ',
7 ' Tue ',
8 ' Wed ',
9 ' ' Thu ',
' Fri ',
One ' ' and ' Sat ',
"+" "Sun",
13);
$pointer = \%weekday;
$i = ' 05 ';
printf "\ ================== start test ================= \ n";
17 #
# These next lines should show an output
19 #
printf ' $ $pointer {$i} is ';
printf "$ $pointer {$i} \ n";
printf ' ${$pointer} {$i} is ';
printf "${$pointer} {$i} \ n";
printf ' $pointer->{$i} is ';
25
-printf "$pointer->{$i}\n";
27 #
These next lines should not show anything 29 #
printf ' ${$pointer {$i}} is ';
printf "${$pointer {$i}} \ n";
printf ' ${$pointer->{$i}} is ';
printf "${$pointer->{$i}}";
"\ ================== end of test ================= \ n";
35
The resulting output is as follows:
================== start Test =================
$ $pointer {$i} is Fri
${$pointer} {$i} is Fri
$pointer->{$i} is Fri
${$pointer {$i}} is
${$pointer->{$i}} is
================== end of Test =================
As you can see, the first three forms of output show the expected results, and the latter two do not. When you don't know if you're right, output the results and see. In Perl, an ambiguous code is used to experiment with the output of the print statement, which allows you to understand how Perl interprets your code.
V. Multidimensional arrays
Statement @array = list; You can create a reference to an array, in parentheses you can create a reference to an anonymous array. The following statement is an example of a three-dimensional array for drawing:
$line = [' Solid ', ' black ', [' 1 ', ' 2 ', ' 3 '], [' 4 ', ' 5 ', ' 6 '];
This statement establishes a three-dimensional array with four elements, and the variable $line points to the array. The first two elements are scalar, the type and color of the storage lines, the latter two are references to anonymous arrays, and the starting and ending points of the storage lines. The syntax for accessing its elements is as follows:
$arrayReference->[$index] single-dimensional array
$arrayReference->[$index 1][$index 2] two-dimensional array
$arrayReference->[$index 1][$index 2][$index 3] Three-dimensional array
You can create extremely complex structures with your intellect, design experience, and the memory of your computer allowed, but it's best to be friendly to people who might read or manage your code-try to make the code easier. On the other hand, if you want to show off your programming skills to others, Perl gives you the opportunity and the ability to write code that will inevitably confuse you. :)
Recommendation: When you want to use more than three-dimensional arrays, it is best to consider using other data structures to simplify the code.
Here's an example of creating and using a two-dimensional array:
1 #!/usr/bin/perl
2 #
3 # Using Multi-dimensional Array references
4 #
5 $line = [' Solid ', ' black ', [' 1 ', ' 2 ', ' 3 '], [' 4 ', ' 5 ', ' 6 '];
6 print "\ $line->[0] = $line->[0] \ n";
7 print "\ $line->[1] = $line->[1] \ n";
8 print "\ $line->[2][0] = $line->[2][0] \ n";
9 print "\ $line->[2][1] = $line->[2][1] \ n";
print "\ $line->[2][2] = $line->[2][2] \ n";
print "\ $line->[3][0] = $line->[3][0] \ n";
print "\ $line->[3][1] = $line->[3][1] \ n";
print "\ $line->[3][2] = $line->[3][2] \ n";
print "\ n"; # The obligatory output beautifier.
The resulting output is as follows:
$line->[0] = solid
$line->[1] = Black
$line->[2][0] = 1
$line->[2][1] = 2
$line->[2][2] = 3
$line->[3][0] = 4
$line->[3][1] = 5
$line->[3][2] = 6
So what about three-dimensional arrays? The following is a slightly modified version of the previous example.
1 #!/usr/bin/perl
2 #
3 # Using multi-dimensional Array references again
4 #
5 $line = [' Solid ', ' black ', [' 1 ', ' 2 ', ' 3 ', [' 4 ', ' 5 ', ' 6 ']];
6 print "\ $line->[0] = $line->[0] \ n";
7 print "\ $line->[1] = $line->[1] \ n";
8 print "\ $line->[2][0] = $line->[2][0] \ n";
9 print "\ $line->[2][1] = $line->[2][1] \ n";
print "\ $line->[2][2] = $line->[2][2] \ n";
print "\ $line->[2][3][0] = $line->[2][3][0] \ n";
print "\ $line->[2][3][1] = $line->[2][3][1] \ n";
print "\ $line->[2][3][2] = $line->[2][3][2] \ n";
print "\ n";
The resulting output is as follows:
$line->[0] = solid
$line->[1] = Black
$line->[2][0] = 1
$line->[2][1] = 2
$line->[2][2] = 3
$line->[2][3][0] = 4
$line->[2][3][1] = 5
$line->[2][3][2] = 6
Access to the third layer element is shaped like $line->[2][3][0], similar to the array_pointer[2][3][0 in C language]. In this case, the subscript is a number, and of course it can be replaced by a variable. In this way, arrays and hash tables can be combined to form complex structures, as follows:
1 #!/usr/bin/perl
2 #
3 # Using multi-dimensional Array and Hash references
4 #
5%cube = (
6 ' 0 ', [' 0 ', ' 0 ', ' 0 '],
7 ' 1 ', [' 0 ', ' 0 ', ' 1 '],
8 ' 2 ', [' 0 ', ' 1 ', ' 0 '],
9 ' 3 ', [' 0 ', ' 1 ', ' 1 '],
10 ' 4 ', [' 1 ', ' 0 ', ' 0 '],
11 ' 5 ', [' 1 ', ' 0 ', ' 1 '],
12 ' 6 ', [' 1 ', ' 1 ', ' 0 '],
13 ' 7 ', [' 1 ', ' 1 ', ' 1 ']
14);
$pointer = \%cube;
print "\ n Da Cube \ n";
+ foreach $i (sort keys% $pointer) {
$list = $ $pointer {$i};
$x = $list->[0];
$y = $list->[1];
$z = $list->[2];
printf "point $i = $x, $y, $z \ n";
(+}
The resulting output is as follows:
Da Cube
Point 0 = 0,0,0
Point 1 = 0,0,1
Point 2 = 0,1,0
Point 3 = 0,1,1
Point 4 = 1,0,0
Point 5 = 1,0,1
Point 6 = 1,1,0
Point 7 = 1,1,1
This is an example of defining a cube. The%cube is a dot and a coordinate, which is an array of three numbers. Variable $list gets a reference to an array of coordinates: $list = $$ pointer{$i}; Then access each coordinate value: $x = $list->[0]; ... You can also assign values to $x, $y, and $z as follows: ($x, $y, $z) = @ $list;
when using hash tables and arrays, the following two statements are equivalent in the case of an array:
$ $names [0] = " Kamran ";
$names->[0] = "Kamran";
The following two statements are equivalent to a hash table:
$ $lastnames {"Kamran"} = "Husain";
$lastnames->{"Kamran"} = "Husain"; The arrays in the
perl can be created and extended in the run. The array is created automatically when the reference to the array first appears to the left of the equation, as are the simple variables and multidimensional arrays. The following sentence, if the array contours does not exist, is created:
$contours [$x] [$y] [$z] = &xlate ($mouseX, $mouseY);
Vi. references to subroutines
perl a subroutine similar to a pointer to a function in C, constructed as follows:
$pointer _to_sub = Sub {... declaration of sub ...};
calls the subroutine through the constructed reference:
& $pointer _to_sub (parameters);
The return value of a subroutine is not limited to data, but it can also return a reference to a subroutine. The returned subroutine is executed at the call, but is set at the point at which it was originally created, as determined by the way Perl handles closure. Closure means that if you define a function, it runs with the content that was originally defined. (Closure see the reference book for OOP) The following example sets up multiple error messages to display subroutines, such subroutine definition methods can be used to create templates.
#!/usr/bin/perl
Sub ErrorMsg {
my $lvl = shift;
#
# define the subroutine to run when called.
#
Return SUB {
my $msg = shift; # Define the error type now.
Print "ERR level $lvl: $msg \ n"; }; # Print later.
}
$severe = errormsg ("severe");
$fatal = errormsg ("fatal");
$annoy = errormsg ("annoying");
& $severe ("Divide by Zero");
& $fatal ("Did you forget-use a semi-colon?");
& $annoy ("Uninitialized variable in use");
The resulting output is as follows:
ERR level severe:divide by zero
ERR level Fatal:did Do forget to use a semi-colon?
ERR level annoying:uninitialized variable inch
use
In the above example, the subroutine errormsg uses the local variable $LVL, which is used to return to the caller. When ErrorMsg is called, the value of the $LVL is set to the returned subroutine content, although it is used by the My function. Three calls set three different values for the $LVL variable. When ErrorMsg returns, the value of the $LVL is saved to the subroutine code that is generated each time it is declared. The last three sentences are replaced with the value of $msg when the resulting subroutine reference is called, but the value of $LVL is still the value of the corresponding subroutine code when it is created.
It's confusing, isn't it? Yes, so this kind of code is rare in Perl programs.
Vii. Arrays and subroutines
Arrays facilitate the management of related data, this section discusses how to pass multiple arrays to a subroutine. Before we talked about using @_ to pass the parameters of the subroutine, but @_ is a single-dimensional array, regardless of the number of parameters you pass the group, are stored sequentially in the @_, so with the shape of my (@a,@b) [email protected]_; Statement to get the parameter value, all values are assigned to @a, and @b is empty. So how do you pass more than one array to the subroutine? method is to use a reference. See the following example:
#!/usr/bin/perl
@names = (Mickey, Goofy, Daffy);
@phones = (5551234, 5554321, 666);
$i = 0;
Sub Listem {
My ($a, $b) = @_;
foreach (@ $a) {
Print "a[$i] =". @ $a [$i]. " " . " \tb[$i] = ". @ $b [$i]. " \ n ";
$i + +;
}
}
&listem (\ @names, \ @phones);
The resulting output is as follows:
A[0] = Mickey b[0] = 5551234a[1] = Goofy b[1] = 5554321a[2] = Daffy b[2] = 666
Attention:
1. Be sure to use a reference when you want to pass an array with more than one parameter to the subroutine.
2, must not use in the Sub-program form (@variable) [email protected]_; Statement processing parameters, unless you want to centralize all the parameters into a long array.
Viii. references to file handles
Sometimes, the same information must be output to a different file, for example, a program may output to the screen in one instance, another output to the printer, then one output to the record file, and even output to these three files simultaneously. Compared to each processing to write a separate statement, there can be a better way to implement the following:
Spitout (\*stdin);
Spitout (\*lphandle);
Spitout (\*loghandle);
Where the subroutine Spitout code is as follows:
Sub Spitout {
my $fh = shift;
Print $fh "Gee Wilbur, I like this lettuce\n";
}
Note that the syntax for the file handle reference is \*filehandle.
Previous chapter Next Chapter catalogue
PERL5 references/pointers in the 12th chapter PERL5