Tag Archives: C

C এর সাথে Python প্রোগ্রামিং এক্সটেনশন (Python Extension Programming with C)

Huge Sell on Popular Electronics

C এর সাথে Python প্রোগ্রামিং এক্সটেনশন

C, C++ অথবা Java প্রোগ্রামিং এর যেকোন কোড Python script এর সাথে ইন্টেগ্রেট/ রূপান্তর করা যায়, যাকে Python এক্সটেনশন বলে। Python এক্সটেনশন ফাইলগুলো স্বাভাবিক C লাইব্রেরীর মত, Unix অপারেটিং সিস্টেম এ .so ফরম্যাট ও Windows মেশিনে.dll ফরম্যাটের হয়।

 

এক্সটেনশন লেখার পূর্বশর্ত

Python এক্সটেনশন লিখতে হলে Python হেডার ফাইল এর দরকার পড়ে Unix মেশিনে এসব ক্ষেত্রে python2.5-dev নামক একটি প্যাকেজ ইনস্টল করার দরকার হয়। Windows মেশিনে অবশ্য এই হেডার ফাইল গুলো বাইনারি Python ইনস্টলার প্যাকেজের সাথেই থাকে।

প্রথম দিকে Python extension মোডিউল তৈরি করতে হলে কোডটিতে চার ধরনের ফাইল সাজাতে হবে। যেমন,

  • হেডার ফাইলh.
  • C ফাংশন functions (যেগুলো মোডিউল এর ইন্টারফেস হিসেবে ব্যবহৃত হবে)।
  • ফাংশনের একটি টেবিল (Python developer দের জন্য দরকার)
  • একটি ইনিশিয়ালাইজেশন ফাংশন

 

হেডার ফাইল Python.h

Python API এ ঢোকার জন্য Python.h হেডার ফাইলটিকে C সোর্স ফাইল এর অন্তর্গত করে Python ইন্টারপ্রেটার এর সাথে এক্সটেনশন মোডিউল ইন্টেগ্রেট করতে হবে। C ফাংশনগুলো নিচের তিন রকমের হতে পারে।


static PyObject *MyFunction( PyObject *self, PyObject *args );

static PyObject *MyFunctionWithKeywords(PyObject *self,
                                 PyObject *args,
                                 PyObject *kw);

static PyObject *MyFunctionWithNoArgs( PyObject *self );

 

প্রতিটি স্টেটমেন্টই ফলাফল হিসেবে একটি Python object দিবে। Python এ C এর মত কোন ভয়েড ফাংশন নেই। ভয়েড এর ক্ষেত্রে, Python এর Nonevalue’র সমতুল্য C value পাওয়া যাবে। Python headers গুলো এই কাজ করার জন্য Py_RETURN_NONE নামের ম্যাক্রো ফাইল ঠিক করে।

এ ধরনের Python এক্সটেনশনে ব্যবহৃত C ফাংশন গুলোকে স্ট্যাটিক (স্থিতিশীল) ফাংশন বলে, কারন এক্সটেনশন মোডিউলের বাইরে এদের কোন ব্যবহার নেই। Python মোডিউল ও Python ফাংশন গুলোর নাম একত্রিত করে C ফাংশনের নামগুলো ঠিক করা হয়। নিচের উদাহরণটিক লক্ষ্য করি,


static PyObject *module_func(PyObject *self, PyObject *args) {
/* Do your stuff here. */
Py_RETURN_NONE;
}


 

এই Python ফাংশনটির নাম func,  এবং এটি module নামক মোডিউল এর ভেতর অবস্থিত।

 

Method Mapping Table (মেথড ম্যাপিং টেবিল)

মেথড টেবিল হচ্ছে নিচের PyMethodDef স্ট্রাকচারের একটি সাধারণ বিন্যাস (array)।

struct PyMethodDef {   char *ml_name;   PyCFunction ml_meth;   int ml_flags;   char *ml_doc;};

নিচে এই স্ট্রাকচারের সদস্য গুলোর বর্ননা দেয়া হলঃ

  • ml_name:Python ইন্টারপ্রেটার প্রোগ্রামে ব্যবহৃত হবার সময় যেই নাম ব্যবহার করে।
  • ml_meth:ফাংশনের লোকেশন।
  • ml_flags:এটা ইন্টারপ্রেটারকে ধারণা দেয় যে, ml_meth কোন সংকেতটি ব্যবহার করছে (METH_VARARGS, METH_KEYWORDS কিংবা METH_NOARGS)
  • ml_doc: ফাংশনের docstring, প্রোগ্রামার কোন কিছু না লেখলে এটা বাদ যাবে।

উপযুক্ত মেম্বারগুলোর জন্য, এই টেবিলটি একটি শূন্য মানের সেন্টিনেল (sentinel) এর সাহায্যে বাতিল করতে হবে। উদাহরন হিসেবে, উপরের ফাংশনের জন্য, নিচের মেথড ম্যাপিং টেবিলটি সম্ভবঃ


