C/С++ для программиста Python
Мне нужно переключиться с Python на C/С++.
Знаете ли вы быстрый "справочный учебник" или что-то в этом роде, чтобы иметь ссылку на то, как начать? Например, что-то вроде уроков Numpy и Scipy.
Я прочитал много "документации", например
- С++ для чайников
- Язык программирования K & R C
- много блога и онлайн-документации, например: http://eli.thegreenplace.net/2010/01/11/pointers-to-arrays-in-c/,
- http://newdata.box.sk/bx/c/
- тон Q & A здесь, на StackOverflow
- ...
но мне все еще не ясно, как начать портировать на C/С++ что-то вроде:
#!/usr/bin/env python
import time
import numpy as np
import tables as tb
"""Retrieve 3D positions form 1000 files and store them in one single HDF5 file.
"""
t = time.time()
# Empty array
sample = np.array([])
sample.shape = (0,3)
# Loop over the files
for i in range(0, 1000):
filename = "mill2sort-"+str(i)+"-extracted.h5"
print "Doing ", filename
# Open data file
h5f = tb.openFile(filename, 'r')
# Stack new data under previous data
sample = np.vstack((sample, h5f.root.data.read()))
h5f.close()
# Create the new file
h5 = tb.openFile("mill2sort-extracted-all", 'w')
# Save the array
h5.createArray(h5.root, 'data', sample, title='mill_2_sub_sample_all')
h5.flush()
h5.close()
print "Done in ", time.time()-t, " seconds."
в C или С++. В этом примере я даже не мог понять, как передать 3D-массив функции, которая находит ее размеры, что-то вроде
int getArrayDimensions(int* array, int *dimensions){
*dimensions = sizeof(*array)/sizeof(array[0]);
return 0;
}
С массивом
int array[3][3][3] = ...
Спасибо за любое предложение!:)
Ответы
Ответ 1
ОК, для этого конкретного примера:
- вы можете получить службы времени из стандартной библиотеки здесь
- вы можете использовать eigen для линейной алгебры. Это потрясающая библиотека, я в нее влюблен.
- проверьте здесь, чтобы узнать, как управлять файлами
При использовании С++ вы можете пропустить некоторые функции из python, но большинство из них фактически предоставляются библиотеками boost. Например, возвращение нескольких значений из функции очень просто с помощью boost.tuple библиотеки, как в . Вы можете использовать boost:: shared_ptr, если вы не хотите беспокоиться о том, как управлять памятью. Или если вы хотите использовать python для игры с вашими классами С++, вы можете использовать boost.python. Boost.parameter помогает вам определять функции с именованными аргументами. Существует также Boost.lambda для лямбда-функций, но если ваша среда поддерживает его, вы также можете использовать С++ 11 для поддержки языка лямбда функции. Boost - это золотая жила, никогда не прекращайте копать. Предположим, что это часть стандартной библиотеки. Я разрабатываю С++ на разных платформах, и ни один из них, ни boost не подвели меня.
Здесь хороший FAQ для лучших практик С++. Это - очень важный принцип, который вы должны постоянно помнить, работая на С++. Я продюсирую его немного, подумал и подумал; Если вы собираетесь сделать что-то опасное, например: выделить память с помощью raw new
или индексировать массив исходных типов C, пропустить необработанные указатели или сделать static_cast
(даже хуже reinterpret_cast
) и т.д. Они должны как правило, происходят в классе, каким-то образом посвященным им, и код, чтобы убедиться, что они не создают проблем с жизнями, близкими к ним, так что вы можете сразу увидеть, что все под контролем.
Наконец, мой любимый!!! Вы хотите продолжать использовать генераторы в С++? Здесь какая-то темная магия.
Ответ 2
Хорошо, давайте просто начнем с C на данный момент.
void readH5Data(FILE *file, int ***sample); // this is for you to implement
void writeH5Data(FILE *file, int ***sample); // this is for you to implement
int main(int argc, const char *argv[])
{
#define width 3
#define height 3
#define depth 3
time_t t = time(NULL);
int ***sample = calloc(width, sizeof(*sample));
for (int i = 0; i < width; i++)
{
sample[i] = calloc(height, sizeof(**sample));
for (int j = 0; j < height; j++)
{
sample[i][j] = calloc(depth, sizeof(***sample));
}
}
for (int i = 0; i < 1000; i++)
{
char *filename[64];
sprintf(filename, "mill2sort-%i-extracted.h5", i);
// open the file
FILE *filePtr = fopen(filename, "r");
if (filePtr == NULL || ferror(filePtr))
{
fprintf(stderr, "%s\n", strerror(errno));
exit(EXIT_FAILURE);
}
readH5Data(filePtr, sample);
fclose(filePtr);
}
char filename[] = "mill2sort-extracted-all";
FILE *writeFile = fopen(filename, "w");
if (writeFile == NULL || ferror(writeFile))
{
fprintf(stderr, "%s\n", strerror(errno));
exit(EXIT_FAILURE);
}
writeH5Data(writeFile, sample);
fflush(writeFile);
fclose(writeFile);
printf("Done in %lli seconds\n", (long long int) (time(NULL) - t));
for (int i = 0; i < width; i++)
{
for (int j = 0; j < width; j++)
{
free(sample[i][j]);
}
free(sample[i]);
}
free(sample);
}
До тех пор, пока вы помните, что ваш массив равен 3x3x3, у вас не должно быть проблем с превышением границ в методе writeH5Data.
Ответ 3
Этот вопрос становится довольно старым, но вот несколько ссылок, которые мне были полезны:
Руководство по переходу: Python на С++ (pdf)
Краткое введение в С++ для программистов на Python (неполное, но неплохое)