ส่งคืนสตริง C จากฟังก์ชัน


109

ฉันพยายามส่งคืนสตริง C จากฟังก์ชัน แต่ไม่ได้ผล นี่คือรหัสของฉัน

char myFunction()
{
    return "My String";
}

ในmainฉันเรียกมันเช่นนี้:

int main()
{
  printf("%s", myFunction());
}

ฉันได้ลองใช้วิธีอื่นบ้างmyFunctionแล้ว แต่ไม่ได้ผล ตัวอย่างเช่น:

char myFunction()
{
  char array[] = "my string";
  return array;
}

หมายเหตุ: ฉันไม่ได้รับอนุญาตให้ใช้พอยน์เตอร์!

พื้นหลังเล็กน้อยเกี่ยวกับปัญหานี้:

มีฟังก์ชั่นที่ค้นหาว่าเป็นเดือนไหน ตัวอย่างเช่นถ้าเป็น 1 ก็จะส่งกลับเดือนมกราคมเป็นต้น

พอจะพิมพ์ก็ทำแบบนี้: printf("Month: %s",calculateMonth(month));. ตอนนี้ปัญหาคือวิธีส่งคืนสตริงนั้นจากcalculateMonthฟังก์ชัน


10
น่าเสียดายที่คุณต้องการคำแนะนำในกรณีนี้
Nick Bedford

1
@Hayato อืมฉันเชื่อว่าเราเป็นผู้ใหญ่ที่นี่และรู้ว่ามันควรจะกลับ 0 มันเป็นเพียงเพื่อประโยชน์ในการยกตัวอย่าง lox ..
itsaboutcode

3
return 0โดยนัยโดยปริยายเฉพาะใน C99 (และ C ++) แต่ไม่ใช่ใน C90
ชม

1
จากนั้นคุณจะไม่สามารถทำได้ข้างแฮ็กใบ้ซึ่งเป็นเพียงการปรับแต่งตัวชี้ที่พังทลายลงไป ตัวชี้มีอยู่ด้วยเหตุผล ... : |
GManNickG

คำตอบ:


223

ลายเซ็นฟังก์ชันของคุณต้องเป็น:

const char * myFunction()
{
    return "My String";
}

พื้นหลัง:

เป็นพื้นฐานสำหรับ C & C ++ แต่ควรมีการอภิปรายเพิ่มเติมเล็กน้อย

ใน C (& C ++ สำหรับเรื่องนั้น) สตริงเป็นเพียงอาร์เรย์ของไบต์ที่สิ้นสุดด้วยศูนย์ไบต์ดังนั้นคำว่า "string-zero" จึงถูกใช้เพื่อแสดงถึงรสชาติเฉพาะของสตริงนี้ มีสตริงประเภทอื่น ๆ แต่ในภาษา C (& C ++) รสชาตินี้เข้าใจโดยเนื้อแท้ของภาษา ภาษาอื่น ๆ (Java, Pascal ฯลฯ ) ใช้วิธีการที่แตกต่างกันเพื่อทำความเข้าใจ "สตริงของฉัน"

หากคุณเคยใช้ Windows API (ซึ่งอยู่ใน C ++) คุณจะเห็นพารามิเตอร์การทำงานที่ค่อนข้างสม่ำเสมอเช่น: "LPCSTR lpszName" ส่วน 'sz' แสดงถึงแนวคิดของ 'string-zero': อาร์เรย์ของไบต์ที่มีตัวยุติเป็น null (/ ศูนย์)

ชี้แจง:

เพื่อประโยชน์ของ 'คำนำ' นี้ฉันใช้คำว่า 'ไบต์' และ 'อักขระ' แทนกันได้เพราะมันง่ายกว่าที่จะเรียนรู้ด้วยวิธีนี้ โปรดทราบว่ามีวิธีการอื่น ๆ (ระบบอักขระแบบกว้างและอักขระหลายไบต์ ( mbcs )) ที่ใช้ในการจัดการกับอักขระสากล UTF-8เป็นตัวอย่างของ mbcs เพื่อประโยชน์ในการแนะนำฉัน 'ข้าม' ทั้งหมดนี้ไปอย่างเงียบ ๆ

หน่วยความจำ:

ซึ่งหมายความว่าสตริงอย่าง "my string" ใช้ไบต์ 9 + 1 (= 10!) นี่เป็นสิ่งสำคัญที่ต้องรู้ว่าเมื่อใดที่คุณจะจัดสรรสตริงแบบไดนามิกได้ในที่สุด

