Несовместимая ошибка типа указателя [C] - PullRequest
1 голос
/ 15 апреля 2009

Мне постоянно говорят, что в этой строке кода передается аргумент из несовместимого типа указателя.
Вот строка кода:

if (linear_search (size_of_A, argv[i]))  

Что это значит и как мне это исправить? Вот вся программа:

int linear_search ( int size_of_A, char*argv[]){  
   int i;  
   i = 2;  
   while (i <= size_of_A - 1){  
      if (!strcmp (argv [1], argv[i])){  
      return 1;  
      }  
   }  
   return 0;  
}  

int main (int argc, char*argv []){  
   int size_of_A = argc - 2;  
   int i = 2;  
      if (linear_search (size_of_A, argv)){  
         printf ("%s not found\n", argv [1]);  
         return 1;  
      } else{  
         printf ("%s found\n", argv[1]);  
         return 0;  
      }  
      i = i + 1;  
   }  
}   

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

./a 3 hso 8 3  
3 found 

Ответы [ 10 ]

4 голосов
/ 15 апреля 2009

linear_search ожидает тип данных "char **". Вы передаете argv[i], что является просто char*. Попробуйте передать в "argv", как это:

if (linear_search(size_of_A, argv))
2 голосов
/ 15 апреля 2009

У вас логическая ошибка в linear_search. У вас есть цикл while, основанный на значении i, но i никогда не меняется. Возможно, вам не хватает инструкции i++;.

Также (хотя это не изменит поведения вашей программы): переменная i в main никогда не используется. Вы можете удалить его и инструкцию i = i + 1;.

1 голос
/ 15 апреля 2009

Ваша функция линейного поиска сравнивает только argv [1] с argv [2], так как i никогда не увеличивается. Возможное решение (использование цикла for вместо while, что более распространено):

int linear_search ( int size_of_A, char*argv[]){  
   int i = 0;  // should always initialize in construction
   for ( i = 2; i < size_of_A; ++i ) {
      if (!strcmp (argv [1], argv[i])){  
        return 1;  
      }  
   }  
   return 0;  
}

Переменная i никогда по-настоящему не используется в main, вы можете безопасно удалить две строки, которые с ней работают.

1 голос
/ 15 апреля 2009

Вы передаете параметр (второй) в функцию linear_search, который не соответствует ожидаемому типу аргумента. argv [i] имеет тип char *, который обычно называют строкой, в то время как функция linear_search ожидает char * [], который является массивом строк.

0 голосов
/ 15 апреля 2009

oldfart: Остерегайтесь strcmp и всех неограниченных строковых функций (например, strcpy - но будьте осторожны с strncpy: он не добавляет завершающий NULL).

youngun: Но это нормально, так как argv содержит несколько завершенных строк NULL!

из: Этот способ мышления приводит к тому, что переполнение буфера помогает в куче. argv был инициализирован с NULLS. Но с тех пор все могло измениться.

y: Но это небольшая программа, и она никогда не произойдет.

из: Конечно. Программы растут, и «никогда» не случается чаще, чем вы думаете.

y: Хорошо, мистер Параноик, какой размер я должен использовать для ограничения на strncmp? Там нет очевидного числа для использования! Вы предлагаете мне что-нибудь придумать?

из: См. Limit.h, в частности ARG_MAX и _POSIX_ARG_MAX для возможных максимальных значений. Вы можете использовать меньшие значения, если хотите. Если вы это сделаете, задокументируйте это .

y: Итак, я должен написать strncmp( arg, target, 5000 )? Хорошо, мистер параноик.

из: Не делай этого! #define APP_MAX_ARG 5000 и затем используйте strncmp( arg, target, APP_MAX_ARG ). Не заводи меня на магические числа. Дети в эти дни.

из: Эй, малыш, Сойди с моего газона .

0 голосов
/ 15 апреля 2009

Это, кажется, отличное место, чтобы использовать тот факт, что argv<code> is <code>NULL -определен. Вам не нужно передавать количество предметов в нем, но просто сделайте так:

/* Searches through the NULL-aterminated array for the.
 * given needle string. Returns 1 if found, 0 if not.
*/
int linear_search (char **argv, const char *needle)
{
  int i;

  for(i = 0; argv[i] != NULL; i++)
  {
     if(strcmp(argv[i], needle) == 0)
       return 1;
  }
  return 0;
}

Кстати, я рекомендую сравнивать возвращаемое значение strcmp () nagainst литерал 0, а не использовать! запись, поскольку возвращаемое значение на самом деле не является логическим; он возвращает int , который выражает отношение между сравниваемыми элементами.

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

0 голосов
/ 15 апреля 2009

Ваш linear_search () принимает «массив строк» ​​(указатель на массив символов), а вы передаете ему «строку» (argv [i]). Я думаю, вы хотите вызвать linear_search следующим образом:

if (linear_search (size_of_A, (argv + i)))

Хотя я не совсем понимаю логику вашей программы ... Вы пытаетесь найти argv [1] в более поздних аргументах ...?

0 голосов
/ 15 апреля 2009
int linear_search ( int size_of_A, char*argv[]){ 

char*argv[] означает «указатель на массив символов»; как параметр вызова функции, это то же самое, что и char**.

argv - это a char**, но argv[i] - это char*, поскольку C определяет argv[i] как *(argv + i ) или, на английском языке, «разыменование (argv плюс i)». Разыменование char** оставляет вас с char*, и это не то, что linear_search объявлено, чтобы взять.

Посмотрите здесь, если вы все еще в замешательстве.
`

0 голосов
/ 15 апреля 2009

Я не знаю логику вашей программы, но ошибка компилятора решена. Смотрите это:

int main (int argc, char * argv []) {

int size_of_A = argc - 2;  
int i = 2;  
if (linear_search (size_of_A, argv[])){  
     printf ("%s not found\n", argv [1]);  
     return 1;  
} 
0 голосов
/ 15 апреля 2009

Ваша функция ожидает char*[] (что в данном случае должно быть эквивалентно char**). Однако, позвонив по номеру

linear_search (size_of_A, argv[i])

вы просто передаете char* в качестве аргумента (поскольку [i] разыменовывает один указатель). Из того, что я вижу в вашем коде, вы можете попробовать использовать

linear_search (size_of_A, argv+i)

но я не совсем уверен, приведет ли это к намеченному поведению. Все еще слишком рано, чтобы понять C:)

...