⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 m2_pointers.hlp

📁 是一个经济学管理应用软件 很难找的 但是经济学学生又必须用到
💻 HLP
📖 第 1 页 / 共 2 页
字号:
{smcl}
{* 25mar2005}{...}
{cmd:help m2 pointers}
{hline}
{* index pointers}{...}
{* index NULL tt}{...}
{* index dereferencing}{...}

{title:Title}

{p 4 4 2}
{hi:[M-2] pointers -- Pointers}


{title:Syntax}

{p 8 12 2}
{cmd:pointer}[{cmd:(}{it:totype}{cmd:)}]
[{it:orgtype}]
[{cmd:function}]
...


{p 4 4 2}
where {it:totype} is 

	[{it:eltype}] [{it:orgtype}] [{cmd:function}] 

{p 4 4 2}
and where {it:eltype} and {it:orgtype} are 

		{it:eltype                   orgtype}
		{hline 17}        {hline 10}{cmd}
		transmorphic             matrix
		numeric                  vector 
		real                     rowvector
		complex                  colvector
		string                   scalar{txt}
		{cmd:pointer}[{cmd:(}{it:towhat}{cmd:)}]        {hline 10}
		{hline 17}


{p 4 4 2}
{cmd:pointer}[{cmd:(}{it:totype}{cmd:)}]
[{it:orgtype}]
can be used in front of declarations, be they function declarations, argument 
declarations, or variable definitions.


{title:Description}

{p 4 4 2}
Pointers are objects that contain the addresses of other objects.
The {cmd:*} prefix operator obtains the contents of an address.
Thus if {it:p} is a pointer, {cmd:*}{it:p} refers to the contents of 
the object to which {it:p} points.
Pointers are an advanced programming concept.  Most programs,
including involved and complicated ones, can be written without them.

{p 4 4 2}
In Mata, pointers are commonly used to

{p 8 12 2}
1.  put a collection of objects under a single name

{p 8 12 2}
2.  pass functions to functions.

{p 4 4 2}
One need not understand everything about pointers merely to pass 
functions to functions; see {bf:{help m2_ftof:[M-2] ftof}}.  


{title:Remarks}

{p 4 4 2}
Remarks are presented under the headings


	{bf:What is a pointer?}
	{bf:Pointers to variables}
	{bf:Pointers to expressions}
	{bf:Pointers to functions}
	{bf:Pointers to pointers}
	{bf:Pointer arrays}
	{bf:Mixed pointer arrays}
	{bf:Definition of NULL}
	{bf:Use of parentheses}
	{bf:Pointer arithmetic}
	{bf:Listing pointers}
	{bf:Declaration of pointers}
	{bf:Use of pointers to collect objects}
	{bf:Efficiency}


{title:What is a pointer?}

{p 4 4 2}
A pointer is the address of a variable or a function.  For instance, say
variable {it:X} contains a matrix.  Another variable {it:p} might contain
137,799,016, and if 137,799,016 were the address at which {it:X} were stored,
then {it:p} would be said to point to {it:X}.  Addresses are seldom written in
base 10, so rather than saying {it:p} contains 137,799,016, we would be
more likely to say that {it:p} contains 0x836a568, which is the way we write
numbers in base 16.  Regardless of how we write addresses, however, {it:p}
contains a number and that number corresponds to the address of another
variable.

{p 4 4 2}
In our program, if we refer to {it:p}, we are referring to {it:p}'s contents,
the number 0x836a568.  The monadic operator {cmd:*} is defined as "refer to the
contents of the address" or "dereference":  {cmd:*}{it:p} means {it:X}.  We
could code {cmd:Y = *p} or {cmd:Y = X}, and either way, we would obtain the
same result.  In our program, we could refer to
{it:X}{cmd:[}{it:i}{cmd:,}{it:j}{cmd:]} or
{cmd:(*}{it:p}{cmd:)[}{it:i}{cmd:,}{it:j}{cmd:]}, and either way, we would
obtain the {it:i}, {it:j} element of {it:X}.

{p 4 4 2}
The monadic operator {cmd:&} is how we put addresses into {it:p}.  To load
{it:p} with the address of {it:X}, we code {it:p} {cmd:=} {cmd:&}{it:X}.