ดังนั้นหากไม่มี "การยกเลิกศูนย์" นี้คุณจะไม่มีสตริง คุณมีอาร์เรย์ของอักขระ (หรือที่เรียกว่าบัฟเฟอร์) อยู่รอบ ๆ ในหน่วยความจำ

อายุการใช้งานของข้อมูล:

การใช้ฟังก์ชันด้วยวิธีนี้:

const char * myFunction()
{
    return "My String";
}

int main()
{
    const char* szSomeString = myFunction(); // Fraught with problems
    printf("%s", szSomeString);
}

... โดยทั่วไปจะนำคุณไปสู่ข้อผิดพลาดที่ไม่สามารถจัดการได้แบบสุ่ม / ข้อผิดพลาดส่วนและสิ่งที่คล้ายกันโดยเฉพาะอย่างยิ่ง 'ลงข้างทาง'

ในระยะสั้นแม้ว่าคำตอบของฉันจะถูกต้อง - 9 ครั้งจาก 10 ครั้งคุณจะพบว่าโปรแกรมหยุดทำงานหากคุณใช้วิธีนี้โดยเฉพาะอย่างยิ่งถ้าคุณคิดว่าเป็น 'แนวปฏิบัติที่ดี' ที่จะทำเช่นนั้น ในระยะสั้น: โดยทั่วไปแล้วไม่ใช่

ตัวอย่างเช่นลองนึกภาพว่าในอนาคตตอนนี้สตริงต้องได้รับการปรับแต่งอย่างใดอย่างหนึ่ง โดยทั่วไป coder จะ 'ใช้เส้นทางที่ง่าย' และ (พยายาม) เขียนโค้ดดังนี้:

const char * myFunction(const char* name)
{
    char szBuffer[255];
    snprintf(szBuffer, sizeof(szBuffer), "Hi %s", name);
    return szBuffer;
}

นั่นคือโปรแกรมของคุณจะผิดพลาดเพราะคอมไพเลอร์ (อาจ / อาจจะไม่) ได้เปิดตัวหน่วยความจำที่ใช้โดยszBufferตามเวลาที่printf()อยู่ในmain()ที่เรียกว่า (คอมไพเลอร์ของคุณควรเตือนคุณถึงปัญหาดังกล่าวล่วงหน้า)

มีสองวิธีในการส่งคืนสตริงที่จะไม่ทำให้เกิดความเสียหาย

  1. ส่งคืนบัฟเฟอร์ (คงที่หรือจัดสรรแบบไดนามิก) ที่มีชีวิตอยู่ชั่วขณะ ใน C ++ ให้ใช้ 'คลาสตัวช่วย' (ตัวอย่างเช่นstd::string) เพื่อจัดการกับอายุการใช้งานของข้อมูล (ซึ่งต้องเปลี่ยนค่าส่งคืนของฟังก์ชัน) หรือ
  2. ส่งผ่านบัฟเฟอร์ไปยังฟังก์ชันที่กรอกข้อมูล

โปรดทราบว่าเป็นไปไม่ได้ที่จะใช้สตริงโดยไม่ใช้พอยน์เตอร์ใน C ดังที่ฉันได้แสดงไว้มันมีความหมายเหมือนกัน แม้ในคลาสเทมเพลต C ++ จะมีการใช้บัฟเฟอร์ (นั่นคือพอยน์เตอร์) อยู่เบื้องหลังเสมอ

ดังนั้นเพื่อตอบคำถามที่ดีกว่า (คำถามที่แก้ไขแล้ว) (แน่นอนว่ามี 'คำตอบอื่น ๆ ' มากมายที่สามารถให้ได้)

คำตอบที่ปลอดภัยกว่า:

ตัวอย่างที่ 1 โดยใช้สตริงที่จัดสรรแบบคงที่:

const char* calculateMonth(int month)
{
    static char* months[] = {"Jan", "Feb", "Mar" .... };
    static char badFood[] = "Unknown";
    if (month<1 || month>12)
        return badFood; // Choose whatever is appropriate for bad input. Crashing is never appropriate however.
    else
        return months[month-1];
}

int main()
{
    printf("%s", calculateMonth(2)); // Prints "Feb"
}

สิ่งที่ 'คงที่' ทำที่นี่ (โปรแกรมเมอร์หลายคนไม่ชอบ 'การจัดสรร' ประเภทนี้) คือสตริงจะถูกใส่เข้าไปในส่วนข้อมูลของโปรแกรม นั่นคือมันถูกจัดสรรอย่างถาวร

หากคุณย้ายไปที่ C ++ คุณจะใช้กลยุทธ์ที่คล้ายกัน:

class Foo
{
    char _someData[12];
public:
    const char* someFunction() const
    { // The final 'const' is to let the compiler know that nothing is changed in the class when this function is called.
        return _someData;
    }
}

... แต่อาจจะง่ายกว่าที่จะใช้คลาสตัวช่วยเช่นstd::stringหากคุณกำลังเขียนโค้ดสำหรับการใช้งานของคุณเอง (ไม่ใช่ส่วนหนึ่งของไลบรารีที่จะแชร์กับผู้อื่น)

ตัวอย่างที่ 2 โดยใช้บัฟเฟอร์ที่กำหนดผู้โทร:

นี่เป็นวิธีที่ 'เข้าใจผิดได้มากกว่า' ในการส่งผ่านสตริงไปรอบ ๆ ข้อมูลที่ส่งคืนไม่ได้อยู่ภายใต้การจัดการโดยฝ่ายที่โทร นั่นคือตัวอย่างที่ 1 อาจถูกฝ่ายที่โทรเข้ามาใช้ในทางที่ผิดและทำให้คุณได้รับความผิดพลาดของแอปพลิเคชัน วิธีนี้จะปลอดภัยกว่ามาก (แม้ว่าจะใช้โค้ดมากกว่า):

void calculateMonth(int month, char* pszMonth, int buffersize)
{
    const char* months[] = {"Jan", "Feb", "Mar" .... }; // Allocated dynamically during the function call. (Can be inefficient with a bad compiler)
    if (!pszMonth || buffersize<1)
        return; // Bad input. Let junk deal with junk data.
    if (month<1 || month>12)
    {
        *pszMonth = '\0'; // Return an 'empty' string
        // OR: strncpy(pszMonth, "Bad Month", buffersize-1);
    }
    else
    {
        strncpy(pszMonth, months[month-1], buffersize-1);
    }
    pszMonth[buffersize-1] = '\0'; // Ensure a valid terminating zero! Many people forget this!
}

int main()
{
    char month[16]; // 16 bytes allocated here on the stack.
    calculateMonth(3, month, sizeof(month));
    printf("%s", month); // Prints "Mar"
}

มีสาเหตุหลายประการที่วิธีที่สองดีกว่าโดยเฉพาะอย่างยิ่งถ้าคุณกำลังเขียนไลบรารีเพื่อให้ผู้อื่นใช้ (คุณไม่จำเป็นต้องล็อกเข้ากับรูปแบบการจัดสรร / ยกเลิกการจัดสรรเฉพาะบุคคลที่สามไม่สามารถทำลายรหัสของคุณได้ และคุณไม่จำเป็นต้องเชื่อมโยงไปยังไลบรารีการจัดการหน่วยความจำที่เฉพาะเจาะจง) แต่เช่นเดียวกับรหัสทั้งหมดขึ้นอยู่กับคุณว่าคุณชอบอะไรที่สุด ด้วยเหตุนี้คนส่วนใหญ่จึงเลือกใช้ตัวอย่างที่ 1 จนกว่าพวกเขาจะถูกไฟไหม้หลายครั้งจนไม่ยอมเขียนแบบนั้นอีกต่อไป;)

คำเตือน:

ฉันเลิกใช้ไปหลายปีแล้วและตอนนี้ C ของฉันค่อนข้างเป็นสนิม โค้ดสาธิตนี้ควรคอมไพล์อย่างถูกต้องด้วย C (ใช้ได้สำหรับคอมไพเลอร์ C ++)


2
ที่จริงฟังก์ชั่นความต้องการที่จะกลับมาchar *เป็นตัวอักษรของสตริงใน C char[]เป็นประเภท อย่างไรก็ตามต้องไม่แก้ไขด้วยวิธีใด ๆ ดังนั้นการส่งคืนจึงconst char*เป็นที่ต้องการ (ดูsecurecoding.cert.org/confluence/x/mwAV ) กลับมาchar *อาจมีความจำเป็นถ้าสตริงจะถูกนำมาใช้ในการรับมรดกหรือฟังก์ชั่นห้องสมุดภายนอกที่ (ขออภัย) คาดว่าchar*เป็นอาร์กิวเมนต์ยากแม้มันจะอ่านจากมัน ในทางกลับกัน C ++ มีตัวอักษรconst char[]ประเภทสตริง(และตั้งแต่ C ++ 11 คุณสามารถมีstd::stringตัวอักษรได้)
TManhente

17
@cmroanirgo คำนำหน้าของฉันประกาศให้ผู้อ่านทราบว่าฟังก์ชันนี้สร้างขึ้นโดยผู้ใช้ ฉันคิดว่ามันสมเหตุสมผลอย่างยิ่งที่จะใช้ในบริบทดังกล่าว
quant

4
ตามที่นี่: stackoverflow.com/questions/9970295/…คุณสามารถส่งคืน string literal ได้
giorgim

6
รหัสที่ทำเครื่องหมายfraught with problemsในส่วน "อายุของข้อมูล" นั้นใช้ได้อย่างสมบูรณ์แบบจริงๆ ตัวอักษรสตริงมีช่วงอายุคงที่ใน C / C ++ ดูลิงก์ที่ Giorgi กล่าวถึงด้านบน
chengiz

1
@cmroanirgo การส่งคืนตัวอักษรสตริงเป็นแนวทางปฏิบัติที่ดีและมีสไตล์ที่ดี ไม่ใช่ "เต็มไปด้วยปัญหา" และจะไม่ผิดพลาด 9 ใน 10 ครั้ง: จะไม่มีวันผิดพลาด แม้แต่คอมไพเลอร์จากยุค 80 (อย่างน้อยที่สุดที่ฉันเคยใช้) ก็รองรับอายุการใช้งานสตริงที่ไม่ จำกัด ได้อย่างถูกต้อง หมายเหตุ: ฉันไม่แน่ใจว่าคุณหมายถึงอะไรเกี่ยวกับการแก้ไขคำตอบ: ฉันยังเห็นว่ามีแนวโน้มที่จะขัดข้อง
หยุด

12

สตริง AC ถูกกำหนดให้เป็นตัวชี้ไปยังอาร์เรย์ของอักขระ

หากคุณไม่สามารถมีพอยน์เตอร์ได้โดยนิยามคุณไม่สามารถมีสตริงได้


void foo( char array[], int length)คุณสามารถส่งผ่านในอาร์เรย์เพื่อฟังก์ชั่นและจากนั้นทำงานบนอาร์เรย์ที่: แน่นอนว่าarrayเป็นตัวชี้ที่อยู่ใต้ฝากระโปรง แต่ไม่ใช่ตัวชี้ "อย่างชัดเจน" ดังนั้นจึงอาจใช้งานง่ายกว่าสำหรับบางคนที่เรียนรู้อาร์เรย์ แต่ยังไม่ได้เรียนรู้ตัวชี้
jvriesem

12

สังเกตฟังก์ชั่นใหม่นี้:

const char* myFunction()
{
    static char array[] = "my string";
    return array;
}

ฉันกำหนด "อาร์เรย์" เป็นแบบคงที่ มิฉะนั้นเมื่อฟังก์ชันสิ้นสุดลงตัวแปร (และตัวชี้ที่คุณกำลังส่งคืน) จะอยู่นอกขอบเขต เนื่องจากหน่วยความจำนั้นได้รับการจัดสรรบนสแต็กและจะเสียหาย ข้อเสียของการใช้งานนี้คือโค้ดจะไม่ถูกส่งกลับและไม่ปลอดภัย

อีกทางเลือกหนึ่งคือการใช้mallocเพื่อจัดสรรสตริงในฮีปจากนั้นจึงเป็นอิสระในตำแหน่งที่ถูกต้องของรหัสของคุณ รหัสนี้จะถูก reentrant และเธรดปลอดภัย

ตามที่ระบุไว้ในความคิดเห็นนี่เป็นแนวทางปฏิบัติที่ไม่ดีอย่างยิ่งเนื่องจากผู้โจมตีสามารถฉีดโค้ดไปยังแอปพลิเคชันของคุณได้ (เขา / เธอต้องเปิดโค้ดโดยใช้ GDB จากนั้นสร้างเบรกพอยต์และแก้ไขค่าของตัวแปรที่ส่งคืนให้ล้นและ ความสนุกเพิ่งเริ่มต้น)

