2012-03-22 5 views
10

Мне нужно переключиться с Python на C/C++.
Знаете ли вы быстрый «справочный учебник» или что-то в этом роде, чтобы иметь ссылку на то, как начать? Например, что-то вроде уроков Numpy и Scipy.
Я прочитал много «документации», напримерC/C++ для программиста Python

  • C++ для чайников
  • K & R C Язык программирования
  • много блога и онлайн-документации, такой как: HTTP: // эли. thegreenplace.net/2010/01/11/pointers-to-arrays-in-c/,
  • http://newdata.box.sk/bx/c/
  • тонн Q & A здесь, на StackOverflow
  • ...

, но это все еще не ясно, мне даже как начать делать перенос на C/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 или C++. В этом примере я даже не был в состоянии понять, как передавать 3D-массив в функцию, найти его размеры, что-то вроде

int getArrayDimensions(int* array, int *dimensions){ 
    *dimensions = sizeof(*array)/sizeof(array[0]); 
    return 0; 
} 

с массивом будучи

int array[3][3][3] = ... 

Спасибо за любые предложения !:)

+2

Выберите один: C или C++. «C/C++» не существует. С ++ легче учиться, чем C, на мой взгляд. –

+2

@daknok_t Я сомневаюсь в этом. C++ очень эффективен в использовании, как только вы это хорошо знаете, но это один из самых трудных для изучения. – enobayram

+0

@daknok_t: Я еще не решил между C или C++, поэтому написал «C/C++»! но какой из них лучше подходит мне, это еще один вопрос! – brunetto

ответ

5

Хорошо, давайте начнем с 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».

+1

Я бы просто заметил, что Ричард вызывает 'calloc()' три отдельных раза: 'sample' - это массив указателей (внешний' calloc'), каждый из которых указывает на массив указателей (средний 'calloc'), каждый из которых указывает на массив 'int' (внутренний 'calloc'). Когда я впервые начал с C, у меня была бумага повсюду, где я набросал блоки памяти, чтобы разобрать то, что указывало на что. Кроме того, если вам действительно нужен размер массива, в большинстве случаев вам придется не отставать от него при создании массива. C не знает, где массивы «заканчиваются», в общем, поэтому 'sizeof()' не работает. –

+2

Спасибо за ответ, я изучу его, но я искал «ссылку», что-то вроде https://www.cfa.harvard.edu/~jbattat/computer/python/science/idl-numpy. HTML. Хорошо, на самом деле это не «таблица преобразования», а что-то вроде «в C/C++ - это хорошая практика для управления массивами таким образом, чтобы передать их таким образом, и если вам нужно сделать что-то часто необходимо», вы должны сделать это » ! – brunetto

+2

Чтобы быть более ясным, я ищу «цифровую ссылку» (но не «числовые рецепты»). После того, как я прочитал много теории, я до сих пор не знаю, как начать быть продуктивным, у меня нет ссылок на то, как делать простые, «стандартные» и повседневные вещи, например манипулировать многомерными массивами и передавать их функциям. После стольких лет программирования C/C++ в мире я думаю, что будут «стандартные» общие знания, которые предлагают «Чтобы выполнять <повседневные операции>, вы должны сделать это» , поэтому мне не нужно изобретать колесо, массивы манипуляции и так далее. Я искал что-то вроде этого :) :) – brunetto

7

OK, для этого конкретного примера:

  • вы можете получить время службы из стандартной библиотеки here
  • вы можете использовать eigen для линейной алгебры. Это потрясающая библиотека, я в нее влюблен.
  • проверка here, чтобы узнать, как работать с файлами

При использовании C++, вы можете пропустить некоторые функции из питона, но большинство из них на самом деле обеспечиваются boost библиотек. Например, возвращение нескольких значений из функции очень просто с библиотекой boost.tuple, как в here. Вы можете использовать boost::shared_ptr, если не хотите беспокоиться об управлении памятью. Или, если вы хотите использовать python для игры с вашими классами C++, вы можете использовать boost.python. Boost.parameter помогает вам определять функции с именованными аргументами. Существует также Boost.lambda для лямбда-функций, но если ваша среда поддерживает его, вы также можете использовать C++ 11 для поддержки языка для лямбда-функций. Boost - это золотая жила, никогда не прекращайте копать. Предположим, что это часть стандартной библиотеки. Я разрабатываю C++ на многих разных платформах, и ни один из них, ни импульс еще не подвели меня.

Here является хорошим часто задаваемым вопросом для лучших практик C++.This - очень важный принцип, который вы должны иметь в виду во все времена, работая на C++. Я продюсирую его немного, подумал и подумал; Если вы собираетесь сделать что-то опасное, например: выделить память с необработанным new или индексировать массив исходных типов C, пропустить необработанные указатели или сделать static_cast (еще хуже reinterpret_cast) и т. Д. Обычно они должны происходить в классе как-то посвященный им, и код, чтобы убедиться, что они не создают проблем с жизнями, очень близкими им, так что вы можете сразу увидеть, что все под контролем.

И, наконец, мой любимый !!! Вы хотите продолжать использовать генераторы в C++? Here - некоторая темная магия.

+0

но темная магия недействительна C++. –

+0

это, я использую его на регулярной основе, на регулярном компиляторе C++ (gcc). Подумайте об этом, я даже использовал его на основе армейского проекта! (Android NDK) – enobayram

+0

Я второй это. Используйте C++ (или, даже лучше, C++ 11) вместо C, так как он ближе к Python. Используйте Boost, чтобы делать все, с чем вы привыкли, от Python, например, лямбда-функций. Никогда не используйте raw-указатели - используйте std :: string, std :: vector и shared_ptr. – Gurgeh

Смежные вопросы