[-Wincompatible-типы указателей]. не знаю, в чем проблема

#c #pointers #incompatibletypeerror

Вопрос:

Я не могу найти, где это пошло не так. Когда я запускаю программу, она показывает «доступ запрещен».

 #include<stdio.h>
int main()
{
    char arr[4][40] =
    { "array of c string",
        "is fun to use",
        "make sure to properly",
        "tell the array size"
    };
char *p = arr;  /*Char-4-eg-Find-the-output.c:10:11: warning: initialization of 'char *' from 
incompatible pointer type 'char (*)[40]' [-Wincompatible-pointer-types]*/
    for (int i = 0; i < 100; i  )
    {
        printf("%c",*p );
        p  ;
   }
    return 0;
}
 

Комментарии:

1. Каков ваш ожидаемый результат? Что должна делать ваша программа?

2. Программа должна быть в порядке, потому что доступ к байтам в объектах через char* разрешен и arr должен превышать 100 байт. «отказано в доступе», вероятно, означает, что вашему антивирусному программному обеспечению не понравилось ваше творение. Добавьте приведение, чтобы устранить предупреждение: char *p = (char*)arr;

3. Это означает, что char *p = arr; это бессмысленно, просто так. Я предполагаю, что вы хотели указать на первый элемент первого массива? Это было бы char *p = amp;arr[0][0];

Ответ №1:

Обозначения массивов, используемые в выражениях за редкими исключениями, преобразуются в указатели на их первые элементы.

Итак, в этой декларации

 char *p = arr;
 

указатель массива arr преобразуется в указатель на его первый элемент. Элементы массива arr имеют тип char[40] . Таким образом, указатель на объект этого типа имеет тип char( * )[40] .

Однако инициализированный указатель имеет тип char * . И нет никакого неявного преобразования из типа char ( * )[40] в тип char * . Таким образом, компилятор выдает сообщение.

Либо вам нужно использовать кастинг, как

 char *p = ( char * )arr;
 

или написать

 char *p = arr[0];
 

или

 char *p = amp;arr[0][0];
 

Если вы хотите вывести массив строк в виде одного предложения, вы можете написать, например

 #include <stdio.h>

int main(void) 
{
    enum { N = 40 };
    
    char arr[][N] =
    { 
        "array of c string",
        "is fun to use",
        "make sure to properly",
        "tell the array size"
    };
    

    for ( char ( *p )[N] = arr; p != arr   sizeof( arr ) / sizeof( *arr );   p )
    {
        if ( p != arr ) putchar( ' ' );
        printf( "%s", *p );
    }
    
    putchar( 'n' );
    
    return 0;
}
 

Вывод программы является

 array of c string is fun to use make sure to properly tell the array size
 

Комментарии:

1. В этом случае предупреждение можно отключить с char *p = arr[0]; помощью или char *p = amp;arr[0][0]; ,, но я не уверен, что ОП пытается сделать с обрезанным кодом, который он опубликовал.

2. @icebp его char (*p)[40] = arr; тоже можно заставить замолчать

Ответ №2:

Измените char *p = arr; на char *p = amp;arr[0][0]; .

Комментарии:

1. Это просто отрывок из другого (хорошего) ответа, без каких-либо объяснений…

2. @manuell Извините, мне также нужно готовиться к экзаменам в моей средней школе, поэтому у меня не было так много времени, чтобы подробно объяснить это, но я, конечно, не вычитал это из других ответов.