static PyMethodDef module_methods[] = {
   { "func", (PyCFunction)module_func, METH_NOARGS, NULL },
   { NULL, NULL, 0, NULL }
};

 

ইনিশিয়ালাইজেশন ফাংশনঃ

এক্সটেনশন মোডিউলের সর্বশেষ অংশ হচ্ছে ইনিশিয়ালাইজেশন ফাংশন। মোডিউল লোড হবার পড়ে Python ইন্টারপ্রেটার এই ফাংশনটি ব্যবহার করে। এই ফাংশনের নামকরন initModule আকারের হয় (Module হচ্ছে মোডিউলটির নাম)।।

আপনি যেই লাইব্রেরী তৈরি করবেন সেটা থেকেই ইনিশিয়ালাইজেশন ফাংশন এক্সপোর্ট করা হবে। Python হেডার ফাইল গুলো PyMODINIT_FUNC ফাংশনের সাহায্যে কম্পাইলেশনের সময় বিভিন্ন পরিস্থিতি অনুযায়ী এই এক্সপোর্টটি করে থাকে। সেক্ষেত্রে আপনাকে এটি ফাংশন সংজ্ঞায়িত করার সময় ব্যবহার করতে হবে। C ইনিশিয়াল ফাংশন সাধারণত নিচের কাঠামো অনুযায়ী হয়ঃ


PyMODINIT_FUNC initModule() {
   Py_InitModule3(func, module_methods, "docstring...");
}

 

এখানে, Py_InitModule3 ফাংশনের ৩টি মেম্বার হচ্ছে−

  • func: যে ফাংশনটি এক্সপোর্ট করা হবে।
  • module_methods:ম্যাপিং টেবিলের নাম।
  • docstring: এক্সটেনশনে ব্যবহৃত কমেন্ট।

যেমন,


#include <Python.h>

static PyObject *module_func(PyObject *self, PyObject *args) {
   /* Do your stuff here. */
   Py_RETURN_NONE;
}

static PyMethodDef module_methods[] = {
   { "func", (PyCFunction)module_func, METH_NOARGS, NULL },
   { NULL, NULL, 0, NULL }
};

PyMODINIT_FUNC initModule() {
   Py_InitModule3(func, module_methods, "docstring...");
}

 

নিচের উদাহরণটি উপরের কনসেপ্ট গুলোর আরেকটি প্রয়োগঃ


#include <Python.h>

static PyObject* helloworld(PyObject* self)
{
    return Py_BuildValue("s", "Hello, Python extensions!!");
}

static char helloworld_docs[] =
    "helloworld( ): Any message you want to put here!!\n";

static PyMethodDef helloworld_funcs[] = {
    {"helloworld", (PyCFunction)helloworld, 
     METH_NOARGS, helloworld_docs},
    {NULL}
};

void inithelloworld(void)
{
    Py_InitModule3("helloworld", helloworld_funcs,
                   "Extension module example!");
}

 

এখানে Py_BuildValue ফাংশনটি Python এর মান (value) তৈরি করে। উপরের কোডটি hello.c ফাইল এ সেভ করুন. এখন আমরা দেখবো কিভাবে Python script এর এই মোডিউলটিকে ইনস্টল ও কম্পাইল করা যায়।

 

এক্সটেনশন তৈরি ও ইন্সটল করাঃ

distutils প্যাকেজ এর সাহায্যে সহজেই Python এর অরিজিনাল মোডিউল ও এক্সটেনশন সঠিকভাবে বন্টন করা যায়। মোডিউল গুলো সোর্স আকারে ভাগ করা থাকে, এবং setup.py  এর সাহায্যে তৈরি ও ইন্সটল করা হয়। উপরের মোডিউলটির জন্য নিম্নোক্ত setup.py স্ক্রিপ্টটি তৈরি করতে হবে।


from distutils.core import setup, Extension
setup(name='helloworld', version='1.0',  \
      ext_modules=[Extension('helloworld', ['hello.c'])])

 

এখন নিচের কমান্ডটি প্রয়োগ করলে তা সঠিক কম্পাইলার, লিঙ্কার কমান্ড এবং ফ্ল্যাগ এর সাহায্যে প্রয়োজনীয় কম্পাইলেশন, সংযোজন করবে, ও সঠিক ডিরেক্টরিতে ফলাফলস্বরূপ ডাইনামিক লাইব্রেরী কপি করবে ।


$ python setup.py install

 

Unix সিস্টেমে আপনাকে রুট হিসেবে এই কমান্ডটি রান করাতে হবে যাতে করে সাইট-প্যাকেজ ডিরেক্টরি তে লেখার পারমিশন থাকে। Windows এর জন্য অবশ্য এটি কোন সমস্যা না।

 

Importing Extensions

একবার এক্সটেনশন ইন্সটল করা হলে, আপনি সেই এক্সটেনশন Python স্ক্রিপ্টে এভাবে ইম্পোর্ট করতে পারবেন।


#!/usr/bin/python
import helloworld

print helloworld.helloworld()

 

এই মডেলটি নিচের ফলাফল দিবে।


Hello, Python extensions!!

 

 

Passing Function Parameters

যেহেতু আপনি এমন ফাংশন চান যেটা আর্গুমেন্ট গ্রহণ করতে পারে, তাই নিচের যেকোনো C function ব্যবহার করতে পারেন। উদাহরণস্বরূপ, নিচের ফাংশনটি এমনভাবে সংজ্ঞায়িত করা যেতে পারে,


static PyObject *module_func(PyObject *self, PyObject *args) {
   /* Parse args and do something interesting here. */
   Py_RETURN_NONE;
}

 

নতুন ফাংশনের জায়গা সম্বলিত মেথড টেবিলটি এমন হবেঃ


static PyMethodDef module_methods[] = {
   { "func", (PyCFunction)module_func, METH_NOARGS, NULL },
   { "func", module_func, METH_VARARGS, NULL },
   { NULL, NULL, 0, NULL }
};

 

C ফাংশনের PyObject থেকে আর্গুমেন্ট এক্সট্রাক্ট করার জন্য API PyArg_ParseTuple ফাংশনটি ব্যবহার করতে পারেন। PyArg_ParseTuple এর প্রথম আর্গুমেন্টটি হচ্ছে args আর্গুমেন্ট। এই অবজেক্টটিকে আপনি parsing করবেন। দ্বিতীয় আর্গুমেন্টটি হবে এমন একটি ফরম্যাট স্ট্রিং যেটা আপনি যেভাবে আর্গুমেন্ট গুলো চান সেভাবে বর্ননা করবে। প্রতিটি আর্গুমেন্ট ফরম্যাট স্ট্রিং এর এক বা একাধিক ক্যারেক্টার দ্বারা প্রকাশিত।


static PyObject *module_func(PyObject *self, PyObject *args) {
   int i;
   double d;
   char *s;

   if (!PyArg_ParseTuple(args, "ids", &i, &d, &s)) {
      return NULL;
   }
   
   /* Do something interesting here. */
   Py_RETURN_NONE;
}

 

নতুন মোডিউলের ভার্সন কম্পাইল ও ইম্পোর্ট করলে নতুন ফাংশনে যেকোনো ধরনের যেকোনো সংখ্যক আর্গুমেন্ট সংযুক্ত করা যায়। যেমন,


module.func(1, s="three", d=2.0)
module.func(i=1, d=2.0, s="three")
module.func(s="three", d=2.0, i=1)


এখানে আপনি আপনার প্রয়োজন মত আরও বৈচিত্র আনতে পারেন।

PyArg_ParseTuple  ফাংশন

PyArg_ParseTuple ফাংশনের স্ট্যান্ডার্ড সিগ্নেচার হচ্ছেঃ


int PyArg_ParseTuple(PyObject* tuple,char* format,...)

 

এই ফাংশনটি ভুল হলে ০ মান আসবে, আর সঠিক হলে শূন্য ছাড়া অন্য কোন মান আসবে। এখানে tuple হচ্ছে PyObject*, যা C ফাংশনের দ্বিতীয় আর্গুমেন্ট, এবং format হচ্ছে একটি C স্ট্রিং, যা আবশ্যিক (mandatory) ও ঐচ্ছিক (optional) আর্গুমেন্ট গুলো বর্ননা করে।

নিচে PyArg_ParseTuple ফাংশনের ফরম্যাট কোড গুলো দেয়া হলঃ

Code C type Meaning
c char A Python string of length 1 becomes a C char.
d double A Python float becomes a C double.
f float A Python float becomes a C float.
i int A Python int becomes a C int.
l long A Python int becomes a C long.
L long long A Python int becomes a C long long
O PyObject* Gets non-NULL borrowed reference to Python argument.
s char* Python string without embedded nulls to C char*.
s# char*+int Any Python string to C address and length.
t# char*+int Read-only single-segment buffer to C address and length.
u Py_UNICODE* Python Unicode without embedded nulls to C.
u# Py_UNICODE*+int Any Python Unicode C address and length.
w# char*+int Read/write single-segment buffer to C address and length.
z char* Like s, also accepts None (sets C char* to NULL).
z# char*+int Like s#, also accepts None (sets C char* to NULL).
(...) as per ... A Python sequence is treated as one argument per item.
| The following arguments are optional.
: Format end, followed by function name for error messages.
; Format end, followed by entire error message text.

Returning Values

Py_BuildValue অনেকটা PyArg_ParseTuple এর মত ফরম্যাট স্ট্রিং এ কাজ করে নতুন করে তৈরি মানের পরিবর্তে আসল মান দেয়। কিভাবে এড ফাংশন বাস্তবায়ন করতে হয় তার একটি উদাহরণ নিচে দেয়া হলঃ

