নেমস্পেস থাকা বেশিরভাগ ভাষার ক্ষেত্রেই বুদ্ধিমানের মতো মনে হয়। তবে আমি যতদূর বলতে পারি, এএনএসআই সি এটি সমর্থন করে না। কেন না? এটি কোনও ভবিষ্যতের মান অন্তর্ভুক্ত করার পরিকল্পনা আছে?
নেমস্পেস থাকা বেশিরভাগ ভাষার ক্ষেত্রেই বুদ্ধিমানের মতো মনে হয়। তবে আমি যতদূর বলতে পারি, এএনএসআই সি এটি সমর্থন করে না। কেন না? এটি কোনও ভবিষ্যতের মান অন্তর্ভুক্ত করার পরিকল্পনা আছে?
উত্তর:
সি এর নেমস্পেস রয়েছে। কাঠামো ট্যাগগুলির জন্য একটি, এবং অন্য ধরণের। নিম্নলিখিত সংজ্ঞা বিবেচনা করুন:
struct foo
{
int a;
};
typedef struct bar
{
int a;
} foo;
প্রথমটির ট্যাগ ট্যাগ রয়েছে এবং পরে টাইপফের সাথে টাইপ ফু তৈরি করা হবে। তবুও নাম-সংঘর্ষ হয় না। এটি কারণ কাঠামোগত ট্যাগ এবং প্রকারগুলি (অন্তর্নির্মিত প্রকার এবং টাইপডেফ'যুক্ত প্রকারগুলি) পৃথক নেমস্পেসে থাকে।
সি যেটি অনুমতি দেয় না তা হ'ল ইচ্ছামত নতুন নামস্থান তৈরি করা । এটি কোনও ভাষায় গুরুত্বপূর্ণ হিসাবে বিবেচনা করার আগেই সিটিকে প্রমিত করা হয়েছিল, এবং নেমস্পেস যুক্ত করা পিছনের দিকের সামঞ্জস্যেরও হুমকিস্বরূপ ছিল কারণ এটি সঠিকভাবে কাজ করার জন্য নাম ম্যাঙ্গালিংয়ের প্রয়োজন। আমি মনে করি এটি দর্শনশাস্ত্র নয়, প্রযুক্তিগত কারণগুলির জন্য দায়ী করা যেতে পারে।
সম্পাদনা: জেরেমিপি ভাগ্যক্রমে আমাকে সংশোধন করেছে এবং যে নামের জায়গাটি আমি মিস করেছি তা উল্লেখ করেছে। লেবেলগুলির জন্য এবং স্ট্রাক্ট / ইউনিয়ন সদস্যদের জন্যও নেমস্পেস রয়েছে।
struct
সংজ্ঞা তার সদস্যদের জন্য একটি নতুন নেমস্পেস ঘোষণা করে। আমি এই সত্যটি কাজে লাগানোর পক্ষে বলছি না এবং এর ব্যবহারের কোনও উপায় সম্পর্কে আমি অবগত নই, কারণ struct
এর স্থির সদস্য থাকতে পারে না।
সম্পূর্ণতার জন্য সি-তে নেমস্পেসগুলি থেকে আপনি পেতে পারেন এমন "বেনিফিট" অর্জনের বিভিন্ন উপায় রয়েছে
আমার প্রিয় পদ্ধতিগুলির মধ্যে একটি হ'ল কাঠামোটি ব্যবহার করে এমন একাধিক পদ্ধতি পয়েন্টার রাখার জন্য যা আপনার লাইব্রেরি / ইত্যাদির ইন্টারফেস are
তারপরে আপনি এই কাঠামোর একটি বাহ্যিক উদাহরণ ব্যবহার করুন যা আপনি আপনার সমস্ত ফাংশনকে নির্দেশ করে আপনার লাইব্রেরির অভ্যন্তরে শুরু করেছিলেন। এটি আপনাকে ক্লায়েন্টের নেমস্পেসে না রেখে আপনার গ্রন্থাগারে আপনার নামগুলি সহজ রাখতে দেয় (গ্লোবাল স্কোপে এক্সটার্নাল ভেরিয়েবল ব্যতীত, সম্ভবত কয়েক শতাধিক পদ্ধতি বনাম))
কিছু অতিরিক্ত রক্ষণাবেক্ষণ জড়িত রয়েছে তবে আমি মনে করি এটি ন্যূনতম।
এখানে একটি উদাহরণ:
/* interface.h */
struct library {
const int some_value;
void (*method1)(void);
void (*method2)(int);
/* ... */
};
extern const struct library Library;
/* interface.h */
/* interface.c */
#include "interface.h"
void method1(void)
{
...
}
void method2(int arg)
{
...
}
const struct library Library = {
.method1 = method1,
.method2 = method2,
.some_value = 36
};
/* end interface.c */
/* client code */
#include "interface.h"
int main(void)
{
Library.method1();
Library.method2(5);
printf("%d\n", Library.some_value);
return 0;
}
/* end */
এর ব্যবহার . সিনট্যাক্স ক্লাসিক লাইব্রেরি_ফাংশন () লাইব্রেরী_সুম_মূল্য পদ্ধতির উপর একটি শক্তিশালী সমিতি তৈরি করে। তবে কিছু সীমাবদ্ধতা রয়েছে যার একটিতে আপনি ম্যাক্রোগুলিকে ফাংশন হিসাবে ব্যবহার করতে পারবেন না।
library.method1()
?
.c
ফাইলে আমার সমস্ত ফাংশনগুলি ডিফল্টরূপে স্থিতিশীল করার চেষ্টা করে যাচ্ছি , সুতরাং কেবলমাত্র প্রকাশিত ফাংশনগুলিই ফাইলের const struct
সংজ্ঞাতে স্পষ্টভাবে উদ্ভাসিত হয় .c
।
function1
/ এবং method2
উভয়ের সাথে সংকলনের সময় / এর আসল ঠিকানাটি গণনা করবে । আপনি যদি নিজের উত্স সহ এই জাতীয় লাইব্রেরিগুলি সংকলন না করেন তবে এই পদ্ধতিটি এর ফাংশন কলগুলিতে কিছু ওভারহেড যুক্ত করবে। -O2
-flto
সি এর নেমস্পেস রয়েছে। বাক্য গঠনটি হ'ল namespace_name
। এমনকি আপনি এটিকে বাসা হিসাবে বাসাতে পারেন general_specific_name
। এবং আপনি যদি প্রতিবার নেমস্পেসের নাম না লিখে নাম অ্যাক্সেস করতে সক্ষম হতে চান তবে একটি শিরোনাম ফাইলে সম্পর্কিত প্রিপ্রোসেসর ম্যাক্রোগুলি অন্তর্ভুক্ত করুন eg
#define myfunction mylib_myfunction
নাম মাংলিংয়ের তুলনায় এটি অনেক বেশি পরিচ্ছন্ন এবং নির্দিষ্ট ভাষা নেমস্পেসগুলি সরবরাহ করতে প্রতিশ্রুতিবদ্ধ অন্যান্য নৃশংসতা।
.তিহাসিকভাবে, সি সংকলকগুলির নামগুলি ম্যাঙ্গেল করে না (তারা উইন্ডোতে করে তবে cdecl
কলিং কনভেনশনের জন্য ম্যাঙ্গিলিং কেবল একটি আন্ডারস্কোর উপসর্গ যুক্ত করে)।
এটি অন্যান্য ভাষা (এসেম্বারার সহ) এর সি লাইব্রেরিগুলি ব্যবহার করা সহজ করে তোলে এবং আপনি প্রায়শই extern "C"
সি ++ এপিআইয়ের জন্য মোড়ক দেখেন এমন একটি কারণ ।
শুধু historicalতিহাসিক কারণ। সেই সময় নেমস্পেসের মতো কিছু থাকার কথা কেউ ভাবেনি। এছাড়াও তারা ভাষাটি সহজ রাখার চেষ্টা করেছিল। ভবিষ্যতে তাদের এটি থাকতে পারে
কোনও উত্তর নয়, তবে কোনও মন্তব্য নয়। সি namespace
স্পষ্টভাবে সংজ্ঞায়নের কোনও উপায় সরবরাহ করে না । এটির পরিবর্তনশীল সুযোগ রয়েছে। উদাহরণ স্বরূপ:
int i=10;
struct ex {
int i;
}
void foo() {
int i=0;
}
void bar() {
int i=5;
foo();
printf("my i=%d\n", i);
}
void foobar() {
foo();
bar();
printf("my i=%d\n", i);
}
আপনি ভেরিয়েবল এবং ফাংশনগুলির জন্য যোগ্য নাম ব্যবহার করতে পারেন:
mylib.h
void mylib_init();
void mylib_sayhello();
নাম স্থান থেকে একমাত্র পার্থক্য যা আপনি হতে using
পারবেন না এবং আমদানি করতে পারবেন না from mylib
।
namespace mylib { void init(); void say_hello(); }
যা এটিও গুরুত্বপূর্ণ (ইশ)।
নেমস্পেসগুলি হওয়ার আগে এএনএসআই সি আবিষ্কার করা হয়েছিল।
কারণ যে লোকেরা এই ক্ষমতাটি সিতে যুক্ত করতে চায় তারা একত্রিত হয় নি এবং সংকলক লেখক দল এবং আইএসও সংস্থাগুলিতে কিছুটা চাপ দেওয়ার জন্য সংগঠিত হয়নি।
সি সি ++ এর মতো নেমস্পেসগুলি সমর্থন করে না। সি ++ নেমস্পেসের প্রয়োগগুলি নামগুলিকে ম্যাঙ্গেল করে। নীচে বর্ণিত পদ্ধতির সাহায্যে আপনি নাম না থাকা অবস্থায় সি ++ তে নেমস্পেসের সুবিধা পেতে পারবেন। আমি বুঝতে পারি যে প্রশ্নের প্রকৃতি হ'ল সি-স্পেস নাম্বারগুলিকে কেন সমর্থন করে না (এবং একটি তুচ্ছ উত্তরটি হ'ল এটি কার্যকর হয় না কারণ এটি :))। আমি কেবল ভেবেছিলাম যে এটি টেমপ্লেট এবং নেমস্পেসগুলির কার্যকারিতাটি কীভাবে বাস্তবায়িত করেছি তা দেখার জন্য কাউকে সহায়তা করতে পারে।
নেমস্পেস এবং / অথবা টেমপ্লেটগুলি সি ব্যবহার করে কীভাবে সুবিধা পাবেন সে সম্পর্কে আমি একটি টিউটোরিয়াল লিখেছিলাম
সি তে নেমস্পেস এবং টেম্পলেটগুলি (লিঙ্কযুক্ত তালিকাগুলি ব্যবহার করে)
বেসিক নেমস্পেসের জন্য, একটি সাধারণভাবে একটি সম্মেলন হিসাবে নেমস্পেসের নামটির উপসর্গ করতে পারে।
namespace MY_OBJECT {
struct HANDLE;
HANDLE *init();
void destroy(HANDLE * & h);
void do_something(HANDLE *h, ... );
}
হিসাবে লেখা যেতে পারে
struct MY_OBJECT_HANDLE;
struct MY_OBJECT_HANDLE *my_object_init();
void my_object_destroy( MY_OBJECT_HANDLE * & h );
void my_object_do_something(MY_OBJECT_HANDLE *h, ... );
নেমস্পেসিং এবং টেম্পলেটগুলির ধারণাটি ব্যবহার করার জন্য আমার যে দ্বিতীয় পদ্ধতির দরকার ছিল তা হ'ল ম্যাক্রো কনটেনটেশন ব্যবহার করা এবং অন্তর্ভুক্ত করা। উদাহরণস্বরূপ, আমি একটি তৈরি করতে পারি
template<T> T multiply<T>( T x, T y ) { return x*y }
নিম্নলিখিত হিসাবে টেমপ্লেট ফাইল ব্যবহার করে
গুণ - টেমপ্লেট
_multiply_type_ _multiply_(multiply)( _multiply_type_ x, _multiply_type_ y);
গুণ - টেমপ্লেট
_multiply_type_ _multiply_(multiply)( _multiply_type_ x, _multiply_type_ y) {
return x*y;
}
আমরা এখন অন্তর্নির্মিতভাবে নিম্নলিখিত হিসাবে সংজ্ঞা দিতে পারি। এই উদাহরণে, আমি একটি int_m Multiply.h / .c ফাইল তৈরি করব।
int_m Multiply.h
#ifndef _INT_MULTIPLY_H
#define _INT_MULTIPLY_H
#ifdef _multiply_
#undef _multiply_
#endif
#define _multiply_(NAME) int ## _ ## NAME
#ifdef _multiply_type_
#undef _multiply_type_
#endif
#define _multiply_type_ int
#include "multiply-template.h"
#endif
int_m Multiply.c
#include "int_multiply.h"
#include "multiply-template.c"
এই সমস্ত শেষে, আপনার জন্য একটি ফাংশন এবং শিরোনাম ফাইল থাকবে।
int int_multiply( int x, int y ) { return x * y }
আমি সরবরাহিত লিঙ্কগুলিতে আরও একটি বিস্তারিত টিউটোরিয়াল তৈরি করেছি যা লিঙ্কযুক্ত তালিকার সাথে এটি কীভাবে কাজ করে তা দেখায়। আশা করি এটি কাউকে সাহায্য করবে!