{p 4 4 2}
The special address 0 (zero, written in hexadecimal as 0x0), also known as
{cmd:NULL}, is how we record that a pointer variable points to nothing.  A
pointer variable contains NULL or it contains the address of another
variable.

{p 4 4 2}
Or it contains the address of a function.  Say that {it:p} contains
0x836a568 and that 0x836a568, rather than being the address of matrix {it:X},
is the address of function {it:f}().  To get the address of {it:f}() into
{it:p}, just as we coded {it:p} {cmd:=} {cmd:&}{it:X} previously, we code
{it:p} {cmd:=} {cmd:&}{it:f}{cmd:()}.  The {cmd:()} at the end tells {cmd:&}
that we want the address of a function.  We code {cmd:()} on the 
end regardless of the number of arguments {it:f}() requires because we are 
not executing {it:f}(), we are just obtaining its address.

{p 4 4 2}
To execute the function at 
0x836a568 -- now we will assume that {it:f}() takes two arguments and 
call them {it:i} and {it:j} -- 
we code {cmd:(*}{it:p}{cmd:)(}{it:i}{cmd:,}{it:j}{cmd:)}
just as we coded
{cmd:(*}{it:p}{cmd:)[}{it:i}{cmd:,}{it:j}{cmd:]} 
when {it:p} contained the address of matrix {it:X}.


{title:Pointers to variables}

{p 4 4 2}
To create a pointer {it:p} to a variable, you code

	{it:p} {cmd:=} {cmd:&}{it:varname}

{p 4 4 2}
For instance, if {it:X} is a matrix, 

	{it:p} {cmd:=} {cmd:&}{it:X}

{p 4 4 2}
stores in {it:p} the address of {it:X}.  Subsequently, referring to 
{cmd:*}{it:p} and referring to {it:X} amount to the same thing.  
That is, if {it:X} contained a 3 {it:x} 3 identity matrix and you 
coded 

	{cmd:*}{it:p}{cmd: = Hilbert(4)}

{p 4 4 2}
then after that you would find that {it:X} contained the 4 {it:x} 4 Hilbert
matrix.  {it:X} and {cmd:*}{it:p} are the same matrix.

{p 4 4 2}
If {it:X} contained a 3 {it:x} 3 identity matrix and you coded

	{cmd:(*}{it:p}{cmd:)[2,3] = 4} 

{p 4 4 2}
you would then find {it:X}{cmd:[2,3]} equal to 4.

{p 4 4 2}
You cannot, however, point to the interior of objects.  That is, you cannot
code

	{it:p} {cmd:=} {cmd:&}{it:X}{cmd:[2,3]}

{p 4 4 2}
and get a pointer that is equivalent to {it:X}{cmd:[2,3]} in the 
sense that if you later coded {cmd:*}{it:p}{cmd:=2}, you would see the change
reflected in {it:X}{cmd:[2,3]}.  The statement {it:p} {cmd:=}
{cmd:&}{it:X}{cmd:[2,3]} is valid, but what it does, we will explain in
{bf:Pointers to expressions} below.

{p 4 4 2}
By the way, variables can be sustained by being pointed to.
Consider the program 

	{cmd}pointer(real matrix) scalar example(real scalar n) 
	{
		real matrix	tmp

		tmp = I(3)
		return(&tmp)
	}{txt}

{p 4 4 2}
Ordinarily, variable {cmd:tmp} would be destroyed when {cmd:example()} 
concluded execution.  In this case, however, {cmd:tmp}'s existence 
will be sustained because of the pointer to it.  We might code 

	{it:p}{cmd: = example(3)}

{p 4 4 2}
and the result will be to create {cmd:*}{it:p} containing the 3 {it:x} 3
identity matrix.  The memory consumed by that matrix will be freed when 
it is no longer being pointed to, which will occur when {it:p} itself 
is freed, or, before that, when the value of {it:p} is changed, perhaps by

	{it:p} {cmd:= NULL}


{title:Pointers to expressions}

{p 4 4 2}
You can code 

	{it:p} {cmd:= &(2+3)}

{p 4 4 2}
and the result will be to create {cmd:*}{it:p} containing 5.  
Mata creates a temporary variable to contain the evaluation of the 
expression and sets {it:p} to the address of the temporary variable.
That temporary variable will be freed when {it:p} is freed or, before 
that, when the value of {it:p} is changed, just as {cmd:tmp} was 
freed in the example in the previous section.