static PyObject *foo_add(PyObject *self, PyObject *args) {   int a;   int b;    if (!PyArg_ParseTuple(args, "ii", &a, &b)) {     return NULL;   }   return Py_BuildValue("i", a + b);}

Python এ করলে নিচের মত হবেঃ

def add(a, b):   return (a + b)

আপনি Python এর লিস্ট এর সাহায্যে ফাংশনটি থেকে দুই ধরনের ফলাফল দেখাতে পারেন, যেমনঃ


static PyObject *foo_add(PyObject *self, PyObject *args) {
   int a;
   int b;

   if (!PyArg_ParseTuple(args, "ii", &a, &b)) {
      return NULL;
   }
   return Py_BuildValue("i", a + b);
}

 

এই কোডটি Python এ করা হলে এরকম হবেঃ


def add(a, b):
   return (a + b)

 

Py_BuildValue ফাংশন

Py_BuildValue ফাংশনের স্ট্যান্ডার্ড সিগ্নেচার হচ্ছে −


PyObject* Py_BuildValue(char* format,...)

 

এখানে format একটি C স্ট্রিং যা কোন Python অবজেক্ট তৈরি হবে সেটার বর্ননা করে। নিচের Py_BuildValue আর্গুমেন্ট গুলো প্রকৃতপক্ষে C এর মান, যা থেকে প্রোগ্রামটির রেসাল্ট তৈরি হয়। PyObject* এর ফলাফল একটি নতুন ইন্টারফেস তৈরি করে। নিচের টেবিলে প্রচলিত কিছু কোড স্ট্রিং দেয়া হল, যার মধ্যে মাঝে মাঝে এক বা একাধিক কোড স্ট্রিং ফরম্যাট এ সংযুক্ত হয়।

Code C type Meaning
c char A C char becomes a Python string of length 1.
d double A C double becomes a Python float.
f float A C float becomes a Python float.
i int A C int becomes a Python int.
l long A C long becomes a Python int.
N PyObject* Passes a Python object and steals a reference.
O PyObject* Passes a Python object and INCREFs it as normal.
O& convert+void* Arbitrary conversion
s char* C 0-terminated char* to Python string, or NULL to None.
s# char*+int C char* and length to Python string, or NULL to None.
u Py_UNICODE* C-wide, null-terminated string to Python Unicode, or NULL to None.
u# Py_UNICODE*+int C-wide string and length to Python Unicode, or NULL to None.
w# char*+int Read/write single-segment buffer to C address and length.
z char* Like s, also accepts None (sets C char* to NULL).
z# char*+int Like s#, also accepts None (sets C char* to NULL).
(...) as per ... Builds Python tuple from C values.
[...] as per ... Builds Python list from C values.
{...} as per ... Builds Python dictionary from C values, alternating keys and values.

{...} কোডটি C এর জোড় সংখ্যক মানের জন্য ডিকশনারি তৈরি করে, যেমন Py_BuildValue("{issi}",23,"zig","zag",42) কোডটি Python এর মত এই ডিকশনারিটি তৈরি করেঃ {23:'zig','zag':42}.

Use sorting criterion in sort function

Huge Sell on Popular Electronics

/* The following code example is taken from the book
 * "The C++ Standard Library - A Tutorial and Reference"
 * by Nicolai M. Josuttis, Addison-Wesley, 1999
 *
 * (C) Copyright Nicolai M. Josuttis 1999.
 * Permission to copy, use, modify, sell and distribute this software
 * is granted provided this copyright notice appears in all copies.
 * This software is provided "as is" without express or implied
 * warranty, and with no claim as to its suitability for any purpose.
 */

#include <iostream>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <string>
#include <algorithm>
#include <iterator>
#include <functional>
#include <numeric>

/* PRINT_ELEMENTS()
 * - prints optional C-string optcstr followed by
 * - all elements of the collection coll
 * - separated by spaces
 */
template <class T>
inline void PRINT_ELEMENTS (const T& coll, const char* optcstr="")
{
    typename T::const_iterator pos;

    std::cout << optcstr;
    for (pos=coll.begin(); pos!=coll.end(); ++pos) {
        std::cout << *pos << ' ';
    }
    std::cout << std::endl;
}

/* INSERT_ELEMENTS (collection, first, last)
 * - fill values from first to last into the collection
 * - NOTE: NO half-open range
 */
template <class T>
inline void INSERT_ELEMENTS (T& coll, int first, int last)
{
    for (int i=first; i<=last; ++i) {
        coll.insert(coll.end(),i);
    }
}

using namespace std;

void printCollection (const list<int>& l)
{
    PRINT_ELEMENTS(l);
}

bool lessForCollection (const list<int>& l1, const list<int>& l2)
{
    return lexicographical_compare
                (l1.begin(), l1.end(),   // first range
                 l2.begin(), l2.end());  // second range
}

