Использование struct с C и cython - PullRequest
0 голосов
/ 20 августа 2011

Я очень плохо знаком с C. Я хочу написать C-код, который я заверну в Cython.
Это мой C-код (генератор случайных значений на основе начального числа):

#include <math.h>

typedef struct {
    int seed;
    int bits;
    int max;
    double fmax;
    int value;
} rGen;

rGen rGen_Init(int seed, int start, int bits) {
    rGen gen;
    int max = pow(2, bits);
    gen.seed    = seed % max;
    gen.bits    = bits;
    gen.max     = max;
    gen.fmax    = (double) max;
    gen.value   = start % max;
    return gen;
}

double rGen_Next(rGen gen) {
    int value = gen.value;
    value = (gen.seed << gen.bits) * value / (gen.bits + 1);
    value = pow(value, 4);
    value = value % (gen.max - 1);
    gen.value = value;

    return (double) value / gen.fmax;
}

Выполните небольшую проверку, если атрибут value экземпляра rGen действительно изменяется:

#include "pyran.c"
#include <stdio.h>

int main() {
    rGen gen = rGen_Init(1000, 200, 32); // Create an initialized struct-instance
    int i;
    for(i = 0; i < 10; i += 1) {
        rGen_Next(gen);
        printf("%i\n", gen.value);
    }
    return 0;
}

Вывод:

200
200
200
200
200
200
200
200
200
200

Значение атрибута value не изменяется. Почему это ведет себя так? Должен ли я использовать указатели? И если да, то как их использовать?

Ответы [ 2 ]

2 голосов
/ 20 августа 2011

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

double rGen_Next(rGen* gen) {
    int value = gen->value;
    value = (gen->seed << gen->bits) * value / (gen->bits + 1);
    value = pow(value, 4);
    value = value % (gen->max - 1);
    gen->value = value;

    return (double) value / gen->fmax;
}

Назовите это так: rGen_Next(&gen);, если gen - переменная с автоматическим сроком хранения. Кроме того: Хорошей практикой C является наличие функции init, которая принимает указатель на фактически инициализируемый объект. Таким образом, это зависит от пользователя, как распределена структура.

bool rGen_Init(rGen* gen, int seed, int start, int bits) {
    int max = pow(2, bits);
    gen->seed    = seed % max;
    gen->bits    = bits;
    gen->max     = max;
    gen->fmax    = (double) max;
    gen->value   = start % max;

    // omit the return if there is no chance of failure, 
    return true;
}
1 голос
/ 20 августа 2011

Время жизни экземпляра gen, определенного в rGen_init, заканчивается при возврате функции.Вы можете определить функцию rGen_init(struct rGen *gen,...) и изменить параметр gen, используя этот указатель.

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