{p 4 4 2}
When you code 

	{it:p} {cmd:=} {cmd:&}{it:X}{cmd:[2,3]}

{p 4 4 2}
the result is the same.  The expression is evaluated and the result of the
expression stored in a temporary variable.  That is why subsequently coding
{cmd:*}{it:p}{cmd:=2} does not change {it:X}{cmd:[2,3]}.  All
{cmd:*}{it:p}{cmd:=2} does is change the value of the temporary variable.

{p 4 4 2}
Setting pointers equal to the value of expressions can be useful.
In the following code fragment, we create {it:n} 5 {it:x} 5 matrices
for later use:

	{cmd}pvec = J(1, n, NULL)
	for (i=1; i<=n; i++) pvec[i] = &(J(5, 5, .)){txt}


{title:Pointers to functions}

{p 4 4 2}
When you code 

	{it:p} {cmd:= &}{it:functionname}{cmd:()}

{p 4 4 2}
the address of the function is stored in {it:p}.  You can later execute 
the function by coding 

	... {cmd:(*}{it:p}{cmd:)(}...{cmd:)}

{p 4 4 2}
Distinguish carefully between 

	{it:p} {cmd:= &}{it:functionname}{cmd:()}

{p 4 4 2}
and 

	{it:p} {cmd:= &(}{it:functionname}{cmd:())}

{p 4 4 2}
The latter would execute {it:functionname}() with no arguments and then 
assign the returned result to a temporary variable.

{p 4 4 2}
For instance, assume that you wish to write a function {cmd:neat()} that will
calculate the derivative of another function, which function you will pass to
{cmd:neat()}.  Your function, we will pretend, returns a real scalar.

{p 4 4 2}
You could do that as follows

	{cmd:real scalar neat(pointer(function) p,} {it:other args}...{cmd:)}
	{cmd:{c -(}}
		...
	{cmd:{c )-}}

{p 4 4 2}
although you could be more explicit as to the characteristics of the 
function you are passed:

	{cmd:real scalar neat(pointer(real scalar function) p,} {it:other args}...{cmd:)}
	{cmd:{c -(}}
		...
	{cmd:{c )-}}

{p 4 4 2}
In any case, inside the body of your function, where you want to call 
the passed function, you code 

		{cmd:(*p)(}{it:arguments}{cmd:)}

{p 4 4 2}
For instance, you might code 

		{cmd:approx = ( (*p)(x+delta)-(*p)(x) ) / delta}

{p 4 4 2}
The caller of your {cmd:neat()} function, wanting to use it with, say, 
function {cmd:zeta_i_just_wrote()}, would code

		{it:result} {cmd:= neat(&zeta_i_just_wrote(),} {it:other args}...{cmd:)}


{title:Pointers to pointers}

{p 4 4 2}
Pointers to pointers (to pointers ...) are allowed, for instance, 
if {it:X} is a matrix

	{it:p1}{cmd: = &X}
	{it:p2}{cmd: = &p1}

{p 4 4 2}
In this case, {cmd:*}{it:p2} is equivalent to {it:p1}, and 
{cmd:**}{it:p2} is equivalent to {it:X}.

{p 4 4 2}
Similarly, we can construct a pointer to a pointer to a function:

	{it:q1}{cmd: = &}{it:f}{cmd:()}
	{it:q2}{cmd: = &p1}

{p 4 4 2}
In this case, {cmd:*}{it:q2} is equivalent to {it:q1}, and 
{cmd:**}{it:q2} is equivalent to {it:f}().
	
{p 4 4 2}
When constructing pointers to pointers, never type {cmd:&&} -- such as
{cmd:&&}{it:x} -- to obtain the address of the address of {it:x}.  Type
{cmd:&(&}{it:x}{cmd:)} or {cmd:& &}{it:x}.  {cmd:&&} is a synonym for {cmd:&},
included for those used to coding in C.


{title:Pointer arrays}

{p 4 4 2}
You may create an array of pointers, such as 

	{it:P}{cmd: = (&}{it:X1}{cmd:, &}{it:X2}{cmd:, &}{it:X3}{cmd:)}

{p 4 4 2}
or

	{it:Q}{cmd: = (&}{it:f1}{cmd:(), &}{it:f2}{cmd:(), &}{it:f3}{cmd:())}

{p 4 4 2}
In this case, 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -