>
나는 C를 처음 접했고 char * 의 가치를 바꾸는 방법에 대해 혼란스러워한다.  기능 간.

예 :

#include <stdio.h>
void testing(char *s) {
        s = "hi";
} // testing
int main() {
        char *s = "hello";
        testing(s);
        printf("%s\n", s);
} // main

이 경우, s 값은 변경되지 않으며 "hello"  인쇄됩니다.

s 를 어떻게 바꿀 수 있습니까 , 함수의 반환 유형이나 매개 변수를 변경하지 않고?


  • 답변 # 1

    C 함수 호출은 엄격하게 값을 전달합니다. 이것은 당신이 s 를 통과하면 의미   testing 로 로컬 사본이 작성됩니다. s 에 새로운 값 할당  따라서 함수에서 main 의 값에 영향을 미치지 않습니다. .

    포인터의 값이 복사되기 때문에 포인터가 가리키는 메모리에 액세스 할 수 있습니다. 만약 s  읽기 전용이 아닌 메모리를 가리키면 한 버퍼의 내용을 다른 버퍼로 복사 할 수 있습니다. 예를 들어, s = "hi"; 대신 ,

    strcpy(s, "hi");
    
    
    main 에서 , 진술 char *s = "hello";   s 가있을 가능성이 높습니다  읽기 전용 버퍼를 가리 킵니다. 쓰기 가능한 버퍼로 만들려면 s 를 선언하십시오.  대신 배열로 :

    char s[] = "hello";
    
    

    포인터가 아닌 포인터 값을 변경하려면 main 를 포함하는 메모리의 주소를 전달해야합니다 s 의 버전 : 포인터에 대한 포인터. 다음과 같이 보일 것입니다 :

    #include <stdio.h>
    void testing(char **s) {
            *s = "hi";
    } // testing
    int main() {
            char *s = "hello";
            testing(&s);
            printf("%s\n", s);
    } // main
    
    

    또 다른 (아마도이 ​​맥락에서 더 나은) 방법은 입력 및 출력 모두에 매개 변수 대신 반환 값을 사용하는 것입니다.

    #include <stdio.h>
    char *testing(char *s) {
            s = "hi";
            return s;
    } // testing
    int main() {
            char *s = "hello";
            s = testing(s);
            printf("%s\n", s);
    } // main
    
    

  • 답변 # 2

    main 에서 char *s  문자열 리터럴 "hello" 로 초기화됩니다. . 이것은 s 를 의미  6 char 의 익명 배열을 가리킬 것입니다.   { 'h', 'e', 'l', 'l', o', '\0' } 값을 포함 . 그러나이 배열의 내용은 표준에 관한 한 수정할 수 없으므로이 배열에 쓰는 코드는정의되지 않은 동작을 나타냅니다.

    testing 에 전화 매개 변수 char *s  함수 내에서 지역 변수로 취급됩니다. 포인터 값을 변경해도 char *s 에 영향을 미치지 않습니다   main 의 변수 . C 함수 호출에서 모든 매개 변수는값으로전달됩니다.

    testing 내 , 당신은 s 를 변경  다른 문자열 리터럴 "hi" 를 가리 키려면 . main 의 초기화와 유사 testing s  3 char 의 익명 배열을 가리 킵니다.   { 'h', 'i', '\0' } 값을 포함 . 이 익명 배열의 내용은 수정할 수 없습니다. 위에서 언급했듯이 이것은 main 에 영향을 미치지 않습니다. s  포인터.

    매개 변수를 수정하거나 두 함수의 반환 유형을 원하지 않는다고 언급했습니다. 그렇게하기 위해, testing  매개 변수 s 가 가리키는 배열의 내용을 덮어 써야합니다. . main 의 현재 코드부터  와이즈 비즈  수정할 수없는 배열을 가리키는 경우 수정 가능한 배열을 가리 키도록 변경해야합니다. 이것은 s 를 변경하여 수행 할 수 있습니다 main  포인터 대신 배열로 :

    s
    
    

    그런 다음 int main() { char s[] = "hello"; // N.B. s[] is 6 chars long including the null terminator testing(s); printf("%s\n", s); } // main 를 변경할 수 있습니다  매개 변수 testing 가 가리키는 배열의 내용을 겹쳐 쓰려면 :

    s
    
    

    나는 #include <string.h> void testing(char *s) { strcpy(s, "hi"); } // testing 를 사용했다  위 버전의 strcpy 에서 표준 라이브러리 기능 .

    너무 많은 testing 를 쓰지 않도록하는 것은 당신에게 달려 있습니다. char 가 가리키는 배열에 s .

    배열 s 의 길이  main에서 초기화 프로그램 "hello"(5 자 + null 종료 자 문자)에 의해 자동으로 6으로 설정되었습니다. 6 개 이상의 s 를 덮어 써야하는 경우 명시 적으로 배열의 길이를 설정할 수 있습니다. 널 종료자를 포함하여 :

    char
    
    

  • 답변 # 3

    함수는 인수 값의 사본 만받습니다 :

       char s[100] = "hello";  // s[100] has space for 99 characters plus a null terminator.
    
    

    함수를 돌려서 값을 돌려받을 수 있습니다 :

    void f(int x)          // x is a new variable that is initialized to the argument value.
    {
        x = x + 3;         // Adds 3 to the local x.
        printf("%d\n", x); // Prints 8.
    }
    int main(void)
    {
        int x = 5;
        f(x);              // Passes 5, not x, to f.
        printf("%d\n", x); // Prints 5, not 8.
    }
    
    

    함수가 객체의 값을 변경하도록하여 함수에서 값을 다시 가져올 수도 있습니다. 이렇게하려면 객체의 주소를 함수에 제공해야합니다.

    int f(int x)           // Function is changed to return int.
    {
        x = x + 3;         // Adds 3 to the local x.
        printf("%d\n", x); // Prints 8.
        return x;          // Returns new value.
    }
    int main(void)
    {
        int x = 5;
        x = f(x);          // Set x from the value returned by the function.
        printf("%d\n", x); // Prints 8.
    }
    
    

    함수를 변경하는 함수를 원한다면, 포인터의 주소를 전달할 수 있습니다 :

    void f(int *p)          // p is a pointer to an int.
    {
        *p = *p + 3;        // Adds 3 to the pointed-to int.
        printf("%d\n", *p); // Prints 8.
    }
    int main(void)
    {
        int x = 5;
        f(&x);             // Passes address of x to f.
        printf("%d\n", x); // Prints 8.
    }
    
    
    void f(char **p) // p is a pointer to a pointer to a char. { *p = "hi" // Sets *p to point to (first character of) "hi". printf("%s\n", x); // Prints "hi". } int main(void) { char *s = "hello"; // Sets s to point to (first character of) "hello". f(&s); // Passes address of s to f. printf("%s\n", x); // Prints "hi". }

관련 자료

  • 이전 java - MyClassclassgetResource ()에서 레벨을 올리는 방법
  • 다음 java - 실 서버 중지