int main()
{
    list<int> c1, c2, c3, c4;

    // fill all collections with the same starting values
    INSERT_ELEMENTS(c1,1,5);
    c4 = c3 = c2 = c1;

    // and now some differences
    c1.push_back(7);
    c3.push_back(2);
    c3.push_back(0);
    c4.push_back(2);

    // create collection of collections
    vector<list<int> > cc;

    cc.push_back(c1);
    cc.push_back(c2);
    cc.push_back(c3);
    cc.push_back(c4);
    cc.push_back(c3);
    cc.push_back(c1);
    cc.push_back(c4);
    cc.push_back(c2);

    // print all collections
    for_each (cc.begin(), cc.end(),
              printCollection);
    cout << endl;

    // sort collection lexicographically
    sort (cc.begin(), cc.end(),    // range
          lessForCollection);      // sorting criterion

    // print all collections again
    for_each (cc.begin(), cc.end(),
              printCollection);
}
/*
1 2 3 4 5 7
1 2 3 4 5
1 2 3 4 5 2 0
1 2 3 4 5 2
1 2 3 4 5 2 0
1 2 3 4 5 7
1 2 3 4 5 2
1 2 3 4 5

1 2 3 4 5
1 2 3 4 5
1 2 3 4 5 2
1 2 3 4 5 2
1 2 3 4 5 2 0
1 2 3 4 5 2 0
1 2 3 4 5 7
1 2 3 4 5 7

 */

C++ code : Read file content

Huge Sell on Popular Electronics

#include <iostream>
#include <fstream>
using namespace std;

int main()
{
  ifstream in("test", ios::in | ios::binary);

  if(!in) {
    cout << "Cannot open input file.\n";
    return 1;
  }

  double num;
  char str[80];

  in.read((char *) &num, sizeof(double));
  in.read(str, 14);
  str[14] = '\0'; // null terminate str

  cout << num << ' ' << str;

  in.close();

  return 0;
}

Sort objects stored in deque

Huge Sell on Popular Electronics

/* The following code example is taken from the book
 * "The C++ Standard Library - A Tutorial and Reference"
 * by Nicolai M. Josuttis, Addison-Wesley, 1999
 *
 * (C) Copyright Nicolai M. Josuttis 1999.
 * Permission to copy, use, modify, sell and distribute this software
 * is granted provided this copyright notice appears in all copies.
 * This software is provided "as is" without express or implied
 * warranty, and with no claim as to its suitability for any purpose.
 */
#include <iostream>
#include <string>
#include <deque>
#include <set>
#include <algorithm>
using namespace std;


/* class Person
 */
class Person {
  private:
    string fn;    // first name
    string ln;    // last name
  public:
    Person() {
    }
    Person(const string& f, const string& n)
     : fn(f), ln(n) {
    }
    string firstname() const;
    string lastname() const;
    // ...
};

inline string Person::firstname() const {
    return fn;
}

inline string Person::lastname() const {
    return ln;
}

ostream& operator<< (ostream& s, const Person& p)
{
    s << "[" << p.firstname() << " " << p.lastname() << "]";
    return s;
}


/* binary function predicate:
 * - returns whether a person is less than another person
 */
bool personSortCriterion (const Person& p1, const Person& p2)
{
    /* a person is less than another person
     * - if the last name is less
     * - if the last name is equal and the first name is less
     */
    return p1.lastname()<p2.lastname() ||
           (p1.lastname()==p2.lastname() &&
            p1.firstname()<p2.firstname());
}

int main()
{
    // create some persons
    Person p1("nicolai","josuttis");
    Person p2("ulli","josuttis");
    Person p3("anica","josuttis");
    Person p4("lucas","josuttis");
    Person p5("lucas","otto");
    Person p6("lucas","arm");
    Person p7("anica","holle");

    // insert person into collection coll
    deque<Person> coll;
    coll.push_back(p1);
    coll.push_back(p2);
    coll.push_back(p3);
    coll.push_back(p4);
    coll.push_back(p5);
    coll.push_back(p6);
    coll.push_back(p7);

    // print elements
    cout << "deque before sort():" << endl;
    deque<Person>::iterator pos;
    for (pos = coll.begin(); pos != coll.end(); ++pos) {
        cout << *pos << endl;
    }

    // sort elements
    sort(coll.begin(),coll.end(),    // range
         personSortCriterion);       // sort criterion

    // print elements
    cout << "deque after sort():" << endl;
    for (pos = coll.begin(); pos != coll.end(); ++pos) {
        cout << *pos << endl;
    }
}

/*
deque before sort():
[nicolai josuttis]
[ulli josuttis]
[anica josuttis]
[lucas josuttis]
[lucas otto]
[lucas arm]
[anica holle]
deque after sort():
[lucas arm]
[anica holle]
[anica josuttis]
[lucas josuttis]
[nicolai josuttis]
[ulli josuttis]
[lucas otto]

 */

