programing

할당은 캐스트가 없는 정수에서 포인터를 만듭니다.

testmans 2023. 10. 12. 22:16
반응형

할당은 캐스트가 없는 정수에서 포인터를 만듭니다.

자바 배경에서 저는 C를 배우고 있지만, 모호한 컴파일러 오류 메시지가 점점 더 좌절감을 느낍니다.제 암호는 이렇습니다.

/*
 * PURPOSE
 *      Do case-insensetive string comparison.
 */
#include <stdio.h>
#include <string.h>
#include <ctype.h>

int compareString(char cString1[], char cString2[]);
char strToLower(char cString[]);

int main() {
    // Declarations
    char cString1[50], cString2[50];
    int isEqual;

    // Input
    puts("Enter string 1: ");
    gets(cString1);
    puts("Enter string 2: ");
    gets(cString2);

    // Call
    isEqual = compareString(cString1, cString2);
    if (isEqual == 0)
        printf("Equal!\n");
    else
        printf("Not equal!\n");

    return 0;
}

// WATCH OUT
//      This method *will* modify its input arrays.
int compareString(char cString1[], char cString2[]) {
    // To lowercase
    cString1 = strToLower(cString1);
    cString2 = strToLower(cString2);

    // Do regular strcmp
    return strcmp(cString1, cString2);
}

// WATCH OUT
//      This method *will* modify its input arrays.
char strToLower(char cString[]) {
    // Declarations
    int iTeller;

    for (iTeller = 0; cString[iTeller] != '\0'; iTeller++)
        cString[iTeller] = (char)tolower(cString[iTeller]);

    return cString;
}

이렇게 하면 경고가 두 개 발생합니다.

  • 할당은 캐스트가 없는 정수에서 포인터를 만듭니다.
    • cString1 = strToLower(cString1);
    • cString2 = strToLower(cString2);
  • 반환은 캐스트 없이 포인터에서 정수를 만듭니다.
    • cString을 반환합니다.

누가 이 경고를 설명해 줄 수 있습니까?

C 문자열은 자바 문자열과 전혀 다릅니다.그들은 본질적으로 캐릭터들의 배열입니다.

strToLower가 char를 반환하므로 오류가 발생합니다.char는 C에서 정수의 한 형태입니다.포인터인 char[]에 할당하는 것입니다.따라서 "정수를 포인터로 변환"합니다.

strToLower는 모든 변경 사항을 변경합니다. 특히 차가 아닌 다른 것을 반환할 이유가 없습니다.공백 또는 char*를 반환해야 합니다.

strToLower로 호출할 때 또한 할당할 필요가 없으므로 cString1에 대한 메모리 주소를 전달하는 것입니다.

제 경험상, C의 문자열은 자바/C# 배경에서 C로 돌아가는 사람들에게 가장 배우기 어려운 부분입니다.사람들은 (자바에서도 어레이를 할당하는 경우가 많기 때문에) 메모리 할당을 잘 할 수 있습니다.최종 목표가 C가 아닌 C++라면 C 문자열에 덜 집중하고 기본 사항을 이해하고 STL의 C++ 문자열을 사용하는 것을 선호할 수 있습니다.

은 strToLower 의이어야 합니다.char*것은 아니다.chare하지 하지 않아야 시 할당다)

  • 1) 사용하지않습니다.gets! 버퍼 오버플로우 취약성을 도입했습니다.fgets(..., stdin)대신.

  • 2)에서strToLower합니다를 chara char-어레이. 둘 중 하나만 돌려도 돼요.char*가 제안한 를(를) 반환합니다void입력 내용을 수정하고 계시니까요.요만 쓰면 됩니다.

 

 strToLower(cString1);
 strToLower(cString2);
  • 를 구분하지 않는 하려면 3) /를 strcasecmp및 스 및 Mac)스stricmp(윈도우즈).

다른 와 같이 를 반환하려고 하는 . 입니다.cString은 (char * context - 이 컨텍스트에서 값을 하도록 선언된 ))char(이것은 정수입니다.)합니다를 A를 할당하는 것입니다.char합니다.char *포인팅합니다.이것이 경고를 유발하는 이유입니다.의 반품 다로 .char *, 로는 아닌char.