ขอแนะนำให้ให้ผู้โทรจัดการเกี่ยวกับการจัดสรรหน่วยความจำ ดูตัวอย่างใหม่นี้:

char* myFunction(char* output_str, size_t max_len)
{
   const char *str = "my string";
   size_t l = strlen(str);
   if (l+1 > max_len) {
      return NULL;
   }
   strcpy(str, str, l);
   return input;
}

โปรดทราบว่าเนื้อหาเดียวที่สามารถแก้ไขได้คือเนื้อหาที่ผู้ใช้ ผลข้างเคียงอื่น - ตอนนี้รหัสนี้ปลอดภัยแล้วอย่างน้อยก็จากมุมมองของไลบรารี โปรแกรมเมอร์ที่เรียกใช้วิธีนี้ควรตรวจสอบว่าส่วนหน่วยความจำที่ใช้เป็นเธรดปลอดภัย


2
โดยทั่วไปแล้วนี่เป็นวิธีที่ไม่ดีในการทำสิ่งต่างๆ ถ่าน * สามารถถูกจัดการโดยรหัสรอบข้าง นั่นคือคุณสามารถทำสิ่งนี้: strcpy (myFunction (), "A really long string"); และโปรแกรมของคุณจะหยุดทำงานเนื่องจากการละเมิดการเข้าถึง
cmroanirgo

บางสิ่งบางอย่างที่ขาดหายไปอยู่ใกล้กับ"คนหนึ่งที่ผู้ใช้"
Peter Mortensen

8

ปัญหาของคุณคือประเภทการส่งคืนของฟังก์ชัน - ต้องเป็น:

char *myFunction()

... แล้วสูตรดั้งเดิมของคุณจะได้ผล

โปรดทราบว่าคุณไม่สามารถทำได้มีสตริง C ได้หากไม่มีพอยน์เตอร์เกี่ยวข้องบางแห่งตลอดแนว

นอกจากนี้: เปิดคำเตือนคอมไพเลอร์ของคุณ มันควรจะมีการเตือนคุณเกี่ยวกับสายการกลับมาที่แปลงchar *ไปcharโดยไม่ต้องหล่ออย่างชัดเจน


1
ฉันคิดว่าลายเซ็นควร const char * เนื่องจากสตริงเป็นตัวอักษร แต่ถ้าฉันไม่เข้าใจผิดคอมไพเลอร์จะยอมรับสิ่งนี้
ลุค

5

จาก backstory ที่คุณเพิ่งเพิ่มเข้ามาพร้อมกับคำถามทำไมไม่เพียงแค่คืนค่าจำนวนเต็ม 1 ถึง 12 สำหรับเดือนแล้วปล่อยให้ฟังก์ชัน main () ใช้คำสั่ง switch หรือ if-else แลดเดอร์เพื่อตัดสินใจว่าจะพิมพ์อะไร แน่นอนว่ามันไม่ใช่วิธีที่ดีที่สุดที่จะไป - char * จะเป็น - แต่ในบริบทของชั้นเรียนเช่นนี้ฉันคิดว่ามันน่าจะสง่างามที่สุด


3

คุณสามารถสร้างอาร์เรย์ในตัวเรียกซึ่งเป็นฟังก์ชันหลักและส่งอาร์เรย์ไปยัง callee ซึ่งเป็น myFunction () ของคุณ ดังนั้น myFunction สามารถเติมสตริงลงในอาร์เรย์ อย่างไรก็ตามคุณต้องประกาศ myFunction () เป็น

char* myFunction(char * buf, int buf_len){
  strncpy(buf, "my string", buf_len);
  return buf;
}

และในฟังก์ชั่นหลักควรเรียก myFunction ด้วยวิธีนี้:

char array[51];
memset(array, 0, 51); /* All bytes are set to '\0' */
printf("%s", myFunction(array, 50)); /* The buf_len argument  is 50, not 51. This is to make sure the string in buf is always null-terminated (array[50] is always '\0') */

อย่างไรก็ตามยังคงใช้ตัวชี้


2