A simple C++ Program code

Huge Sell on Popular Electronics

#include <iostream>
#include <fstream>
using namespace std;

int main()
{
  ifstream in("test", ios::in | ios::binary);

  if(!in) {
    cout << "Cannot open input file.\n";
    return 1;
  }

  double num;
  char str[80];

  in.read((char *) &num, sizeof(double));
  in.read(str, 14);
  str[14] = '\0'; // null terminate str

  cout << num << ' ' << str;

  in.close();

  return 0;
}

valarray with double value inside

Huge Sell on Popular Electronics

/* The following code example is taken from the book
 * "The C++ Standard Library - A Tutorial and Reference"
 * by Nicolai M. Josuttis, Addison-Wesley, 1999
 *
 * (C) Copyright Nicolai M. Josuttis 1999.
 * Permission to copy, use, modify, sell and distribute this software
 * is granted provided this copyright notice appears in all copies.
 * This software is provided "as is" without express or implied
 * warranty, and with no claim as to its suitability for any purpose.
 */
#include <iostream>
#include <valarray>
using namespace std;

// print valarray line-by-line
template<class T>
void printValarray (const valarray<T>& va, int num)
{
    for (int i=0; i<va.size()/num; ++i) {
        for (int j=0; j<num; ++j) {
            cout << va[i*num+j] << ' ';
        }
        cout << endl;
    }
    cout << endl;
}

int main()
{
    /* valarray with 12 elements
     * - four rows
     * - three columns
     */
    valarray<double> va(12);

    // fill valarray with values
    for (int i=0; i<12; i++) {
        va[i] = i;
    }

    printValarray (va, 3);

    // assign 77 to all values that are less than 5
    va[va<5.0] = 77.0;

    // add 100 to all values that are greater than 5 and less than 9
    va[va>5.0 && va<9.0] = valarray<double>(va[va>5.0 && va<9.0]) + 100.0;

    printValarray (va, 3);
}

/*
0 1 2
3 4 5
6 7 8
9 10 11

77 77 77
77 77 5
106 107 108
9 10 11


 */

Print minimum, maximum, and sum of the valarray

Huge Sell on Popular Electronics

/* The following code example is taken from the book
 * "The C++ Standard Library - A Tutorial and Reference"
 * by Nicolai M. Josuttis, Addison-Wesley, 1999
 *
 * (C) Copyright Nicolai M. Josuttis 1999.
 * Permission to copy, use, modify, sell and distribute this software
 * is granted provided this copyright notice appears in all copies.
 * This software is provided "as is" without express or implied
 * warranty, and with no claim as to its suitability for any purpose.
 */
#include <iostream>
#include <valarray>
using namespace std;
 
// print valarray
template <class T>
void printValarray (const valarray<T>& va)
{
    for (int i=0; i<va.size(); i++) {
        cout << va[i] << ' ';
    }
    cout << endl;
}
 
int main()
{
    // define two valarrays with ten elements
    valarray<double> va1(10), va2(10);
 
    // assign values 0.0, 1.1, up to 9.9 to the first valarray
    for (int i=0; i<10; i++) {
        va1[i] = i * 1.1;
    }
 
    // assign -1 to all elements of the second valarray
    va2 = -1;
 
    // print both valarrays
    printValarray(va1);
    printValarray(va2);
 
    // print minimum, maximum, and sum of the first valarray
    cout << "min(): " << va1.min() << endl;
    cout << "max(): " << va1.max() << endl;
    cout << "sum(): " << va1.sum() << endl;
 
    // assign values of the first to the second valarray
    va2 = va1;
 
    // remove all elements of the first valarray
    va1.resize(0);
 
    // print both valarrays again
    printValarray(va1);
    printValarray(va2);
}
 
/*
0 1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 9.9
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1
min(): 0
max(): 9.9
sum(): 49.5
 
0 1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 9.9
 
 */

সি প্রোগ্রামিং এ মেমোরি ব্যবস্থাপনাঃ Memory Management in C Programming

Huge Sell on Popular Electronics

সি প্রোগ্রামিং এ মেমোরি ব্যবস্থাপনা

রিদওয়ান বিন শামীম

এই অধ্যায়ে সি প্রোগ্রামিং এ ডাইনামিক মেমোরি ম্যনেজমেন্ট নিয়ে আলোচনা করা হবে। সি প্রোগ্রামিং ল্যাঙ্গুয়েজে মেমোরি বণ্টন ও ব্যবস্থাপনার জন্য কয়েক ধরনের ব্যবস্থা আছে, তাদেরকে হিডার ফাইলে রাখা হয়। এধরনের ফাংশন গুলোকে এভাবে দেখানো যায়ঃ

S.N. Function and Description

1 void *calloc(int num, int size);
Num ইলিমেন্টের এর জন্য array বরাদ্দ দেয় এই ফাংশন, যেগুলোর আকার বাইটে সীমাবদ্ধ।

