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

📄 m2_pointers.hlp

📁 是一个经济学管理应用软件 很难找的 但是经济学学生又必须用到
💻 HLP
📖 第 1 页 / 共 2 页
字号:
{cmd:*}{it:P}{cmd:[2]} is equivalent to {it:X2} and 
{cmd:*}{it:Q}{cmd:[2]} is equivalent to {it:f2}().


{title:Mixed pointer arrays}

{p 4 4 2}
You may create mixed pointer arrays, such as 

	{it:R}{cmd: = (&}{it:X}{cmd:, &}{it:f}{cmd:())}

{p 4 4 2}
In this case, 
{cmd:*}{it:R}{cmd:[2]} is equivalent to {it:f}().

{p 4 4 2}
You may not, however, create arrays of pointers mixed with real, complex,
or string elements.  Mata will abort with a type-mismatch error.


{title:Definition of NULL}

{p 4 4 2}
{cmd:NULL} is the special pointer value that means "points to nothing" or 
undefined.  {cmd:NULL} is like 0 in many ways -- for instance, coding 
{cmd:if (X)} is equivalent to coding {cmd:if (X!=NULL)}, but {cmd:NULL}
is distinct from zero in other ways.  0 is a numeric value; {cmd:NULL} is 
a pointer value.


{title:Use of parentheses}

{p 4 4 2}
Use parentheses to make your meaning clear.  

{p 4 4 2}
In the table below, we assume 

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

	{it:P} {cmd:= (&}{it:X11}{cmd:, &}{it:X12}{cmd: \ &}{it:X21}{cmd:, &}{it:X22}{cmd:)}

	{it:q} {cmd:= &}{it:f}{cmd:()}

	{it:Q} {cmd:= (&}{it:f11}{cmd:(), &}{it:f12}{cmd:() \ &}{it:f21}{cmd:(), &}{it:f22}{cmd:())}

{p 4 4 2}
where 
{it:X}, 
{it:X11}, 
{it:X12}, 
{it:X21}, and
{it:X22} 
are matrices and 
{it:f}(), 
{it:f11}(), 
{it:f12}(), 
{it:f21}(), and
{it:f22}() 
are functions.


	Expression        meaning
	{hline 64}
	{cmd:*}{it:p}                {it:X}
	{cmd:*}{it:p}{cmd:[1,1]}           {it:X}
	{cmd:(*}{it:p}{cmd:)[1,1]}         {it:X}{cmd:[1,1]}

	{cmd:*}{it:P}{cmd:[1,2]}           {it:X12}
	{cmd:(*}{it:P}{cmd:[1,2])[3,4]}    {it:X12}{cmd:[3,4]}

	{cmd:*}{it:q}{cmd:(a,b)}           execute function {it:q}{cmd:()} of {cmd:a}, {cmd:b}; dereference that
	{cmd:(*}{it:q}{cmd:)(a,b)}         {it:f}{cmd:(}{it:a}{cmd:,}{it:b}{cmd:)}
	{cmd:(*}{it:q}{cmd:[1,1])(a,b)}    {it:f}{cmd:(}{it:a}{cmd:,}{it:b}{cmd:)}

	{cmd:*}{it:Q}{cmd:[1,2](a,b)}      nonsense
	{cmd:(*}{it:Q}{cmd:[1,2])(a,b)}    {it:f12}{cmd:(}{it:a}{cmd:,}{it:b}{cmd:)}
	{hline 64}


{title:Pointer arithmetic}

{p 4 4 2}
Arithmetic with pointers (which is to say, with addresses) is not allowed:

	: {cmd:y = 2}
	: {cmd:x = &y}
	: {cmd:x+2}
                  {err:<stmt>:  3205  undefined operation on pointer}

{p 4 4 2}
Do not confuse the expression {cmd:x+2} with the expression {cmd:*x+2}, which
is allowed and in fact evaluates to 4.

{p 4 4 2}
You may use the equality and inequality operators {cmd:==} and {cmd:!=} with
pairs of pointer values:

	{cmd}if (p1 == p2) {c -(} 
		...
	{c )-}

	if (p1 != p2) {c -(}
		...
	{c )-}{txt}

{p 4 4 2}
In addition, pointer values may be assigned and compared with the value
{cmd:NULL}, which is a lot like, but different from, zero:  {cmd:NULL} is a 1
{it:x} 1 scalar containing an address value of 0.  An unassigned pointer has
the value {cmd:NULL}, and you may assign the value {cmd:NULL} to pointers:

	{cmd:p = NULL}

{p 4 4 2}
Pointer values may be compared with {cmd:NULL}, 

	{cmd}if (p1 == NULL) {c -(} 
		...
	{c )-}

	if (p1 != NULL) {c -(}
		...
	{c )-}{txt}

{p 4 4 2}
but if you attempt to dereference a {cmd:NULL} pointer, you will get an error:

	: {cmd:x = NULL}
	: {cmd:*x + 2}
                  {err:<stmt>:  3120  attempt to dereference NULL pointer}

{p 4 4 2}
Concerning logical expressions, you may directly examine pointer values:

	{cmd}if (p1) {c -(} 
		...
	{c )-}{txt}

{p 4 4 2}
The above is interpreted as if {cmd:if (p1!=NULL)} were coded.


{title:Listing pointers}

{p 4 4 2}
You may list pointers:

	: {cmd:y = 2}
	: {cmd:x = &y}
	: {cmd:x}
	  {cmd:0x8359e80}

{p 4 4 2}
What is shown, 0x8359e80, is the memory address of {cmd:y} during our 
Stata session.  If you typed the above lines, the address you would see could
differ, but that does not matter.