ประเภทการส่งคืนฟังก์ชันของคุณเป็นอักขระเดี่ยว ( char) คุณควรส่งตัวชี้กลับไปที่องค์ประกอบแรกของอาร์เรย์อักขระ หากคุณใช้พอยน์เตอร์ไม่ได้แสดงว่าคุณเมา :(


2

หรือสิ่งนี้เป็นอย่างไร:

void print_month(int month)
{
    switch (month)
    {
        case 0:
            printf("January");
            break;
        case 1:
            printf("february");
            break;
        ...etc...
    }
}

และเรียกสิ่งนั้นกับเดือนที่คุณคำนวณที่อื่น


1
+1 ไม่ใช่สิ่งที่ OP ถาม แต่นี่อาจเป็นสิ่งที่งานมอบหมายคาดหวังให้คุณทำเนื่องจากเขาไม่สามารถใช้พอยน์เตอร์ได้
Vitim.us

แม้แต่ printf ก็ใช้พอยน์เตอร์ ตัวชี้ก็เหมือนกับมีดซึ่งจำเป็นสำหรับการใช้ชีวิตและการทำงาน แต่คุณต้องถือมันด้วยด้ามจับและใช้ด้านที่แหลมคมตัดด้วยมิฉะนั้นคุณจะมีช่วงเวลาที่ไม่ดี การวางช่องว่างในการกำหนดฟังก์ชันที่น่าเสียดายเป็นปัญหาทางสมองสำหรับโปรแกรมเมอร์ C มือใหม่หลายคน ถ่าน * func (ถ่าน * s); ถ่านfunc (ถ่าน * s); ถ่าน func * ถ่าน * s); เหมือนกันทั้งหมด แต่ทั้งหมดดูแตกต่างกันและเพื่อความสับสนรวมกัน * ยังเป็นตัวดำเนินการ de-reference สำหรับตัวแปรที่เป็นพอยน์เตอร์
Chris Reid

1

A charเป็นเพียงอักขระหนึ่งไบต์เดียว ไม่สามารถจัดเก็บสตริงของอักขระหรือเป็นตัวชี้ (ซึ่งคุณไม่สามารถมีได้) ดังนั้นคุณจึงไม่สามารถแก้ปัญหาของคุณได้โดยไม่ต้องใช้พอยน์เตอร์ (ซึ่งchar[]ก็คือน้ำตาลซินแทติก)


1

หากคุณไม่สามารถใช้พอยน์เตอร์ได้ให้ทำดังนี้:

char get_string_char(int index)
{
    static char array[] = "my string";
    return array[index];
}

int main()
{
    for (int i = 0; i < 9; ++i)
        printf("%c", get_string_char(i));
    printf("\n");
    return 0;
}

เลข 9 วิเศษมากและนี่ไม่ใช่ตัวอย่างของการเขียนโปรแกรมที่ดี แต่คุณเข้าใจประเด็น โปรดทราบว่าพอยน์เตอร์และอาร์เรย์เป็นสิ่งเดียวกัน (ชนิดของ) ดังนั้นนี่จึงเป็นการโกงเล็กน้อย


โดยปกติแล้วหากคุณจำเป็นต้องใช้วิธีแก้ปัญหาดังกล่าวในการทำการบ้านข้อสันนิษฐานเบื้องต้นของคุณจะผิด
ชม

1

ในโค้ดของคุณคุณกำลังพยายามส่งคืน a String(ใน C ซึ่งไม่มีอะไรเลยนอกจากอาร์เรย์ของอักขระที่สิ้นสุดด้วยค่าว่าง) แต่ประเภทการส่งคืนของฟังก์ชันของคุณcharเป็นสาเหตุของปัญหาทั้งหมดสำหรับคุณ คุณควรเขียนด้วยวิธีนี้แทน:

const char* myFunction()
{

    return "My String";

}

และเป็นการดีเสมอที่จะconstกำหนดประเภทของคุณด้วยในขณะที่กำหนดตัวอักษรใน C ให้เป็นตัวชี้เนื่องจากตัวอักษรใน C ไม่สามารถแก้ไขได้


0

ต้นแบบฟังก์ชันของคุณระบุว่าฟังก์ชันของคุณจะส่งคืนอักขระ ดังนั้นคุณไม่สามารถส่งคืนสตริงในฟังก์ชันของคุณ


0
char* myFunction()
{
    return "My String";
}

ใน C ตัวอักษรสตริงคืออาร์เรย์ที่มีคลาสหน่วยความจำคงที่แบบคงที่ดังนั้นการส่งตัวชี้กลับไปยังอาร์เรย์นี้จึงปลอดภัย รายละเอียดเพิ่มเติมอยู่ในคำถาม Stack Overflow "Life-time" ของสตริงลิเทอรัลใน C


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.