2 void free(void *address);
এই ফাংশন এড্রেস দ্বারা নির্ধারিত মেমোরি ব্লক প্রকাশ করে।

3 void *malloc(int num);
এই ফাংশন num bytes এর array বরাদ্ধ করে,এবং তাদের শুরু করায়।

4 void *realloc(void *address, int newsize);
এই ফাংশন মেমোরিকে পুনরায় সংগঠিত করে ও নতুন আকারে গড়ে তুলে।

প্রোগ্রামিং এ কাজ করার সময় যদি অ্যারির আকার সম্পর্কে জানা থাকে তাহলে অ্যারি সনাক্ত করা সহজ হবে। উদাহরণস্বরূপ, কারো নাম সংরক্ষণ করতে গেলে, নাম লিখতে ম্যাক্সিমাম ১০০ অক্ষর লাগতে পারে, যা আমরা এভাবে লিখতে পারি,
char name[100];

কিন্তু যদি এমন হয় যেখানে আমাদের যে তথ্য লিখতে হবে তার আকার সম্পর্কে কোন ধারণা নেই, যেমন কোন বিষয়ে বিবৃতি, সেক্ষেত্রে আমাদের একটি পয়েন্টার ব্যবহার করতে হবে অনির্ধারিত মেমোরি সাইজ উল্লেখ করে, যা পরবর্তীতে এভাবে দেখানো যায়,
#include
#include
#include

int main()
{
char name[100];
char *description;

strcpy(name, "Zara Ali");

/* allocate memory dynamically */
description = malloc( 200 * sizeof(char) );
if( description == NULL )
{
fprintf(stderr, "Error - unable to allocate required memory\n");
}
else
{
strcpy( description, "Zara ali a DPS student in class 10th");
}
printf("Name = %s\n", name );
printf("Description: %s\n", description );
}

উপরের কোডগুলো ঠিকভাবে লিখা হলে তা এরুপ ফলাফল দেখাবে,
Name = Zara Ali
Description: Zara ali a DPS student in class 10th

একই ধরনের প্রোগ্রাম লিখা যাবে malloc কে calloc দ্বারা রিপ্লেস করে,
calloc(200, sizeof(char));

অপারেটিং সিস্টেম নিজেই প্রোগ্রামের বরাদ্দ করা মেমোরি রিলিজ করবে, কিন্তু আমরা নিজেরাই প্রয়োজন শেষ হলে free() ফাংশন দ্বারা মেমোরি রিলিজ করে দিতে পারি। এছাড়াও realloc() ফাংশন ব্যবহার করে বরাদ্দকৃত মেমোরি ব্লকের আকার ছোটবড়ও করা যায়। realloc() এবং free() ফাংশন ব্যবহার করে দেখা যাক।

#include
#include
#include

int main()
{
char name[100];
char *description;

strcpy(name, "Zara Ali");

/* allocate memory dynamically */
description = malloc( 30 * sizeof(char) );
if( description == NULL )
{
fprintf(stderr, "Error - unable to allocate required memory\n");
}
else
{
strcpy( description, "Zara ali a DPS student.");
}
/* suppose you want to store bigger description */
description = realloc( description, 100 * sizeof(char) );
if( description == NULL )
{
fprintf(stderr, "Error - unable to allocate required memory\n");
}
else
{
strcat( description, "She is in class 10th");
}

printf("Name = %s\n", name );
printf("Description: %s\n", description );

/* release memory using free() function */
free(description);
}

উপরের কোড ঠিকভাবে লিখা হলে তা যে ফলাফল দেখাবে তা হল,
Name = Zara Ali
Description: Zara ali a DPS student.She is in class 10th
বাড়তি মেমোরি ব্লক বরাদ্দ না করে আমরা উপরের ফাংশন লিখে দেখতে পারি, মেমোরিতে সীমাবদ্ধতা থাকলে strcat() ফাংশন প্রদর্শিত হবে।

সি এবং অ্যারে : Array in C

Huge Sell on Popular Electronics

int marks[4][10] = {{80, 70, 92, 78, 58, 83, 85, 66, 99, 81}, {75, 67, 55, 100, 91, 84, 79, 61, 90, 97}, {98, 67, 75, 89, 81, 83, 80, 90, 88, 77}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};

 

 #include <stdio.h>  
 int main()  
 {  
     int marks[4][10] = {{80, 70, 92, 78, 58, 83, 85, 66, 99, 81}, {75, 67, 55, 100, 91, 84, 79, 61, 90, 97}, {98, 67, 75, 89, 81, 83, 80, 90, 88, 77}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};  
     int col;  
     for(col = 0; col < 10; col++) {  
         marks[3][col] = marks[0][col] / 4.0 + marks[1][col] / 4.0 + marks[2][col] / 2.0;  
         printf("Roll NO: %d  Total Marks: %d\n", col + 1, marks[3][col]);  
     }  
     return 0;  
 }

 

 int marks[4][10];  
 int i, j;  
 for (i = 0; i < 4; i++) {  
     for (j = 0; j < 10; j++) {  
         scanf("%d", &ara[i][j]);  
     }  
 } 

 

