Hi. I’m trying to learn Go. I first wrote this code on Modula-2, and then in C++, and now in Go.
I’m getting an unusual output for the first grouping of print statements. Whenever I printf AnEntryPointer, I get all zeros in the output. When I follow the link lists forwards and backwards, I get a long number for the value of the pointer fields. I think this number is too long to be a pointer.
What am I missing?
Thanks.
/*
REVISION HISTORY
----------------
3/12/15 From modula2.org tutorial. This section deals with dynamic memory usage. I will change it around so I better understand it.
And I've made it a double linked list.
3/13/15 Will add output of the pointers so I can compare this with the prev and next field contents. And I changed the name
of variable AnEntry to AnEntryPointer.
3/15/15 Converting to C++, and changing more names to be clearer that they are pointers.
3/18/15 Removed the char cast to see if it still works. It does.
3/18/15 Made AdrToHexStr also a function.
6/7/16 Converted to Go
*/
package main
import (
"fmt"
// "strings"
// "unsafe"
);
type FullName struct {
PrevP *FullName;
NextP *FullName;
FirstName string;
Initial byte;
LastName string;
}; // struct FullName
var(
StartOfListP,EndofListP,CurrentPlaceInListP,PrevPlaceInListP,AnEntryPointer *FullName;
I int;
s,s0 string;
)
/******************************************************************************************************/
/*
func AdrToHexStr(adr unsafe.Pointer) (OutStr1,OutStr2 string) {
const ASCZERO = '0'; // int
const ascA = 'A'; // int
var h int;
var OutInt [16]int;
Str20 := ""; // receives the hex characters, one by one, in reverse
OutStr2 = " "; // 16 spaces to be filled in reverse
i := 0;
for j := 0; j < 16; j++ {
OutInt[j] = ' ';
}
L := int(uintptr(adr));
for { // until L = 0
h = L % 16; // % is MOD op
if h <= 9 {
Str20 += string(h + ASCZERO);
OutInt[i] = h + ASCZERO;
}else{
Str20 += string(h -10 + ascA);
OutInt[i] = h -10 + ascA;
}; // h <= 9
i++;
L = L / 16;
if L == 0 { break };
} // until L = 0
OutStr1 = " ";
j := 0;
for { // until i = 0
i--;
OutStr1[j] = Str20[i];
j++;
if i == 0 { break };
}
OutStr2 = string(OutInt);
OutStr2 = strings.Trim(OutStr2," ");
return;
} // AdrToHexStr This entire function can be replaced by a call to Sprintf, but nevermind that
*/
/**************************************************************************************************/
func main() {
StartOfListP = nil;
EndofListP = nil;
CurrentPlaceInListP = nil;
PrevPlaceInListP = nil;
/* Generate the first name in the list */
AnEntryPointer = new(FullName);
StartOfListP = AnEntryPointer;
fmt.Print(" 1: ");
// s0,s = AdrToHexStr(AnEntryPointer);
fmt.Printf("First pointer value %x, %#v\n",AnEntryPointer,AnEntryPointer);
AnEntryPointer.PrevP = nil; // do I need to dereference all of these?
AnEntryPointer.FirstName = "John "; // or is this covered by "syntactic sugar"?
AnEntryPointer.Initial = 'Q'; // Seems it is covered by "syntactic sugar"
AnEntryPointer.LastName = " Doe"; // The explicit dereferences are not needed.
AnEntryPointer.NextP = nil;
/* Generate 2nd name in the list */
PrevPlaceInListP = AnEntryPointer;
AnEntryPointer = new(FullName);
fmt.Print(" 2: ");
// s,s0 = AdrToHexStr(AnEntryPointer);
fmt.Printf("%x, %#V\n",AnEntryPointer,AnEntryPointer);
CurrentPlaceInListP = AnEntryPointer;
(*PrevPlaceInListP).NextP = CurrentPlaceInListP; // This explicit dereference is not needed
(*CurrentPlaceInListP).PrevP = PrevPlaceInListP;
(*CurrentPlaceInListP).FirstName = "Mary ";
(*CurrentPlaceInListP).Initial = 'R';
(*CurrentPlaceInListP).LastName = " Johnson";
(*CurrentPlaceInListP).NextP = nil;
/* Add 10 more names to complete the list */
for I=1; I<=10; I++ {
PrevPlaceInListP = CurrentPlaceInListP;
AnEntryPointer = new(FullName);
fmt.Print(I+2,":");
// s,s0 = AdrToHexStr(AnEntryPointer);
fmt.Printf("%x,%#v\n",AnEntryPointer,AnEntryPointer);
if (I % 3) == 0 { fmt.Println() }
CurrentPlaceInListP = AnEntryPointer;
PrevPlaceInListP.NextP = CurrentPlaceInListP;
CurrentPlaceInListP.PrevP = PrevPlaceInListP;
CurrentPlaceInListP.FirstName = "Billy ";
CurrentPlaceInListP.Initial = byte(I+64); // 65 is cap A
CurrentPlaceInListP.LastName = " Franklin";
CurrentPlaceInListP.NextP = nil;
}; /* FOR I */
EndofListP = CurrentPlaceInListP;
fmt.Println();
fmt.Println();
/* Display the list on the monitor in forward direction */
fmt.Println(" List in forward direction.");
CurrentPlaceInListP = StartOfListP;
for {
if CurrentPlaceInListP == nil { break };
// s,s0 = AdrToHexStr(CurrentPlaceInListP.PrevP);
fmt.Printf("%x: ",CurrentPlaceInListP.PrevP);
fmt.Printf("%s %c %s: ",CurrentPlaceInListP.FirstName,CurrentPlaceInListP.Initial,CurrentPlaceInListP.LastName)
// s,s0 = AdrToHexStr(CurrentPlaceInListP.NextP);
fmt.Printf("%x\n",CurrentPlaceInListP.NextP);
PrevPlaceInListP = CurrentPlaceInListP;
CurrentPlaceInListP = CurrentPlaceInListP.NextP;
}
/* Display the list on the monitor in reverse direction */
fmt.Println();
fmt.Println(" List in reverse direction. ");
CurrentPlaceInListP = EndofListP;
for {
if CurrentPlaceInListP == nil {break}
// _,s0 = AdrToHexStr(CurrentPlaceInListP.PrevP);
fmt.Printf("%x: ",CurrentPlaceInListP.PrevP);
fmt.Printf("%s %c %s: ",CurrentPlaceInListP.FirstName,CurrentPlaceInListP.Initial,CurrentPlaceInListP.LastName)
// s,_ = AdrToHexStr(CurrentPlaceInListP.NextP);
fmt.Printf("%x\n",CurrentPlaceInListP.NextP);
PrevPlaceInListP = CurrentPlaceInListP;
CurrentPlaceInListP = CurrentPlaceInListP.PrevP;
}
/* Deallocate is unnecessary in Go */
} // LinkList