참고로, 이러한 할당은 (적분 상수 0을 제외하고) C에서 포인터와 정수를 혼합하는 것은 불법이기 때문에, 언어적 관점에서 볼 때 사실상 제약 위반(즉, "오류")입니다.이 점에서 귀하의 컴파일러는 너무 용서할 수 없으며 이러한 위반을 단지 "경고"로 보고합니다.

은 몇몇 에서 입니다를 수 입니다.void문자열을 inplace로 수정하기 때문에 함수를 사용할 수 있습니다.확실히 작동하겠지만(실제로 문자열을 수정하는 것이므로) 함수에서 동일한 값을 반환하는 것은 문제가 없습니다.C실,되는 C입니다와 strcpy사용을 선택하면 함수 호출을 "연쇄"할 수 있고, "연쇄"를 사용하지 않으면 사실상 비용이 들지 않기 때문입니다.

그건 는, 만을 하는 데 .compareString내 눈에는 완전히 불필요해 보입니다. (그들은 아무것도 깨지지 않을지라도)그들을 없애버릴 겁니다

int compareString(char cString1[], char cString2[]) { 
    // To lowercase 
    strToLower(cString1); 
    strToLower(cString2); 

    // Do regular strcmp 
    return strcmp(cString1, cString2); 
} 

또는 "연쇄"를 사용하고 할 수 있습니다.

int compareString(char cString1[], char cString2[]) { 
    return strcmp(strToLower(cString1), strToLower(cString2)); 
} 

이 의 (char *반품이 편리할 것입니다) .이러한 "연쇄된" 함수 호출은 단계별 디버거로는 디버그하기 어려운 경우가 있습니다.

추가적으로, 저는 (입력된 문자열을 수정하는) 그러한 파괴적인 방식으로 문자열 비교 기능을 구현하는 것은 좋은 생각이 아닐 수도 있다고 말하고 싶습니다.제 생각에 비파괴적인 기능이 훨씬 더 큰 가치가 있을 것 같습니다.입력 문자열을 소문자로 명시적으로 변환하는 대신 일반적으로 사용자 지정 문자별 대소문자 구분 문자열 비교 기능을 구현하여 표준을 호출하는 대신 사용하는 것이 좋습니다.strcmp.

이 두 가지 과제는 필요 없습니다.

cString1 = strToLower(cString1); 
cString2 = strToLower(cString2);

문자열을 수정하는 중입니다.

경고는 char를 반환하고 char[](char*에 해당)에 할당하기 때문입니다.

배열의 첫 번째 문자를 가리키는 char*가 아닌 char*를 반환하는 것입니다.

제자리 수정 대신 새 문자 배열을 반환하려면 이미 할당된 포인터(char*)를 매개 변수로 요청하거나 초기화되지 않은 포인터를 요청할 수 있습니다.이 마지막 경우에는 새 문자열에 대해 적절한 문자 수를 할당하고 C 파라미터의 경우 항상 전달된 값으로 전달되므로 함수별로 내부적으로 할당된 배열의 경우 char**를 매개 변수로 사용해야 합니다.물론 전화를 건 사람은 나중에 그 포인터를 놓아주어야 합니다.

strToLower는 char 대신 char *를 반환해야 합니다.이런 거면 될 거예요.

char *strToLower(char *cString)
char cString1[]

배열, 즉 동일한 데이터 유형의 요소 범위 중 첫 번째 요소를 가리키는 포인터입니다.배열을 기준 값으로 전달하는 것이 아니라 기준 포인터로 전달하는 것입니다.

char strToLower(...)

그러나 이 경우 차가 반환됩니다.그래서 당신의 과제는

cString1 = strToLower(cString1);

할당 연산자의 각 면에 서로 다른 유형이 있습니다.실제로 배열에 'char'(정수의 sort)를 할당하는 것이며, 이는 간단한 포인터로 해결됩니다.C++의 암묵적인 변환 규칙으로 인해 이것은 작동하지만 결과는 쓰레기이며 어레이에 대한 추가 액세스는 정의되지 않은 동작을 야기합니다.

해결책은 다음을 만드는 것입니다.strToLower돌아가다char*.

언급URL : https://stackoverflow.com/questions/2074009/assignment-makes-pointer-from-integer-without-cast

반응형