byGary Roberts| Updated: 03/23/2017 | Comments: 2
Pointers are a great tool for CRBasic programs. If you use them carefully, pointers can reduce the amount of program code you need to write, thereby increasing your program’s efficiency and enabling you to use less memory. (Your program can run faster because it does not have to duplicate the data in memory).
要学习如何使用指针,首先谈论变量及其存储方式将很有帮助。变量存储在数据记录器内存中的内存单元中。数据记录器的内存由连续的内存单元组成,一个字节长,每个字节都有一个唯一的地址。为了更好地了解数据记录器如何使用其内存,我将使用下面的类比,当我们开始谈论指针时,这应该有所帮助。
Imagine that the data logger’s memory is a large warehouse that can store lots of things inside it. In our example, we are going to fill our warehouse with buckets of different sizes and types. (Depending on our needs, we may fill the entire warehouse or only a portion of it.) All the buckets we use hold things of one type or another. Larger buckets are used to hold larger things, and smaller buckets are used for smaller things. The number and size of buckets used, as well as the amount of space used in the warehouse, depend on you as the programmer and the needs of the project you are working on.
当我们开始编写CRBASIC程序时,我们会声明变量。在我们的仓库场景中,当我们声明一个变量时,我们将在数据记录器仓库中创建一个存储桶(使用内存单元格),以保存我们想要使用的信息(变量)。该存储桶只能容纳某些类型的变量。例如,一个小桶容纳一个浮点变量,并占据了数据记录器的免费仓库(内存)空间的大约4个字节。另一个小桶有一个布尔变量,它还占用了仓库中4个字节的地板空间。然后,我们添加一个容纳一个字符串变量的大型存储桶,该变量占据了24个字节的仓库空间。
有了一个装满水桶的仓库,我们怎么知道哪个水桶拥有我们想要的信息?幸运的是,我们有能力将有意义的名字命名为有助于描述其持有的信息。例如,我们可以给这个名字temperatureto a bucket that holds a float variable by declaring our float variable astemperature。As we continue to add and declare variables, the data logger’s warehouse (memory) starts filling up.
If our warehouse is getting full, how do we easily find the bucket we need? Fortunately, the data logger’s processor is a fantastic warehouse manager. It knows where every bucket is stored. Each bucket has a specific, unique address with an aisle, section, and shelf within the data logger’s warehouse. (No two buckets share the same address.) The warehouse manager can use the unique address to quickly find the bucket in the warehouse. When we come to the warehouse wanting the bucket holding the float variable we namedtemperature, the data logger efficiently decodes the address and gets the right bucket (data logger memory cells) we are looking for and the information (variable) it contains. We can then read or change what is inside thetemperature桶(例如,temperature= 32.14)。
Now here is where pointers come into play. Pointers are a way for us to help our warehouse manager (the data logger’s processor) be even more effective at its job and be a better steward of the limited warehouse space (memory).
A pointer is a variable whose value is the address of another variable. Just like any variable or constant, you must declare a pointer before you can work with it. When you declare a pointer in CRBasic, it needs to be declared as a typeLong:
Public my_pointer As Long
这条代码线称为指针声明或指针变量。指针变量存储我们要指出的另一个变量的地址。
To use or initialize the new pointer, we then need to tell CRBasic to point it at a specific piece of memory that is tied to thetemperature多变的。为此,我们可以使用以下语法:
my_pointer= @temperature
The memory (warehouse) address oftemperatureis now stored in the pointer variablemy_pointer。The@symbol is known as the address-of operator. It is a unary operator that returns the memory address of its operand. Using the example above,my_pointer现在等于地址temperature。
现在,这使我们能够在CRBASIC计划中做几件事。例如:
public my_pointer长达公共麦克(tom),汤姆(Tom)长时间,梅利莎(Melissa),long my_pointer = @mike mike = 42 tom = Mikemelissa = my_pointer
在这个简短的CRBASIC程序中,以下内容是正确的:
如果我们想要变量melissa包含与mike(and not mike’s memory address), we need to use the pointer dereference or indirection operator!如下所示:
public my_pointer长达公共麦克(tom),汤姆(Tom)长时间,梅利莎(Melissa),long my_pointer = @mike mike = 42 tom = Mikemelissa = !my_pointer
Nowmelissa等于42- 与mikeand汤姆。
好吧,这是整洁的,但这不是一个容易的设置melissaequal tomike? Most of the time, yes. There are times when a pointer is handier, but that’s a more advanced topic.
Now to put pointers into action.
In the“6步骤轻松地解析数据从一个可信的源头e” blog article, I shared with you how to parse XML from other sources using a CRBasic data logger. Now I am going to show you how we can use pointers to improve and shorten the program, as well as save precious data logger memory.
在早期的博客文章,我共享的程序with you looked for and read one variable from the XML file. To get more information from the returned XML, we are going to have to add more如果statements to get the information we need (such as humidity):
如果xml_response_code = xml_end_of_element和XML_ELEMENT_NAME =“ ferver_humity”,那么noaa_releative_humity = xml_value endif
要从XML文件中获取所有数据,我们将添加34个附加如果statements to get it all parsed. Now, using pointers, we can get the work done in a single如果statement!
If xml_response_code = XML_END_OF_ELEMENT Then pointer = 0 pointer = @(xml_element_name)If(pointer > 0) Then !pointer = xml_value万一
我们所做的是声明我们想要使用与XML文件中元素相同的名称中存储信息的变量。通过这样做,我们利用数据记录仪中的指针,使我们的编程更加紧凑和精确。
使用指针,我们的程序像以前一样下载XML,并开始使用XMLParse()instruction. When it gets to the end of an element name, we start into our如果statement. The first line in that如果statement sets the pointer to memory address0。This is just good programming practice, as the data logger will never return a reference to a variable at address0。这有助于我们(以及数据记录器)知道下一行代码中的解除是否有效或失败。
The next line sets the pointer to the address-of operator (@) for the variable with the same name as is stored in the variablexml_element_name。The parentheses around the variable namexml_element_name告诉数据记录仪不要查看地址xml_element_name, but to look at what is stored inxml_element_name。例如,当xml_element_name = “relative_humidity”the variable pointer points to the memory address of the variable namedrelative_humidityand not toxml_element_name。That is why our variable names must be named the same as the elements in the XML file we are parsing.
The last line in the statement says that if the pointer is not pointing to memory address zero, pour the information inxml_value在指向指向的地址的变量中。使用我们以前的示例,存储在xml_value将被倾倒到变量relative_humidity。
Aren’t pointers handy?
I have included a working example of a program usingXMLParse()和指针。只是download the CRBasic programinto your data logger (ensuring the data logger has an active Internet connection), run it, and watch the program update using pointers.
I hope this information was helpful to you. If you have any questions, please post them below.
Comments
凯利|02/16/2018 at 04:56 AM
这是帮助文件中的几行。
"
可以在表达式中访问指针:
!(指针 + x)
将访问Pointer + X的值。
"
so, using this call:
UnpackArray(PkAryVal, @UnPack(),12)
为什么这项工作:
Sub UnpackArray(Val As Long, AryPtr As Long, Elements As Long)
DIM参考长期
Dim x As Long
For x = 0 To Elements - 1
Ref = AryPtr + x
!Ref = (Val >> x AND 1)
Next x
EndSub
but not this:
Sub UnpackArray(Val As Long, AryPtr As Long, Elements As Long)
Dim x As Long
For x = 0 To Elements - 1
!(aryptr + x)=(val >> x和1)
Next x
EndSub
Testing on CR6 os 6.08
感谢您在这个问题上可以忽略的任何灯光
crs|04/07/2018在03:51 PM
我希望看到更多有关在CRBASIC中使用指针的博客文章 /教程。
I am trying to write a function that can accept any type of variable (or array) and perform some operation on it (e.g., using TypeOf() and SprintF()), but not having any luck recognizing the original variable within my function. How does the following, from the CRBasic help file, apply?
By default, pointer variables are of type Long, but they can be typed using Float!, Long!, Boolean!, or String! (e.g., Dim P as Float!). If pointers are not typed, the summation of the values pointed to truncates the floats before the addition.
Also, how would I handle an array within the function? Does the pointer offset have to be scaled for each successive array element by the size of that element?
Pleaselog in or registerto comment.