victor hsu 1B Ответов: 3

Почему он не может работать, я использую указатель(я хочу сравнить имена)


#include <stdio.h>
#include <stdlib.h>

void swap(char *ap,char *bp);
void compare(char *ap,char *bp);
int main()
{
    int b,x,y,j,damn;
    int i=0;
    char info[13][20]=
    {
        "christina",
        "victor",
        "chris",
        "chester",
        "elta",
        "kezia",
        "bew",
        "grace",
        "mavis",
        "tony",
        "oat",
        "adonique",
        "ploy"
    };
    char *ap;
    ap=info[i];
    char *bp;
    bp=info[i+1];
    for(b=0; b<13; b++)
    {
        while(i<13)
        {
            compare(ap,bp);
            i++;
        }
        for(y=0; y<13; y++)
        {
            printf("%s\n", info[y]);
        }
        return 0;
    }
}

void compare(char *ap,char *bp)
{
    int i=0;
    int x;
    int damn;
    if(*ap==*bp)
    {
        int j=1;
        while (*(ap+j)==*(bp+j))
        {
            if (*(ap+j) == '\0' && *(bp+j) == '\0')
            {
                damn=0;
                break;
            }
            j++;
        }
        if (*(ap+j)<*(bp+j))
        {
            damn=1;
        }
        if (*(ap+j)>*(bp+j))
        {
            damn=-1;
        }
    }
        if (*ap<*bp)
        {
            damn=1;
        }
        if (*ap>*bp)
        {
            damn=-1;
        }
        if (damn==-1)
        {
            while(*(ap+x) != '\0' || *(bp+x) != '\0')
            {
                swap(ap,bp);
                x++;
            }
        }
}

void swap(char *ap,char *bp)
{
    char tmp[20];
    int x;
    for(x=0; x<=19; x++)
    {
        tmp[20]=*(ap+x);
        *(ap+x)=*(bp+x);
        *(bp+x)=tmp[20];
    }
}


Что я уже пробовал:

Я изменил какую-то часть и сделал новую функцию сравнения, но она не сработала.

3 Ответов

Рейтинг:
1

Jochen Arndt

Ваш info представляет собой двумерный массив charС где info[index] доступ к массиву данных NULL завершенные строки типа char[] соответственно. char*.

Они обычно называются строковыми указателями. При сравнении этих Уинг == оператор, вы сравниваете указатели (адреса). Для сравнения содержимого (строк) существует стандартная библиотечная функция языка Си: ссылка на strcmp - C++ [^].

Если вы хотите получить доступ к символам из вашего info, вы должны использовать два индекса: info[string_index][char_index].

Когда ap указывает на одну из струн внутри info, вы также можете использовать ap[char_index] или *(ap + char_index) Я предлагаю использовать первый метод, потому что он не так непонятен, как второй . Второй от используется, когда нет индекса char (просто *ap); например, при увеличении указателя внутри цикла.

Так что используйте strcmp чтобы сравнить строки или сделать это в своем собственном коде, обратившись к символам, как описано выше.


victor hsu 1B

хорошо но наш учитель не позволяет нам использовать библиотечную функцию strcmp

Jochen Arndt

Затем вы должны использовать доступ к символам, как описано в моем решении.

Вы делаете это неправильно здесь например:

while ((ap+j)==(bp+j))

Так и должно быть
ap[j] == bp[j]

или
*(ap+j) == *(bp+j)

victor hsu 1B

ладно, а теперь он все еще не поменялся местами? почему?

Jochen Arndt

На этот вопрос уже были даны ответы в решениях 1 и 3.

Однако в вашем коде может быть и больше ошибок (которые также могут быть логическими ошибками, означающими, что это правильный код, но не делающий его так, как он задуман).

Я предлагаю переместить сравнение строк в собственную функцию (то есть: напишите свой собственный strcmp). Тогда код main() становится короче и логические ошибки становятся более очевидными.

Подсказка:
Посмотрите, где вы вызываете функцию swap.
Какова цель цикла while?
Каково значение x изначально?
Каково значение x при следующей итерации цикла?

Рейтинг:
1

Patrice T

C основан на нуле, это означает, что в массиве из 20 элементов их позиции находятся от 0 до 19.

void swap(char *ap, char *bp)
{
    printf("swap");
    char tmp[20];
    int x;
    for(x=0;x<=19;x++)
          {
               tmp[20]=*(ap+x);
               *(ap+x)=*(bp+x);
               *(bp+x)=tmp[20];
          }
}

tmp[20] находится вне массива tmp.
Обратите внимание, что tmp не обязательно быть массивом, достаточно одного символа, как описано в решении 1.

Вам действительно нужно изучить отладчик, чтобы узнать, что работает, а что нет.

[Обновление]
Цитата:
кто-то говорит ,что у моего свопа есть проблема, но я не знаю, какая часть имеет проблему, может ли вы мне помочь.

Я не знаю, в чем именно заключается проблема, было много версий вашего кода со многими предложенными исправлениями.

Изучая программирование с помощью языка си, Вы делаете это трудным путем, потому что с помощью языка си Вы должны обрабатывать все детали.
Мой совет: Научитесь программировать с помощью Visual Basic, он будет обрабатывать большинство деталей, и вы сможете сосредоточиться на изучении программирования.
Как только вы разберетесь в программировании, вы сможете изучить специфику языка C.

Вот ссылки на справочники книг по Си и Си++ авторов этих языков. Обратите внимание, что C является предком C++, поэтому знание C всегда полезно с C++.
Язык программирования Си - Википедия, свободная энциклопедия[^]
https://hassanolity-да.files.wordpress.com/2013/11/the_c_programming_language_2.pdf[^]
http://www.ime.usp.br/~ПФ/Керниган-Ритчи/с-Программирование-электронные книги.формат PDF[^]

Язык Программирования C++ [^]


victor hsu 1B

я запускаю его, но ошибка:подписанное значение не является ни массивом, ни указателем, ни вектором, я не понимаю, что это значит

Patrice T

Воспользуйся Улучшить вопрос чтобы обновить ваш вопрос.
Чтобы каждый мог обратить внимание на эту информацию.
Показать фактический код, сообщение об ошибке и номер строки

victor hsu 1B

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

Рейтинг:
0

CPallini

Правильная реализация вашего swap функция была бы

void swap( char pa[], char pb[], int size)
{
  char t;
  int n;
  for (n=0; n<size; ++n)
  {
    t = pa[n];
    pa[n] = pb[n];
    pb[n] = t;
  }
}

Обратите внимание: копирование массивов символов это очень неэффективно по сравнению с простой заменой указателей символов (вариант, предложенный в вашем предыдущем посте).


victor hsu 1B

я меняю его, но он все равно не может работать.