18.01.2012, 17:17
Quote:
int make_a_zero(int *var)
{
*var = 0;
return 0;
}
main()
{
int hey = 1212;
make_a_zero(&hey);
}
Pointers are a type of variable that points to another variable. With that, we can save alot of memory and make our job way easier like:
pawn Код:
|
stock make_a_zero(&var)
{
var = 0;
return 0;
}
main()
{
new hey = 1212;
make_a_zero(hey);
}
There's a fairly major bug in this version. Currently you're doing "idx = idx + 1 & max;" to get the next index to store in. A very common use case is to set up a load of permanent resources (in this case pointers) at the start of the mode (which would result in them being at the start of the array), and then assign and release more temporary pointers as the mode goes. With your current code this will destroy the initial pointers after a while, but I have no idea for a solution (and I suspect you knew this already so I'm not sure why I'm posting).
|
new
g_Test[] = {123, 456, 789}
;
public OnGameModeInit() {
new pointer = GetVariableAddress(g_Test);
// Change the 2nd value
@[pointer][1] = 444;
// Print out the values
printf("%d, %d, %d", @[pointer][0], @[pointer][1], @[pointer][2]);
}
// Simple assignment
test[2][5] = 123;
// This does the same thing as the line above
// In fact, this is exactly what the PAWN compiler generates
#emit ADDR.pri test
#emit ADD.C 8
#emit MOVE.alt
#emit LOAD.I
#emit ADD
#emit ADD.C 20
#emit MOVE.alt
#emit CONST.pri 123
#emit STOR.I
new array[100][100];
main() {
new address = GetVariableAddress(array);
// WRONG:
@ptr[address][5][10] = 20;
// CORRECT (new):
@ptr[address, 5, 10] = 20;
// Also CORRECT:
@ptr[address, 5][10] = 20;
}
new variable = 200;
new Pointer:ptr = PointerToVar(variable);
ptr = 123;
printf("%d", variable);
// Output: 123
// Operator called when an untagged variable is assigned to a value tagged with Pointer
stock Pointer:operator=(value) {
static addr;
// Get return address
#emit LOAD.S.alt 4
// Add COD
#emit LCTRL 0
#emit ADD
#emit MOVE.alt
// Subtract DAT
#emit LCTRL 1
#emit SUB.alt
// Read the first opcode's parameter
#emit ADD.C 4
#emit STOR.pri addr
#emit LREF.pri addr
#emit STOR.pri addr
// Is this address relative to the previous frame?
if (addr <= 0) {
// Add the previous frame to make it absolute
#emit LOAD.S.pri 0
#emit LOAD.alt addr
#emit ADD
// Load it and store it
#emit LOAD.I
#emit STOR.pri addr
} else {
// Load it and store it
#emit LOAD.pri addr
#emit LOAD.I
#emit STOR.pri addr
}
// Store the new value there
if (addr) {
#emit LOAD.S.pri value
#emit LOAD.alt addr
#emit STOR.I
}
// Add 8 to the return address (to skip the assignment)
#emit LOAD.S.pri 4
#emit ADD.C 8
#emit STOR.S.pri 4
// Return the same value the pointer was
return Pointer:0;
}
stock Pointer:PointerToVar(...) {
#emit LOAD.S.pri 12
#emit RETN
return Pointer:0;
}
Sorry for bump, but have any possible to get the tag of variable, or argument by similar of this? using emit maybe...
Really sorry for bump, but nice include ^^ |
stock SomeFunc({ _, Float, hex}:var, tag = tagof(var))
{
if (tag == tagof(Float:)) {
// "var" is a float
}
}
SomeFunc(playerid, GLOBAL_TAG_TYPES:...)
{
if(tagof(@arg[1]) == tagof(Float:)){ // 0x43
}
}
#define SomeFunc(%0,%1) _SomeFunc(%0,tagof(%1),%1)
_SomeFunc(playerid, tag, GLOBAL_TAG_TYPES:...)
{
if(tagof(tag) == tagof(Float:)){ // 0x43
}
}
Sorry for bump, but have any possible to get the tag of variable, or argument by similar of this? using emit maybe...
Really sorry for bump, but nice include ^^ |