Page 1 of 1

[NXC] How to keep a variable "alive" in a subroutine

Posted: 20 Dec 2011, 20:20
by dodgey
Hi - I'm revisiting an old project and I'm still stumped on the same problem....

I have a string variable in a subroutine. Lets call it "x".

This subroutine calls another subroutine , on occasions, and that "called" subroutine needs to use the string "x" value from it's parent routine.

I thought I had sussed global variables, but I was wrong. Is there a simple way to pass variables on to subroutines so they can use them?

I believe it's in the definition of routines, in the parenthesese, but I don't understand the syntax. When I tried I got random errors on compiling in locations that made no sense, as if I'd removed a } somewhere.

I get "too many arguments" whatever I seem to do on the calling line. e.g. examplesubroutineCall(testvar); as soon as I add the testvar I get the too many arguments error.

Example

Void Test(

Re: [NXC] How to keep a variable "alive" in a subroutine

Posted: 20 Dec 2011, 20:49
by mattallen37
Perhaps you should try Google. You will find many examples.

Re: [NXC] How to keep a variable "alive" in a subroutine

Posted: 20 Dec 2011, 23:52
by muntoo
Is this what you mean?

Code: Select all

void bar(string x)
{

}

void foo(string x)
{
    bar(x);
}

task main()
{
    foo("abc");
}
Could we see your code?

Re: [NXC] How to keep a variable "alive" in a subroutine

Posted: 21 Dec 2011, 10:15
by dodgey
Indeed - though I want to pass on a variable from within the main routine rather than a fixed string value...

I've put "///FORUM COMMENT" by the important bit - I want to use the value of the string "token" in the second subroutine (threre is also a fair bit of textout debugging to ignore)

Code: Select all

sub ReceiveSolution(){
   string buffer = " ";
   string orient = "RBD";
   string token;
   string globalch;
   short i;
   ClearScreen();
   TextOut(0,LCD_LINE2,"waiting solution");
   until(StrLen(buffer)>2) {
      until(ReceiveMessage(PC_INBOX, true, buffer) == NO_ERR);
   }

   token = SubStr(buffer,0,2);
   nActions = StrToNum(token);
   ClearScreen();

   for (i = 0; i<nActions; i++) {
      token = SubStr(buffer,(3+2*i),1);

TextOut(5,LCD_LINE2, "token");
TextOut(5,LCD_LINE3, token);
WaitButton(BTNCENTER);

      solution[i] = StringToActionCode(token);
      //TextOut(0,LCD_LINE1-8*i,token);
      // THIS IS WHERE I INSERT THE MAIN ROUTINE READING "token"

        globalch = token;
TextOut(5,LCD_LINE2, "globalchIS");
TextOut(5,LCD_LINE3, globalch);
WaitButton(BTNCENTER);

        if ((token == "U")||(token == "u")||(token == "1"))
        {
TextOut(5,LCD_LINE3,"Uu1");
WaitButton(BTNCENTER);

           if (orient == "FUR")  {
           RotateUpFace();               ///////FORUM COMMENT
           orient = "FUR";  }
           else if (orient == "RUB") {
           RotateUpFace();

Code: Select all

void RotateUpFace()
{
TextOut(5,LCD_LINE2,"Rotate UoFace");
WaitButton(BTNCENTER);

     LiftUpTopRow();
     if(isdigit(token))
        {
        Rotate180CW();         }
        else if(isupper(token))
        {
        Rotate90CW();          }
        else if(islower(token))
        {
        Rotate90CCW();         }
     Wait(100);
     LiftReset();
     SpinnerReset();
}
I've tried replacing (from the main SR)
RotateUpFace();
with
RotateUpFace(token);

and
void RotateUpFace()
with
void RotateUpFace(string token)

I get errors on both. I've tried using a new string name on the "receiving end" too - no change.

Re: [NXC] How to keep a variable "alive" in a subroutine

Posted: 21 Dec 2011, 15:18
by dodgey
By the way, I looked at a lot of the Google results and they are 99% referring to integers. I looked into passing strings and I'm still a littel confused - it seems you have to convert to char and call the location of the char . I tried a few examples I saw and still get missing parameters or too many arguments.

Re: [NXC] How to keep a variable "alive" in a subroutine

Posted: 21 Dec 2011, 16:15
by HaWe
no, you don't have to convert it.
But ANSI C handles strings in a different way compared to nxC.
Standard ANSi C doesn't have a datatype "string", in standard C strings are arrays of char

Code: Select all

char mystring[] ;
//or
char *mystring ;
The reason for this is that this is what strings exactly actually are. ;)

in nxC you may use strings just like int or float or anything.
Just have a close look at muntoo's samples.

If you want to pass a value to a procedure where the procedure must not change the original value of the string, you have to declare the procedure this way:

Code: Select all

void myStringProc(string mystring) // pass by value
{
  // do anything with the string internally called "mystring"
} 
if it changes mystring internally, it will only change an internal copy of the original string.

if the procedure should be able to change the original value of the string, you have to declare the procedure this way:

Code: Select all

void myStringProc(string & mystring)  // pass by reference
{
  // do anything with the string  internally called "mystring"
} 
(notice the "&" between the datatype and the name of the string).
if it changes mystring internally, it will change also the original string.


Notice also that "pass by reference" is also not standard C (it's more like C++), standard C does it in a different way (via pointers), but the nxC way is more easy for beginners - so don't get confused reading about ANSi C =)

Anyway, in both cases you call your Procedure this way:

Code: Select all

string test;
test="Helmut";
myStringProc(test);
All other local variables in procedures are re-initialized at every single call (in general, except you declare them as "static" - not sure if this is also an issue to you).

Finally, I would recommend not to use the keyword "sub".
"sub" is an old obsolete relict and it's actually anything but C.
you should use "void" instead.

Re: [NXC] How to keep a variable "alive" in a subroutine

Posted: 21 Dec 2011, 18:43
by dodgey
Thanks for the comprehensive reply. I understand now.

Now time for major debugging (the price I am paying for using someone else's code that I'm modifying)

When I change

sub ReceiveSolution()

to

sub ReceiveSolution(string token)

it accepts is, but then takes me to a "break;" at the very bottom of the program (out of this routine , but the routine that calls the above initially - it's a switching menu ) and complaints that "break;" is too few parameters. Oh the fun.

Thanks again