簡體   English   中英

如何在C中轉到String的值?

[英]How can I goto the value of a String in C?

我正在用C語言編寫一個機器人,我遇到了一個我似乎無法弄清楚的問題。

解決這個問題的唯一方法是使用很多goto語句。 我試圖找出一種方法來節省自己寫100多個goto點和語句和if語句等,並且我想知道是否有一種方法來轉換字符串的值。 例如-

string Next = "beginning";
goto Next;
beginning:

有沒有辦法goto Next的值,或者將Next的值替換為goto語句?

如果有一種方法可以做到這一點,那么我就可以只改變的值Next每個驅動命令,然后goto任何字符串的值Next是。

換句話說,只需將字符串轉換為goto標識符,或用它代替一個。

謝謝您的幫助!

-編輯-

很多人都在建議使用switch語句。 我不確定這會起作用,因為我如何編程。 程序的結構就在這里 - 順便說一下,這段代碼只包含了我實際擁有的一些內容,到目前為止我的實際代碼超過了500行。 此外,主要簡化了驅動命令。 但基本概念在這里,比我想要的更容易理解。

task main()
{
  //integer list
  int forwardDrivingSelector = 0;
  int backwardDrivingSelector = 0;
  int rightRotatingSelector = 0;
  string nextCommand;
  int waitTime = 0;
  int countup = 0;

  //driving commands

  driveForward:
  while(forwardDrivingSelector == 1)
  {
    motor[leftMotor] = 127;
    motor[rightMotor] = 127;
    countup++;
    wait1Msec(1);
    if(countup == waitTime)
    {
      countup = 0;
      goto nextCommand;
    }
  }
  driveBackward:
  while(backwardDrivingSelector == 1)
  {
    motor[leftMotor] = -127;
    motor[rightMotor] = 127;
    countup++;
    wait1Msec(1);
    if(countup == waitTime)
    {
      countup = 0;
      goto nextCommand;
    }
  }
  rightRotate:
  while(rightRotatingSelector == 1)
  {
    motor[leftMotor] = 127;
    motor[rightMotor] = -127;
    countup++;
    wait1Msec(1);
    if(countup == waitTime)
    {
      countup = 0;
      goto nextCommand;
    }
  }

  //autonomous driving code

  //first command, drive forward for 1000 milliseconds
  forwardDrivingSelector = 1;
  nextCommand = "secondCommand";
  waitTime = 1000;
  goto driveForward;

  secondCommand:
  forwardDrivingSelector = 0;

  //second command, rotate right for 600 milliseconds
  rightRotatingSelector = 1;
  nextCommand = "thirdCommand";
  waitTime = 600;
  goto rightRotate;

  thirdCommand:
  rightRotatingSelector = 0;

  //third command, drive backwards for 750 milliseconds
  backwardDrivingSelector = 1;
  nextCommand = "end";
  waitTime = 750;
  goto driveBackward;

  end:
  backwardDrivingSelector = 0;

}

所以。 這是如何工作的。 我有一個整數列表,包括驅動命令選擇器,countup和waitTime整數,以及我正在談論的字符串,nextCommand。 接下來是駕駛指令。 在我的真實代碼中,我有大約30個命令,它們都連接到一個遙控器,它的400多行僅用於驅動命令。 接下來是自治代碼。 我這樣設置它的原因是自動代碼部分簡短,簡單,重點突出。 幾乎要向驅動代碼添加一個命令,你打開選擇器,告訴nextCommand字符串下一個命令是什么,設置waitTime(這是命令執行的時間,以毫秒為單位),然后你使代碼轉到你輸入的駕駛命令。駕駛命令驅動你輸入的時間,然后轉到nextCommand;

如果有一種方法可以使goto語句“解釋”字符串作為標識符,那么這在理論上都可以工作,因此可以對其進行更改。

我現在可以想到的有四種簡單的方法可以很容易地解決這個問題,但是它們會使代碼真的很長而且雜亂無章。

現在你對我的問題有了更好的理解,還有更多的輸入? :)

順便說一句 - 我正在使用一個名為robotC的程序,我正在編寫一個vex機器人。 所以我必須使用普通,基本,C,我不能使用任何插件或任何東西......這是另一個原因,這是復雜的,因為我不能有多個類和類似的東西......

作為C語言的擴展,GCC提供了一個名為computed gotos的功能,允許您goto在運行時計算的標簽。 但是, 我強烈建議您重新考慮您的設計

而不是使用帶有超過一百個標簽的gotos (這很容易導致不可維護的意大利面條代碼),而是考慮使用函數指針。 代碼將更加結構化和可維護。

而不是goto,我會調用100個函數之一。 雖然C不會為你處理從字符串到函數的轉換,但是使用排序的結構數組很容易:

struct fn {
    char name[whatever];
    void (*func)(void);
};

然后(例如)通過數組進行二進制搜索以找到與字符串匹配的函數。

另請注意,許多真實系統提供諸如GetProcAddress (Windows)或dlsym (Unix / Linux)之類的東西來為您處理一些工作。

你正在考慮這個錯誤的方法。 您需要調用的每個操作都應該是一個函數,然后您可以通過檢查“next”變量來選擇下一個應該調用的函數。

這可能是您提到的字符串,但您可能最好使用枚舉類型來生成可讀但更有效的代碼。

替代方法雖然可能過度,但可以確保您的函數都使用相同的參數和返回類型,然后使用函數指針來跟蹤下一個應該執行的代碼段。

小提示:如果您認為自己需要超過1個goto語句才能實現某個目標,那么您可能不會考慮最佳解決方案。

您需要退一步考慮其他解決方案,以解決您要解決的問題。 其中一個可能看起來像這樣:

void DoSomething() {
    printf("Something\n");
}

void DoSomethingElse() {
    printf("Something else\n");
}

void (*nextStep)(void) = NULL;

nextStep = DoSomething;
nextStep();
nextStep = DoSomethingElse;
nextStep();

看到它在行動

首先,讓我通過與其他所有人達成一致來形容這一點:這可能不是你正在嘗試做什么的正確方法。 特別是,我認為你可能想要一個有限狀態機,我推薦這篇文章來指導如何做到這一點。

那就是說。 您可以使用switch語句或多或少地執行此switch 例如:

Next = BEGINNING;
HelperLabel:
switch(Next)
{
   case BEGINNING:
     .
     .
     .
     Next = CONTINUING;
     goto HelperLabel;
   case ENDING:
     .
     .
     .
     break;
   case CONTINUING:
     .
     .
     .
     Next = ENDING;
     goto HelperLabel;
}

(請注意, switch語句需要整數或類似整數的值而不是字符串,但您可以使用enum以直接的方式創建這些整數。)

有關將switch / case用作goto的原始典型示例,請參見http://en.wikipedia.org/wiki/Duff's_device

switch怎么樣? 要么使用int / enum / whatever,要么檢查字符串的值(例如循環它和strcmp )以找出目的地。

const char *dsts[n_dsts] = {"beginning","middle",...};
...
int i;
for(i = 0; i < n_dsts; i++) if(strcmp(dsts[i]) == 0) break;
switch(i) {
    case 0: // whatever
    case 1: // whatever
    ...
        break;
    default: // Error, dest not found
}
#define GOTO_HELPER(str, label) \
    if (strcmp(str, #label) == 0) goto label;

#define GOTO(str) do { \
    GOTO_HELPER(str, beginning) \
    GOTO_HELPER(str, end) \
    } while (0)


int main (int argc, char ** argv) {
    GOTO("end");
beginning:
    return 1;
end:
    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM