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

Discussion specific to NXT-G, NXC, NBC, RobotC, Lejos, and more.
Post Reply
dodgey
Posts: 19
Joined: 17 Sep 2011, 23:27

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

Post 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(
mattallen37
Posts: 1818
Joined: 02 Oct 2010, 02:19
Location: Michigan USA
Contact:

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

Post by mattallen37 »

Perhaps you should try Google. You will find many examples.
Matt
http://mattallen37.wordpress.com/

I'm all for gun control... that's why I use both hands when shooting ;)
muntoo
Posts: 834
Joined: 01 Oct 2010, 02:54
Location: Your Worst Nightmare
Contact:

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

Post 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?
Image

Commit to LEGO Mindstorms Robotics Stack Exchange:
bit.ly/MindstormsSE


Commit to LEGO Stack Exchange: bit.ly/Area51LEGOcommit
dodgey
Posts: 19
Joined: 17 Sep 2011, 23:27

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

Post 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.
dodgey
Posts: 19
Joined: 17 Sep 2011, 23:27

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

Post 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.
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

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

Post 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.
dodgey
Posts: 19
Joined: 17 Sep 2011, 23:27

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

Post 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
Post Reply

Who is online

Users browsing this forum: No registered users and 24 guests