programing

주의: 어레이 첨자에 char 유형이 있습니다.

randomtip 2022. 7. 12. 23:23
반응형

주의: 어레이 첨자에 char 유형이 있습니다.

이 프로그램을 실행하면 "array subscript has type 'char"라는 경고가 나타납니다.어디가 잘못됐는지 도와주세요.사용하고 있는 코드::blocks IDE

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
void NoFive()
{
    long long int cal;
    char alpha[25];
    char given[100] = "the quick brown fox jumped over the cow";
    int num[25];
    int i, k;
    char j;
    j = 'a';
    k = 26;
    cal = 1;
    for(i = 0; i <= 25; i++)
    {
        alpha[i] = j++;
        num[i] = k--;
      //  printf("%c = %d \n", alpha[i], num[i]);
    }
    for(i = 0; i <= (strlen(given) - 1); i++)
    {
        for(j = 0; j <= 25; j++)
        {
         if(given[i] == alpha[j]) ***//Warning array subscript has type char***
         {
            cal = cal * num [j]; ***//Warning array subscript has type char***
         }
         else
         {

         }
        }
    }
printf(" The value of cal is %I64u ", cal);
}

main()
{
NoFive();
}

심플, 변경

char j;

로.

unsigned char j;

또는 그냥 평원으로(u)int

unsigned int j;
int j;

GCC로부터의 경고

-Wchar-subscripts 어레이 서브스크립트의 타입이 char인 경우 경고합니다.프로그래머는 이 타입이 일부 머신에서 서명되어 있는 것을 잊어버리는 경우가 많기 때문에, 이것은 에러의 일반적인 원인입니다.이 경고는 -Wall에 의해 유효하게 됩니다.

컴파일러는 실수로 네거티브 어레이 인덱스를 지정하는 것을 원하지 않습니다.그래서 경고다!

이는 GCC가 진단에서 지나치게 관료적이고 간접적인 표현을 사용하는 전형적인 사례로, 이 유용한 경고 뒤에 숨겨진 진짜 문제를 이해하기 어렵게 만든다.

// Bad code example
int demo(char ch, int *data) {
    return data[ch];
}

근본적인 문제는 C 프로그래밍 언어가 "문자"에 대해 몇 가지 데이터 유형을 정의한다는 것입니다.

  • char에는 "기본 실행 문자 집합의 문자"를 포함할 수 있습니다(적어도 A-Z, a-z, 0-9 및 여러 구두점 문자를 포함합니다).
  • unsigned char에는 적어도 0 ~255 범위의 값을 유지할 수 있습니다.
  • signed char에는 적어도 -127 ~127 범위의 값을 유지할 수 있습니다.

C 표준은 다음과 같이 정의한다.char다음 중 하나와 같은 방식으로 동작합니다.signed char또는unsigned char어떤 타입이 실제로 선택되는지는 컴파일러와 운영체제에 따라 다르며, 이 타입에 의해 문서화되어야 합니다.

어레이의 요소에 액세스 할 때arr[index]expression, GCC가 콜하는 경우index첨자대부분의 경우 이 배열 색인은 부호 없는 정수입니다.이것은 일반적인 프로그래밍 스타일로, Java 또는 Go와 같은 언어는 배열 인덱스가 음수인 경우 예외를 발생시킵니다.

C에서 Out-of-Bounds 배열 인덱스는 정의되지 않은 동작을 호출하는 것으로 정의됩니다.다음 코드가 완전히 유효하기 때문에 컴파일러는 모든 경우에 음의 배열 인덱스를 거부할 수 없습니다.

const char *hello = "hello, world";
const char *world = hello + 7;
char comma = world[-2];   // negative array index

C 표준 라이브러리에는 올바르게 사용하기 어려운 곳이 하나 있는데, 그것은 헤더로부터의 문자 분류 함수입니다.<ctype.h>,예를 들어isspace.표현isspace(ch)인수로 문자를 사용할 것 같습니다.

isspace(' ');
isspace('!');
isspace('ä');

스페이스와 느낌표는 기본 실행 문자 집합에서 나왔기 때문에 컴파일러가 정의하는지 여부에 관계없이 동일하게 표현되도록 정의되어 있기 때문에 처음 2개의 케이스는 괜찮습니다.char서명 또는 서명되지 않은 상태로 표시됩니다.

하지만 마지막 사건은, 움라우트가'ä' 하다. 으로 기본 문자 집합 밖에 .일반적으로 기본 실행 문자 집합 외부에 있습니다.에는 1990년 ISO 8859-1이 .'ä'합니다.

unsigned char auml_unsigned = 'ä';   // == 228
signed   char auml_signed   = 'ä';   // == -28

,.isspace이치노

static const int isspace_table[256] = {
    0, 0, 0, 0, 0, 0, 0, 0,
    1, 1, 1, 0, 0, 1, 0, 0,
    // and so on
};

int isspace(int ch)
{
    return isspace_table[ch];
}

이 구현 기법이 일반적입니다.

isspace('ä')가 「이러다」를 정의하고 로 하고 charsigned charISO 8859-1입니다.할 때 이고 이 은 -28로 됩니다.int값을 보존합니다.

되면 됩니다.isspace_table[-28]이는 배열의 경계를 벗어난 테이블에 액세스합니다.이 막연한 행동을 호출합니다.

는 컴파일러 경고하게 설명합니다 그것은 정확히 이 시나리오.

<ctype.h>★★★★★★★★★★★★★★★★★★:

// Correct example: reading bytes from a file
int ch;
while ((ch = getchar()) != EOF) {
    isspace(ch);
}

// Correct example: checking the bytes of a string
const char *str = "hello, Ümläute";
for (size_t i = 0; str[i] != '\0'; i++) {
    isspace((unsigned char) str[i]);
}

또한 매우 유사하라 잘못된 것으로 보인다 몇몇 방식들이 있습니다.

// WRONG example: checking the bytes of a string
for (size_t i = 0; str[i] != '\0'; i++) {
    isspace(str[i]);   // WRONG: the cast to unsigned char is missing
}

// WRONG example: checking the bytes of a string
for (size_t i = 0; str[i] != '\0'; i++) {
    isspace((int) str[i]);   // WRONG: the cast must be to unsigned char
}

합니다.-28 int 가 value-28이에 따라 부정적인 배열 인덱스로 이어진다.

// WRONG example: checking the bytes of a string
for (size_t i = 0; str[i] != '\0'; i++) {
    isspace((unsigned int) str[i]);   // WRONG: the cast must be to unsigned char
}

값인 '이러다'를 합니다.-28unsigned int하면 값 '''는 ''''''는 '''-28하여 가산하여 이 2^32의 에 들어갈 때까지 됩니다.unsigned int'4_294_967_268, '는 '4_294_967_268'입니다.

Ilig의은 NOT가 아닙니다.'ä'심지어(또는 이것은 바이트에 들어맞지 않는 것이 매우 작거나 아마도 UBimplementation-dependent 컴파일할 수 있)컴파일하지 않을까.을 사용하고 UTF-8, UTF-8, UTF-8을 합니다."ä" is is is is is와 "\xc3\xa4".

언급URL : https://stackoverflow.com/questions/9972359/warning-array-subscript-has-type-char

반응형