#include <stdio.h>  
 int main()  
 {  
     int namta[10][10];  
     int row, col;  
     for (row = 0; row < 10; row++) {  
         for(col = 0; col < 10; col++) {  
             namta[row][col] = (row + 1) * (col + 1);  
         }  
     }  
     for (row = 0; row < 10; row++) {  
         for(col = 0; col < 10; col++) {  
             printf("%d x %d = %d\n", (row + 1), (col + 1), namta[row][col]);  
         }  
         printf("\n");  
     }  
     return 0;  
 }  
#include <stdio.h>  
 int main()  
 {  
     char saarc[7][100] = {"Bangladesh", "India", "Pakistan", "Sri Lanka", "Nepal", "Bhutan", "Maldives"};  
     int row;  
     for (row = 0; row < 7; row++) {  
         printf("%s\n", saarc[row]);  
     }  
     return 0;  
 }  

 

 

#include <stdio.h>  
 #include <string.h>  
 int main()  
 {  
     char saarc[7][100] = {"Bangladesh", "India", "Pakistan", "Sri Lanka", "Nepal", "Bhutan", "Maldives"};  
     int row, col, name_length;  
     for (row = 0; row < 7; row++) {  
         name_length = strlen(saarc[row]);  
         for(col = 0; col < name_length; col++) {  
             printf("%c ", saarc[row][col]);  
         }  
         printf("\n");  
     }  
     return 0;  
 }  


#include <stdio.h>  
 #include <string.h>  
 int main()  
 {  
     char saarc[7][100] = {"Bangladesh", "India", "Pakistan", "Sri Lanka", "Nepal", "Bhutan", "Maldives"};  
     int row, col, name_length;  
     for (row = 0; row < 7; row++) {  
         name_length = strlen(saarc[row]);  
         for(col = 0; col < name_length; col++) {  
             printf("(%d, %d) = %c, ", row, col, saarc[row][col]);  
         }  
         printf("\n");  
     }  
     return 0;  
 }  
 
 #include <stdio.h>  
 #include <string.h>  
 int main()  
 {  
     int ara1[5][5] = {{1, 2, 3, 4, 5}, {10, 20, 30, 40, 50}, {100, 200, 300, 400, 500}, {1000, 2000, 3000, 4000, 5000}, {10000, 20000, 30000, 40000, 50000}};  
     int ara2[5][5];  
     int r, c;  
     printf("Content of first array (ara1): \n");  
     for (r = 0; r < 5; r++) {  
         for(c = 0; c < 5; c++) {  
             printf("%d ", ara1[r][c]);  
         }  
         printf("\n");  
     }  
     printf("\n");  
     // now start copy  
     for (r = 0; r < 5; r++) {  
         for(c = 0; c < 5; c++) {  
             ara2[c][r] = ara1[r][c];  
         }  
     }  
     printf("Content of second array (ara2): \n");  
     for (r = 0; r < 5; r++) {  
         for(c = 0; c < 5; c++) {  
             printf("%d ", ara2[r][c]);  
         }  
         printf("\n");  
     }  
     return 0;  
 }  


	

লেকচার – ০৪: সি++ প্রোগ্রামিং – লজিক (C++ Programming – Logic)

Huge Sell on Popular Electronics

লেকচার-০২: সি++ প্রোগ্রামিং – আপনার প্রথম প্রোগ্রাম (C++ Programming – Your first program)

Huge Sell on Popular Electronics

লেকচার – ০১: সি++ প্রোগ্রামিং – মেশিনের মত চিন্তা করুন (C++ Programming – Think like a machine)

Huge Sell on Popular Electronics

লেকচার – 00: সি++ প্রোগ্রামিং কোর্সের রুপরেখা (C++ Programming Course Outline)

Huge Sell on Popular Electronics

লেকচার-০৭: সিএসই-১০০: সি প্রোগ্রামিং পরিচিতি – সি এ লুপ (For loop in C)

Huge Sell on Popular Electronics

লেকচার-০৬: সিএসই-১০০: সি প্রোগ্রামিং পরিচিতি – হোয়াইল লুপ, (While loop in C)

Huge Sell on Popular Electronics

লেকচার-০৮: সিএসই-১০০: সি প্রোগ্রামিং পরিচিতি – সি এ ফাংশন / মেথড (Function/method in C)

Huge Sell on Popular Electronics

লেকচার-০৫: সিএসই-১০০: সি প্রোগ্রামিং পরিচিতি – সি এ শর্তাধীন বিবৃতি (Conditional Statements in C)

Huge Sell on Popular Electronics