{p 4 4 2}
Listing the value of pointers often helps in debugging because, by comparing
addresses, you can determine where pointers are pointing and whether some 
are pointing to the same thing.

{p 4 4 2}
In listings, {cmd:NULL} is presented as 0x0.


{title:Declaration of pointers}

{p 4 4 2}
Declaration of pointers, as with all declarations (see 
{bf:help m2_declarations:[M-2] declarations}})
is optional.  That basic syntax is 

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

{p 4 4 2}
For instance, 

	{cmd:pointer(real matrix) scalar} {it:p1}

{p 4 4 2}
declares that {it:p1} is a pointer scalar and that it points to a 
real matrix, and     

	{cmd:pointer(complex colvector) rowvector} {it:p2}

{p 4 4 2}
declares that {it:p2} is a row vector of pointers and that each 
individual pointer points to a complex colvector, and

	{cmd:pointer(real scalar function) scalar} {it:p3}

{p 4 4 2}
declares that {it:p3} is a pointer scalar and that it points to a 
function that returns a real scalar, and 

	{cmd:pointer(pointer(real matrix function) rowvector) colvector} {it:p4}

{p 4 4 2}
declares that {it:p4} is a column vector of pointers to pointers, the pointers
to which each element points are row vectors, and each of those elements 
point to a function returning a real matrix.

{p 4 4 2}
You can omit the pieces you wish.

	{cmd:pointer() scalar} {it:p5}

{p 4 4 2}
declares that {it:p5} is a pointer scalar -- to what being uncertain.

	{cmd:pointer scalar} {it:p5}

{p 4 4 2}
means the same thing.

	{cmd:pointer} {it:p6}

{p 4 4 2}
declares that {it:p6} is a pointer, but whether it is a matrix, vector, or 
scalar, is unsaid.


{title:Use of pointers to collect objects}

{p 4 4 2}
Assume that you wish to write a function in two parts:  {cmd:result_setup()} and
{cmd:repeated_result()}.

{p 4 4 2}
In the first part, {cmd:result_setup()}, you will be passed a matrix and a
function by the user, and you will make a private calculation that you will
use later, each time {cmd:repeated_result()} is called.
When {cmd:repeated_result()} is called, you will need to know the matrix, 
the function, and the value of the private calculation that you previously
made.

{p 4 4 2}
One solution is to adopt the follow design.  You request the user code

	{cmd:resultinfo = result_setup(}{it:setup args}...{cmd:)}

{p 4 4 2}
on the first call, and 

	{it:value} {cmd:= repeated_result(resultinfo,} {it:other args}...{cmd:)}

{p 4 4 2}
on subsequent calls.  The design is that you will pass the information between
the two functions in {cmd:resultinfo}.  
In this case, {cmd:resultinfo} will need to contain three things:  the
original matrix, the original function, and the private result you
calculated.  The user, however, never need know the details, and you will
simply request that the user declare {cmd:resultinfo} as a pointer vector.

{p 4 4 2}
Filling in the details, you code

	{cmd}pointer vector result_setup(real matrix X, pointer(function) f)
	{c -(}
		real matrix     privmat
		pointer vector  info

		...
		privmat = ...
		...
		info = (&X, f, &privmat)
		return(info)
	{c )-}

	real matrix repeated_result(pointer vector info, ...)
	{c -(}
		pointer(function) scalar   f
		pointer(matrix)   scalar   X
		pointer(matrix)   scalar   privmat

		f = info[2]
		X = info[1]
		privmat = info[3]
		
		... 
		... (*f)(...) ...
		... (*X) ...
		... (*privmat) ...
		...
	{c )-}{txt}

{p 4 4 2}
In point of fact, it was not necessary to unload {cmd:info[]} into the 
individual scalars.  The lines using the passed values could just as well 
have read

		... {cmd:(*info[2])(}...{cmd:)} ...
		... {cmd:(*info[1])} ...
		... {cmd:(*info[3])} ...


{title:Efficiency}

{p 4 4 2}
When calling subroutines, it is better to pass the evaluation of pointer
scalar arguments rather than the pointer scaler itself, because then the
subroutine can run a little faster.  For instance, say {cmd:p} points to 
a real matrix.  It is better to code 

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

{p 4 4 2}
rather than 

		... {cmd:mysub(p)} ...

{p 4 4 2}
and then to write {cmd:mysub()} as 

	{cmd:function mysub(real matrix X)}
	{cmd:{c -(}}
		... {cmd:X} ...
	{cmd:{c )-}}

{p 4 4 2}
rather than 

	{cmd:function mysub(pointer(real matrix) scalar p)}
	{cmd:{c -(}}
		... {cmd:(*p)} ...
	{cmd:{c )-}}

{p 4 4 2}
Dereferencing a pointer (obtaining {cmd:*}{it:p} from {it:p}) does not 
take long, but it does take time.
Passing {cmd:*}{it:p} rather than {it:p} can be important if 
{cmd:mysub()} loops and performs the evaluation of {cmd:*}{it:p} 
hundreds of thousands or millions of times.


{title:Diagnostics}

{p 4 4 2}
The prefix operator {cmd:*} 
(called the dereferencing operator) aborts with error if it is applied to a
nonpointer object.

{p 4 4 2}
Arithmetic may not be performed on undereferenced pointers.  Arithmetic 
operators abort with error.

{p 4 4 2}
The prefix operator {cmd:&} aborts with error if it is applied to a
built-in function.


{title:Also see}

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

{p 4 13 2}
Online:  help for 
{bf:{help m2_intro:[M-2] intro}}
{p_end}

⌨️ 快捷键说明

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