2016-07-10 4 views
1
void printInstructions(); 
char *getUserWord(); 


int main() 
{ 
    printInstructions(); 
    char *baseWord = getUserWord(); 
    printf("%s", baseWord); 
    return 0; 
} 


void printInstructions() 
{ 
    printf("      Instructions:      \n" 
    "===================================================================\n" 
    "= This program is a hangman game.         =\n" 
    "= The first user will enter the name to be guessed    =\n" 
    "= After that, the second user will guess the letters of the word =\n" 
    "= the second user will loose if they have three strikes   =\n" 
    "===================================================================\n"); 
    return; 
} 


char *getUserWord() 
{ 
    static char str[20]; 
    scanf("%s", str); 
    return str; 
} 

내 기능 getUserWord은 문자열을 전달하여 작업을 수행합니다. 내가 온라인으로 읽은 것에서부터 char *baseWord = getUserWord();은 주 함수 내의 변수에 문자열을 할당하는 유일한 방법이었다. 나는 이것이 왜 작동하는지 모르며, 이것이 메모리에서 무엇을하는지조차 확신하지 못한다. 아래는 나에게 의미가있는 것입니다. 왜 이것이 효과가 없을까요?함수를 통해 문자열 전달. C

char baseWord[21]; 
baseWord = getUserWord(); 

답변

5

당신은 포인터와 배열이 같은 것이라고 믿는 함정에 빠졌습니다. 그들은 그렇지 않습니다.

문자열은 일반적으로 C에서 규칙에 따라 char의 배열로 표시되며 추가 종료자인 '\0' (소위 nul 문자)이 마지막에 추가됩니다. 따라서 문자열 리터럴 "AB"은 값이 'A', 'B''\0' 인 세 개의 char 배열로 표시됩니다.

포인터는 배열과 완전히 다르며 문자열은 char의 배열을 사용하여 표현되므로 포인터와 문자열은 완전히 별개입니다. 포인터는 메모리에 주소를 포함하는 변수입니다.

일들이 혼란 스러울 때 배열의 이름은 많은 컨텍스트에서 포인터로 변환됩니다. 예를 들어;

char x[] = "AB"; 
char *p = x; 

이 할당은 작동하지만, 배열이 포인터이거나 포인터가 배열 인 것은 아닙니다. 대신 이름 x은 첫 번째 문자에 대한 포인터로 변환됩니다. 그래서 초기화 문자열 "AB" 가치 'A'와 문자

char *p = &x[0]; 

그래서 p 점 기능적으로 동일합니다.

같은 일이 두 경우 모두

char *getUserWord() 
{ 
    static char str[20]; 
    scanf("%s", &str[0]); 
    return &str[0]; 
} 

char *getUserWord() 
{ 
    static char str[20]; 
    scanf("%s", str); 
    return str; 
} 

가 동등하므로, 코드에서 어떤 일이 일어나고, getUserWord()에 의해 반환되는 포인터는 str[0]의 주소 값을 가지고있다. 즉 baseWord 지금 배열 것처럼 배열의 첫 번째 문자로, 그것은 처리 할 수 ​​있기 때문에 점 main()

char *baseWord = getUserWord(); 

baseWord을 초기화하는 데 사용되는 값이다. C에서 주어진 값이 i 인 경우 baseWord[i] (main())과 str[i]() 사이의 등가 치를 포함합니다. 배열 구문이 사용된다는 사실은 포인터와 배열이 같은 것을 의미하지는 않습니다. 단지 동일한 구문을 사용하여 작업 할 수 있음을 의미합니다.

그러나 실현해야 할 중요한 점은 함수에서 포인터를 반환 할 수 있지만 (배열에 할당 된 반환 값을 사용하거나 초기화에 사용 된 반환 값) 배열이 반환 할 수 없다는 점입니다. 따라서 main()에서 이것은 유효합니다.

char *p = getUserWord(); 
p[0] = 'X'; /* will change str[0] in getUserWord() */ 

그러나 이것은 아닙니다.

char array[20] = getUserWord(); 
+0

대단히 감사합니다. 그래서 실제로 배열을 통해 문자열을 전달할 수있는 방법은 없습니다. 또한, "char * getUserWord()"라고 할 때 함수가 주소를 반환한다는 것을 알 수 있습니까? –

+0

첫 번째 질문에 대한 귀하의 말씨가 명확하지 않습니다 - "배열을 통해 문자열을 전달"한다는 것은 무엇을 의미합니까? 두 번째로 - char * getUserWord() 선언은 포인터를 반환하는 함수를 지정하고 포인터는 주소를 포함하는 변수 유형입니다. – Peter

+0

첫 번째 질문은 실제로 함수에서 문자열을 반환하는 것이 가능하다는 것을 의미합니다. –

-1

이 코드

char baseWord[21]; 
baseWord = getUserWord(); 
어떻게 배열에서 변환 된 것은 수정 좌변이 할당 연산자의 왼쪽 피연산자 필요하면서 좌변 ( N1570 6.3.2.1)이 아니기 때문에

가 작동하지 (N1570 6.5.16).

문자열 읽기가 저장 될 배열에 포인터를 호출 할 수 있습니다. 읽기가 성공하면이 예에서 생략

#include <stdio.h> 

void getUserWord(char* str); 

int main(void) 
{ 
    char baseWord[21] = ""; /* initialize for avoiding undefined behavior in case no data is read */ 
    getUserWord(baseWord); 
    printf("%s", baseWord); 

    return 0; 
} 

void getUserWord(char* str) 
{ 
    scanf("%s", str); 
} 

, 당신은 확인해야합니다.

4

배열을 C로 할당 할 수 없습니다. C 표준 에서 지정해야합니다. 두 번째 예제의 lvalue는 baseWord이고 배열 인 char[21] 유형입니다. 첫 번째 예에서

, 당신은 유형 static char[20]을 가지고 str을 반환 할 때, 그것은 유형 char*로 변환하고 함수에서 반환 및 baseWord을 포인터에 할당 할 수 있습니다. str에는 정적 저장 기간이 있으므로 포인터는 유효한 개체를 가리 킵니다.

정적이 아닌 문자열을 반환하려면 함수 (malloc 함수 사용)를 할당하거나 기존 문자열을 함수에 전달하거나 구조체로 문자열을 래핑 할 수 있습니다.


1 을 (: ISO :에서 인용 9899 IEC :. 201X 6.3.2.1는 Lvalues는 1 배열 및 기능 부호)
수정 가능한 좌변은 배열 유형이 없다는 좌변은,하지 불완전한 타입을 가지지 않고, const 타입을 가지지 않으며, 구조체 또는 공용체 인 경우, const (이)가 포함 된 어떠한 멤버도 포함하지 않는다 (재귀 적으로, 을 포함하는 모든 포함 된 집계 또는 합집합의 멤버 또는 요소). - 인증 유형