Может ли кто-нибудь сказать мне «как функция массива выходит за рамки»? А если нет, то верен ли код?

#arrays #c #function

Вопрос:

Объявите массив чисел int длиной 10. Напишите функцию void readValues(числа int []), которая считывает значения в диапазоне от 10 до 40 с клавиатуры и запрашивает замену, если входные данные имеют значения за пределами от 10 до 40.

Напишите программу на языке Си с отдельной функцией, которая выполняет круговой сдвиг влево элементов чисел массива на n позиций. n-положительное число, и его следует считывать с клавиатуры.

Вот пример ввода:- 11 12 13 14 15 16 17 18 19 20 (int n=) 5 ВЫХОД :- 16 17 18 19 20 11 12 13 14 15

 #include <stdio.h>
//We will take input of numbers from the user
void readValues(int numbers[])
{
    int i;
    for(i=0;i<10;i  )
    {
        int a;
        scanf("%d",amp;a);
        if(a>40 || a<10)
        {
            printf("Please enter a value in range:");//If user puts number greater than 40 or less than 10
            scanf("%d",amp;a);
            numbers[i]=a;
        }
        else
        {
            numbers[i]=a;
        }
    }
}
//now we will put conditions for reversing numbers
int reverse(int numbers[])
{
    int i,j,n;
    int temp=0;
    printf("int n = ");
    scanf("%d",amp;n);
    for(i=0;i<n;i  )
    {
        int b = numbers[0];
        for(j=0;j<10;j  )
        {
            temp = numbers[j];
            numbers[j]=numbers[j 1];
            numbers[j 1]=temp;
        }
        numbers[9]=b;
    }
    for(i=0;i<10;i  )
    {
        printf("%d ",numbers[i]);
    }
}
int main()
{
    int numbers[10];
    readValues(numbers);
    reverse(numbers);
    return 0;
}
 

Мой учитель говорит, что обратная функция не ограничена, но для меня она работает нормально. Пожалуйста, помогите.

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

1. Ваше домашнее задание не важнее, чем чей-либо другой вопрос. Уберите крик из названия.

2. почему это ТАК СРОЧНО? Обратите внимание, что это означает следующее: вы не потрудились приложить к этому усилия, когда у вас было для этого время. Теперь, когда это срочно, зачем нам беспокоиться?

3. «У меня все хорошо» — наиболее распространенное проявление неопределенного поведения. Подумайте об индексации массива и j 1 в течение нескольких минут.

4. Во — первых, как уже было сказано до меня, это не СРОЧНО. Во-вторых, внутри вашего цикла вы получаете доступ к «11-му элементу», когда j равно 10 (из-за numbers[j 1] детали).

5. На всякий случай, если ваш учитель не упомянул об этом, но название reverse -плохое название для функции, которая должна выполнять некоторое вращение чисел.

Ответ №1:

Как уже отмечалось в нескольких комментариях, ваш учитель прав — вы получаете доступ к массиву за пределами — здесь:

     int b = numbers[0];
    for(j=0;j<10;j  )
    {
        temp = numbers[j];
        numbers[j]=numbers[j 1];
        numbers[j 1]=temp;
    }
    numbers[9]=b;
 

Когда j равно 9, утверждение numbers[j]=numbers[j 1]; превращается в numbers[9]=numbers[10]; . Чтение numbers[10] выходит за рамки дозволенного.

… но для меня это прекрасно работает.

Это неопределенное поведение, поэтому может произойти все, что угодно. Причина, по которой это, похоже, работает для вас, заключается в двух вещах. 1) Чтение numbers[10] не привело к сбою программы в вашей системе, а просто ввело какое-то неизвестное значение, numbers[9] и 2) оператор numbers[9]=b; затем ввел ожидаемое значение numbers[9] .

Другими словами — во время выполнения программы данные считывались за пределы, но позже правильное значение было помещено в пункт назначения, так что вы этого никогда не заметили.

кстати

Почему вы меняете значения в цикле? В этом нет необходимости. Чего ты хочешь, так это:

 b = numbers[0];
numbers[0] = numbers[1];
numbers[1] = numbers[2];
...
numbers[8] = numbers[9];
numbers[9] = b;
 

Таким образом, код может быть просто:

     int b = numbers[0];
    for(j=0;j<9;j  )    // Notice the 9 instead of 10
    {
        numbers[j]=numbers[j 1];
    }
    numbers[9]=b;
 

(или даже использовать memmove вместо цикла)

Тем не менее… почему левый сдвиг на один шаг за раз? Вместо этого вы можете избежать внешнего цикла, т. Е. for(i=0;i<n;i ) Переместить элементы в конечное положение в одном цикле , непосредственно перемещая n шаги.

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

1. большое вам спасибо за объяснение , но, к сожалению, это означает отсутствие отметок ;-;

Ответ №2:

Ваш цикл, использующий j переменную, обращается с числами[j 1]. Дважды проверьте свои условия цикла.

Поскольку это домашнее задание, я дам вам только подсказку, а не сделаю это за вас.

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

1. это не домашнее задание, а для ознакомления . Я нашел статью, связанную с этим, которая также решает эту проблему таким же образом tutorialspoint.com/c-program-for-program-for-array-rotation