Различные аргументы realloc и malloc.




При вызове функции malloc, realloc и calloc с нулевым размером поведение не определено. Это значит, что может быть возвращён как NULL, так и реальный адрес. Им можно пользоваться, но к нему нельзя применять операцию разадресации.
Вызов realloc(NULL, size_t) эквиваленте вызову malloc(size_t).
Однако, вызов realloc(NULL, 0) не эквивалентен вызову malloc(0):) Понимайте это, как хотите.

Примеры

1. Простое скользящее среднее равно среднему арифметическому функции за период n. Пусть у нас имеется ряд измерений значения функции. Часто эти измерения из-за погрешности "плавают" или на них присутствуют высокочастотные колебания. Мы хотим сгладить ряд, для того, чтобы избавиться от этих помех, или для того, чтобы выявить общий тренд. Самый простой способ: взять n элементов ряда и получить их среднее арифметическое. n в данном случае - это период простого скользящего среднего. Так как мы берём n элементов для нахождения среднего, то в результирующем массиве будет на n чисел меньше.

Скользящее среднее.

Пусть есть ряд
1, 4, 4, 6, 7, 8, 9, 11, 12, 11, 15
Тогда если период среднего будет 3, то мы получим ряд
(1+4+4)/3, (4+4+6)/3, (4+6+7)/3, (6+7+8)/3, (7+8+9)/3, (8+9+11)/3, (9+11+12)/3, (11+12+11)/3, (12+11+15)/3
Видно, что сумма находится в "окне", которое скользит по ряду. Вместо того, чтобы каждый раз в цикле находить сумму, можно найти её для первого периода, а затем вычитать из суммы крайнее левое значение предыдущего периода и прибавлять крайнее правое значение следующего.
Будем запрашивать у пользователя числа и период, а затем создадим новый массив и заполним его средними значениями.

?

  #include <conio.h> #include <stdio.h> #include <stdlib.h>   #define MAX_INCREMENT 20   void main() { //Считанные числа float *numbers = NULL; //Найденные значения float *mean = NULL; float readNext; //Максимальный размер массива чисел unsigned maxSize = MAX_INCREMENT; //Количество введённых чисел unsigned curSize = 0; //Строка для считывания действия char next[2]; //Шаг unsigned delta; //float переменная для хранения шага float realDelta; unsigned i, j; //Сумма чисел float sum;   numbers = (float*) malloc(maxSize * sizeof(float)); do { //Пока пользователь вводит строку, которая начинается с y или Y, //то продолжаем считывать числа printf("next? [y/n]: "); scanf("%1s", next); if (next[0] == 'y' || next[0] == 'Y') { printf("%d. ", curSize); scanf("%f", &readNext); if (curSize >= maxSize) { maxSize += MAX_INCREMENT; numbers = (float*) realloc(numbers, maxSize * sizeof(float)); } numbers[curSize] = readNext; curSize++; } else { break; } } while(1);   //Считываем период, он должен быть меньше, чем //количество элементов в массиве. Если оно равно, //то результатом станет среднее арифметическое всех введённых чисел do { printf("enter delta (>=%d): ", curSize); scanf("%d", &delta); if (delta <= curSize) { break; } } while(1); realDelta = (float) delta;   //Находим среднее для первого периода mean = (float*) malloc(curSize * sizeof(float)); sum = 0; for (i = 0; i < delta; i++) { sum += numbers[i]; }   //Среднее для всех остальных mean[0] = sum / delta; for (i = delta, j = 1; i < curSize; i++, j++) { sum = sum - numbers[j-1] + numbers[i]; mean[j] = sum / realDelta; }   //Выводим. Чисел в массиве mean меньше на delta curSize = curSize - delta + 1; for (i = 0; i < curSize; i++) { printf("%.3f ", mean[i]); }   free(numbers); free(mean); getch(); }

Это простой пример. Большая его часть связана со считыванием данных, вычисление среднего всего в девяти строчках.

2. Сортировка двумерного массива. Самый простой способ сортировки - перевести двумерный массив MxN в одномерный размером M*N, после чего отсортировать одномерный массив, а затем заполнить двумерный массив отсортированными данными. Чтобы не тратить место под новый массив, мы поступим по-другому: если проходить по всем элементам массива k от 0 до M*N, то индексы текущего элемента можно найти следующим образом:
j = k / N;
i = k - j*M;
Заполним массив случайными числами и отсортируем

?

  #include <conio.h> #include <stdio.h> #include <stdlib.h> #include <time.h>   #define MAX_SIZE_X 20 #define MAX_SIZE_Y 20   void main() { int **mrx = NULL; int tmp; unsigned i, j, ip, jp, k, sizeX, sizeY, flag;   printf("cols: "); scanf("%d", &sizeY); printf("rows: "); scanf("%d", &sizeX);   //Если введённый размер больше MAX_SIZE_?, то присваиваем //значение MAX_SIZE_? sizeX = sizeX <= MAX_SIZE_X? sizeX: MAX_SIZE_X; sizeY = sizeY <= MAX_SIZE_Y? sizeY: MAX_SIZE_Y;   //Задаём начальное значение для генератора псевдослучайных чисел srand(time(NULL)); //Выделяем память под массив указателей mrx = (int**) malloc(sizeX * sizeof(int*)); for (i = 0; i < sizeX; i++) { //Выделяем память под строку и сразу же заполняем элементы //случайными значениями mrx[i] = (int*) malloc(sizeY * sizeof(int)); for (j = 0; j < sizeY; j++) { mrx[i][j] = rand(); } }   //Выводим массив for (i = 0; i < sizeX; i++) { for (j = 0; j < sizeY; j++) { printf("%6d ", mrx[i][j]); } printf("\n"); }   //Сортируем пузырьком, обходя все sizeX*sizeY элементы do { flag = 0; for (k = 1; k < sizeX * sizeY; k++) { //Вычисляем индексы текущего элемента j = k / sizeX; i = k - j*sizeX; //Вычисляем индексы предыдущего элемента jp = (k-1) / sizeX; ip = (k-1) - jp*sizeX; if (mrx[i][j] > mrx[ip][jp]) { tmp = mrx[i][j]; mrx[i][j] = mrx[ip][jp]; mrx[ip][jp] = tmp; flag = 1; } } } while(flag);   printf("-----------------------\n"); for (i = 0; i < sizeX; i++) { for (j = 0; j < sizeY; j++) { printf("%6d ", mrx[i][j]); } free(mrx[i]); printf("\n"); } free(mrx);   getch(); }

3. Бином Ньютона. Создадим треугольную матрицу и заполним биномиальными коэффициентами

?

  #include <conio.h> #include <stdio.h> #include <stdlib.h>   #define MAX_BINOM_HEIGHT 20   void main() { int** binom = NULL; unsigned height; unsigned i, j;   printf("Enter height: "); scanf("%d", &height); height = height <= MAX_BINOM_HEIGHT? height: MAX_BINOM_HEIGHT;   binom = (int**) malloc(height * sizeof(int*)); for (i = 0; i < height; i++) { binom[i] = (int*) malloc((i + 1) * sizeof(int)); }   binom[0][0] = 1; for (i = 1; i < height; i++) { binom[i][0] = binom[i][i] = 1; for (j = i - 1; j > 0; j--) { binom[i][j] = binom[i-1][j-1] + binom[i-1][j]; } }   for (i = 0; i < height; i++) { for (j = 0; j <= i; j++) { printf("%4d ", binom[i][j]); } free(binom[i]); printf("\n"); } free(binom);   getch(); }

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-02-16 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: