как нарезать массив в c - PullRequest
       11

как нарезать массив в c

0 голосов
/ 07 марта 2020

Мне интересно, возможно ли получить часть массива в c с нарезкой списка. В python это может быть сделано в следующем коде. Мне нравится делать это в c.

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
b = a[3:5]
print(b)

Output: [4, 5]

Ответы [ 5 ]

1 голос
/ 07 марта 2020

Ну, вы могли бы начать с чего-то вроде следующего:

// Get half-open range of values from array (includes first index,
// excludes last). Parameter 'source' is the source array, 'from'
// and 'to' are the range ends, and `target` is the destination
// buffer. If you provide buffer, make sure it's big enough. If
// you pass in NULL, a buffer will be allocated for you.
// Will return buffer address or NULL if either range is invalid
// or memory could not be allocated.

int *sliceIntArray(int *source, int from, int to, int *target) {
    // Invalid, return null.

    if (to <= from) {
        return NULL;
    }

    // Only allocate if target buffer not given by caller.

    if (target == NULL) {
        target = malloc((to - from) * sizeof(int));
        if (target == NULL) {
            return NULL;
        }
    }

    // Copy the data and return it.

    memcpy(target, &(source[from]), (to - from) * sizeof(int));

    return target;
}

Это позволит вам передать буфер, если он у вас уже есть, или выделит его для вас, если вы не делаете (что вам понадобится free() в какой-то момент):

int naturals[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};

int slice1[2];
sliceIntArray(naturals, 3, 5, slice1);
// Use slice1 for whatever nefarious purpose you have :-)

int *slice2 = sliceIntArray(naturals, 3, 5, NULL);
// Use slice2 similarly, just make sure you free it when done.
free(slice2);
0 голосов
/ 07 марта 2020

В короткой простой функции:

int* slice(int a[], size_t start, size_t end)
{
    return memcpy(malloc(sizeof(int)*(end-start)), a+start, sizeof(int)*(end-start));
}

Пример использования:

#include <stdio.h>

int main(void) {
    int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int *b = slice(a,3,5);

    for(int i=0; i<2; ++i)
    {
        printf("b[%d] = %d\n", i, b[i]);
    }
    return 0;
}

Выход:

b[0] = 4
b[1] = 5
0 голосов
/ 07 марта 2020

Вы можете использовать структуру в качестве обёртки массива в функции слайса. Таким образом, вы можете вернуть извлеченный фрагмент из функции, не беспокоясь о malloc и free для динамического c выделения памяти. Вот базовый c набросок.

#define MAX 100

typedef struct{ 
    int myarr[MAX];
    int mysize;
} wrapper;

wrapper slice(const int* arr, int size, int include, int exclude) {
    wrapper result = { .myarr = {0}, .mysize = 0 };
    if (include >= 0 && exclude <= size) {
        int count = 0;
        for (int i = include; i < exclude; i++) {
            result.myarr[count] = arr[i];
            count++;
        }
        result.mysize = exclude - include;
        return result;
    }
    else {
        printf("Array index out-of-bounds\n");
        result.mysize = -1;
        return result;
    }
} 

Затем его можно вызвать для любого массива следующим образом:

    int source[10] = {0,1,2,3,4,5,6,7,8,9};  
    wrapper s = slice(source, 10, 5, 10);

Для реализации полного * потребуется совсем немного работы 1012 * функциональность среза, хотя (здесь нет третьего члена для установки размера шага, а также не реализованы различные отрицательные значения).

0 голосов
/ 07 марта 2020

Вам нужно будет сделать свой собственный, в C чаще, чем не в этом случае.

void subset( int *arr, int begin, int end, int *new_array){   
    for(int i = 0; i < end - begin; i++)
        new_array[i] = arr[begin + i]; 
}

Живой образец здесь

Это альтернатива memcopy, уже показанная в других ответах.

0 голосов
/ 07 марта 2020

Нет, вы не можете.

Вы можете создать новый массив и скопировать его, однако:

int src[10] = { ... };
int dest[3];
memcpy(dest, src + 3, sizeof(src[0]) * 2);
...