C: буфер и указатели - PullRequest
       1

C: буфер и указатели

0 голосов
/ 20 декабря 2018

Я пишу небольшую программу, которая должна:

  1. Спросить пользователя, сколько цифр он введет (для динамического добавления на вкладку 2)
  2. Шаг за шагом вводить цифрыи число входит в bufferP, если он положительный, и в bufferN, если отрицательный
  3. Если в буфере больше нет места, удвойте его размер
  4. Наконец printf оба буфера

Вот мой код:

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

int main(){
    int length = 0;
    printf("Number of data: \n");
    scanf("%d", &length);
    int *bufferP = (int*)malloc(2*sizeof(int));
    int *bufferN = (int*)malloc(2*sizeof(int));
    int number = 0;
    for (int i = 0 ; i <= length ; i++){
        scanf("%d", &number);
        if(number < 0){
            if(*bufferN == NULL){
                printf("No more place");
                exit(0);
            }
            *bufferN= number;
            *bufferN++;
        }

        if(number >= 0){
            if(*bufferP == NULL){
                printf("No more place");

            }
            *bufferP = number;
            *bufferP++;
        }

    }

    int res =0;
    printf("tab negative : ");
    for (int i = 0; bufferN[i] != NULL; i++)
    {
        res = bufferN[i]; 
        printf("%d\n", res );
    }
    printf("tab positive : ");
    for (int i = 0; bufferP[i] != NULL; i++)
    {
        res = bufferP[i]; 
        printf("%d\n", res );
    }
}

У меня есть эти ошибки:

 In function ‘main’:
rev_S3_ptr.c:14:16: error: comparison between pointer and integer [-Werror]
    if(*bufferN == NULL){
                ^~
rev_S3_ptr.c:19:4: error: value computed is not used [-Werror=unused-value]
    *bufferN++;
    ^~~~~~~~~~
rev_S3_ptr.c:23:16: error: comparison between pointer and integer [-Werror]
    if(*bufferP == NULL){
                ^~
rev_S3_ptr.c:28:4: error: value computed is not used [-Werror=unused-value]
    *bufferP++;
    ^~~~~~~~~~
rev_S3_ptr.c:35:29: error: comparison between pointer and integer [-Werror]
  for (int i = 0; bufferN[i] != NULL; i++)
                             ^~
rev_S3_ptr.c:41:29: error: comparison between pointer and integer [-Werror]
  for (int i = 0; bufferP[i] != NULL; i++)

Итак, мой вопрос:

  1. Буфер работает как вкладка, верно?Так почему я не могу просто сказать, что если указатель равен нулю, он заполнен и делает * buffer ++?
  2. В поле «Нет больше места» я должен удвоить размер буфера, а я нетзнать, как это сделать.

Ответы [ 4 ]

0 голосов
/ 20 декабря 2018

Давайте начнем с начала:

int *bufferP = (int*)malloc(2*sizeof(int));
int *bufferN = (int*)malloc(2*sizeof(int));

Это правильно, но вы не должны разыгрывать (не используйте (int*)) результат malloc ().Поиск "бросить результат malloc".И кроме того, зачем выделять 2 слота, если вы планируете увеличивать их по мере необходимости?Почему не 10 или 100?Почему не только один?

Давайте продолжим:

if(*bufferN == NULL){
  printf("No more place");
  exit(0);
}

Здесь вы должны рассмотреть буфер N, а не то, на что он указывает.NULL используется для проверки самих указателей, а не значений, указанных указателями;Вот почему компилятор жалуется.В любом случае, обратите внимание, что bufferN никогда не изменит значение само по себе, поэтому не пытайтесь сравнивать его, чтобы понять, заполнен ли буфер.Единственный способ сделать это - подсчитать, сколько предметов вы положили.

Наконец:

        *bufferN= number;
        *bufferN++;

вы правильно сохраните число в месте, указанном указателем.Может быть в порядке.Но в следующей строке вы хотите увеличить указатель, но также разыменовать его.Это не так, но необычно - на самом деле компилятор снова жалуется.

Буфер работает как вкладка, верно?

Неверно.Буфер - это зона памяти, которой вы манипулируете, возможно, с помощью указателей, которыми вы в свою очередь манипулируете.Вы должны отслеживать, что происходит.

В «Нет больше места» я должен удвоить размер буфера, и я не знаю, как это сделать.

Для этого вы используете realloc ().

Я не хочу делать всю работу за вас, но могу объяснить, что вам нужно.Я буду говорить об одном буфере, другой - тот же.

Сначала выделите буфер, как вы делаете сейчас, но для одного слота.И введите счетчик (целое число) для подсчета количества чисел в буфере.Счетчик изначально равен 0.

Когда пользователь вводит число, вы сохраняете его следующим образом:

bufferN[counterN] = number;
counterN++;

На данный момент вы знаете, что буфер заполнен.Мы начали с буфера только с одним (и свободным) слотом, теперь у нас его нет ... почему бы не изменить размер буфера, чтобы снова добавить свободный слот?Мы знаем, что у нас есть counterN элементов в буфере, что буфер заполнен, поэтому мы хотим новый буфер с пазами counterN + 1;realloc () может делать то, что нам нужно.

Обратите внимание, что для чтения и записи в буфере синтаксис bufferN [...] прост и безопасен, потому что теперь вы всегда (через counterN) увеличиваете размер буфера.и сколько предметов в нем содержится.И вы не касаетесь самого указателя.

Есть и другие способы сделать это, но это один - не самый чистый, но разумный.Надеюсь, это поможет.

РЕДАКТИРОВАТЬ: увидев другой ответ, я понял, что требуется удвоить размер буфера .Мое предложение выше не соответствует этому требованию.Извините ... больше работы для вас ... мы (вы) должны учитывать не только элементы, которые добавляются в буфер, но и его размер.Просто еще одна целочисленная переменная для управления.Ну, был бы трюк, чтобы избежать этого, но давайте оставим в покое: -)

0 голосов
/ 20 декабря 2018

В коде есть следующие проблемы:

  1. malloc не вставляет NULL в конце выделенной памяти.Таким образом, проверка if(*bufferN == NULL) не будет работать.Указатель разыменовывает память и, вероятно, получит мусорное значение.
  2. Ошибка rev_S3_ptr.c:14:16: error: comparison between pointer and integer [-Werror] if(*bufferN == NULL){ возникает из-за того, что вы сравниваете адрес значения (*bufferN) с NULL (используется для нулевого адреса).
  3. Код rev_S3_ptr.c:19:4: error: value computed is not used [-Werror=unused-value] *bufferN++; выдает ошибку, поскольку требуется только приращение адреса.Почтение не помогает.
  4. Оператор bufferP[i] означает *(bufferP+i), следовательно, ошибка при сравнении с NULL.
0 голосов
/ 20 декабря 2018

Как насчет этой версии:

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

int main(){
    int length = 0;
    printf("Number of data: \n");
    scanf("%d", &length);
    int bufferP_size = 2, bufferP_loc = 0;
    int *bufferP = (int*)malloc(bufferP_size*sizeof(int));
    int bufferN_size = 2, bufferN_loc = 0;
    int *bufferN = (int*)malloc(bufferN_size*sizeof(int));
    int number = 0;
    for (int i = 0 ; i <= length ; i++) {
        scanf("%d", &number);
        if(number < 0) {
            if(bufferN_loc == (bufferN_size - 1)) {
                int *temp_buffer;
                printf("No more room in negative buffer, extending\n");
                bufferN_size *= 2; 
                temp_buffer = (int*)realloc(bufferN,bufferN_size*sizeof(int));
                if (temp_buffer == NULL) {
                    printf("Memory allocation failed, aborting\n");
                    free(bufferP);
                    free(bufferN);
                    exit(EXIT_FAILURE);
                }
                bufferN = temp_buffer;
            }
            bufferN[bufferN_loc++] = number;
        }

        if(number >= 0) {
            if(bufferP_loc == (bufferP_size - 1)) {
                int *temp_buffer;
                printf("No more room in positive buffer, extending\n");
                bufferP_size *= 2; 
                temp_buffer = (int*)realloc(bufferP,bufferP_size*sizeof(int));
                if (temp_buffer == NULL) {
                    printf("Memory allocation failed, aborting\n");
                    free(bufferP);
                    free(bufferN);
                    exit(EXIT_FAILURE);
                }
                bufferP = temp_buffer;
            }
            bufferP[bufferP_loc++] = number;
        }
    }

    int res =0;
    printf("tab negative : ");
    for (int i = 0; i < bufferN_loc; i++)
    {
        res = bufferN[i]; 
        printf("%d\n", res );
    }
    printf("tab positive : ");
    for (int i = 0; i < bufferP_loc; i++)
    {
        res = bufferP[i]; 
        printf("%d\n", res );
    }
    free(bufferP);
    free(bufferN);
    exit(EXIT_SUCCESS);
}

Существенные изменения:

  • Не выбрасывайте начало указателей буфера при чтении в буфер
  • realloc ваш друг для расширения буфера
  • Вы не можете использовать указатель на буфер, чтобы работать, когда вы достигнете конца буфера, вы должны следить за его размеромсебя
  • Сохраните текущую позицию, а также размер буфера, чтобы вы могли отслеживать, где читать и писать с
0 голосов
/ 20 декабря 2018

Рассмотрим следующие изменения:

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

int main(){
    int length = 0;
    printf("Number of data: \n");
    scanf("%d", &length);

    int bufferP_cap = 2, bufferN_cap = 2;
    int bufferP_size = 0, bufferN_size = 0;
    int* bufferP = (int*)malloc(bufferP_cap * sizeof(int));
    int* bufferN = (int*)malloc(bufferN_cap * sizeof(int));

    int number = 0;
    for (int i = 0 ; i < length ; i++){  // '<' instead of '<='
        scanf("%d", &number);
        if(number < 0){
            if ( bufferN_size == bufferN_cap){
                bufferN_cap *= 2;
                bufferN = (int*)realloc(bufferN, sizeof(int)*bufferN_cap);
            }
            bufferN[bufferN_size++] = number;
        }
        else {
            if ( bufferP_size == bufferP_cap){
                bufferP_cap *= 2;
                bufferP = (int*)realloc(bufferP, sizeof(int)*bufferP_cap);
            }
            bufferP[bufferP_size++] = number;
        }
    }

    printf("tab negative : ");
    for (int i = 0; i < bufferN_size; i++)
        printf("%d\n", bufferN[i]);

    printf("tab positive : ");
    for (int i = 0; i < bufferP_size; i++)
        printf("%d\n", bufferP[i]);

    free(bufferN);
    free(bufferP);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...