আমি এখানে কিছু বৈধ উত্তর দেখতে পাচ্ছি, তবে আমি বিশদটিতে আরও কিছুটা পেতে চলেছি।
আপনি যদি পাঠ্যের এই পুরো প্রাচীরটি দিয়ে যেতে না চান তবে আপনার মূল প্রশ্নের উত্তরের জন্য নীচের সারসংক্ষেপে ঝাঁপুন।
বিমূর্তন
সুতরাং, এই ক্ষেত্রে, আমি কি জন্য অর্থ প্রদান করছি?
আপনি বিমূর্তনের জন্য অর্থ প্রদান করছেন । সহজ এবং আরও বেশি মানব বান্ধব কোড লিখতে সক্ষম হওয়ায় ব্যয় হয়। সি ++ এ, যা একটি অবজেক্ট-ওরিয়েন্টেড ভাষা, প্রায় প্রতিটি জিনিসই একটি বস্তু an আপনি যখন কোনও বস্তু ব্যবহার করেন, তখন তিনটি প্রধান জিনিস সর্বদা হুডের নীচে ঘটবে:
- অবজেক্ট তৈরি, অবজেক্টটি নিজে এবং তার ডেটার জন্য মেমরির বরাদ্দ।
- অবজেক্ট ইনিশিয়ালেশন (সাধারণত কিছু
init()
পদ্ধতির মাধ্যমে )। সাধারণত এই পদক্ষেপের প্রথম জিনিস হিসাবে হুডের নীচে মেমরি বরাদ্দ ঘটে।
- অবজেক্ট ধ্বংস (সর্বদা নয়)।
আপনি কোডটিতে এটি দেখতে পাচ্ছেন না, তবে প্রতিবার একবার আপনি যখন কোনও বস্তু ব্যবহার করেন উপরের তিনটি জিনিসকে কোনও না কোনওভাবে ঘটতে হবে। আপনি যদি ম্যানুয়ালি সবকিছুই করেন তবে কোড অবশ্যই স্পষ্টভাবে দীর্ঘতর হবে।
এখন, অ্যাডস্ট্রাকশন ওভারহেড যোগ না করে দক্ষতার সাথে তৈরি করা যেতে পারে: পদ্ধতি ইনলাইনিং এবং অন্যান্য কৌশলগুলি সংযোজক এবং প্রোগ্রামার উভয়ই বিমূর্তির ওভারহেডগুলি সরাতে ব্যবহার করতে পারেন, তবে এটি আপনার ক্ষেত্রে নয়।
সত্যিই কি ঘটছে সি ++ এ?
এটি এখানে, ভেঙে দেওয়া:
std::ios_base
বর্গ সক্রিয়া করা হয়, যা সবকিছু আমি / এর সাথে সম্পর্কিত হে জন্য বেস বর্গ।
std::cout
বস্তুর সক্রিয়া করা হয়।
- আপনার স্ট্রিংটি লোড করা হয়েছে এবং এতে পাস করা হয়েছে
std::__ostream_insert
, যা (আপনি ইতিমধ্যে নামটি আবিষ্কার করেছেন) একটি পদ্ধতি std::cout
(মূলত <<
অপারেটর) যা স্ট্রিমটিতে একটি স্ট্রিং যুক্ত করে।
cout::endl
এছাড়াও পাস করা হয় std::__ostream_insert
।
__std_dso_handle
এ পাস করা হয় __cxa_atexit
, যা একটি বিশ্বব্যাপী ফাংশন যা প্রোগ্রামটি ছাড়ার আগে "পরিষ্কার" করার জন্য দায়বদ্ধ। __std_dso_handle
এই বিশ্বব্যাপী অবজেক্টগুলি ধ্বংস করতে এবং ধ্বংস করতে নিজেই এই ফাংশনটি বলে।
সুতরাং C == ব্যবহার করে কোনও কিছুর জন্য অর্থ প্রদান করছেন না?
সি কোডে খুব কম পদক্ষেপই ঘটছে:
- আপনার স্ট্রিং লোড করা হয়েছে এবং রেজিস্টার
puts
মাধ্যমে পাস edi
।
puts
ডাকা হয়।
কোথাও কোনও অবজেক্ট নেই, তাই কোনও কিছু আরম্ভ / ধ্বংস করার দরকার নেই।
তবে এর অর্থ এই নয় যে আপনি কোনও কিছুর জন্য "অর্থ প্রদান করছেন" না । আপনি এখনও বিমূর্ততার জন্য অর্থ প্রদান করছেন, এবং সি স্ট্যান্ডার্ড লাইব্রেরিটির সূচনাও এবং গতিশীল রেজোলিউশনটি printf
ফাংশনটি (বা, আসলে puts
যা সংকলক দ্বারা অনুকূলিত হয়েছে যেহেতু আপনার কোনও বিন্যাসের স্ট্রিংয়ের প্রয়োজন নেই) এখনও হুডের নীচে ঘটে।
আপনি যদি এই প্রোগ্রামটি খাঁটি সমাবেশে লিখেন তবে এটি দেখতে এরকম কিছু দেখাবে:
jmp start
msg db "Hello world\n"
start:
mov rdi, 1
mov rsi, offset msg
mov rdx, 11
mov rax, 1 ; write
syscall
xor rdi, rdi
mov rax, 60 ; exit
syscall
কোনটি invoking মধ্যে মূলত শুধুমাত্র ফলাফল write
প্রাপ্ত syscall দ্বারা অনুসরণ exit
প্রাপ্ত syscall। এখন এই ন্যূনতমরূপে একই জিনিস সাধা হবে।
সংক্ষেপ
সিটি হ'ল আরও খালি-হাড় এবং কেবলমাত্র প্রয়োজনীয় ন্যূনতম যা প্রয়োজন তা ব্যবহারকারীর উপর সম্পূর্ণ নিয়ন্ত্রণ রেখে যায়, যা তারা চান তারা মূলত যে কোনও কিছুকে সম্পূর্ণরূপে অনুকূলিত করতে এবং অনুকূলিত করতে সক্ষম। আপনি প্রসেসরকে বলুন কোনও রেজিস্টারে একটি স্ট্রিং লোড করুন এবং তারপরে সেই স্ট্রিংটি ব্যবহার করার জন্য একটি লাইব্রেরি ফাংশনটি কল করুন। অন্যদিকে সি ++ হ'ল উপায়টি আরও জটিল এবং বিমূর্ত । জটিল কোড লেখার সময় এটির প্রচুর সুবিধা রয়েছে এবং এটি আরও সহজে লেখার পক্ষে এবং আরও বেশি মানুষের বান্ধব কোডের অনুমতি দেয় তবে এটি অবশ্যই ব্যয় করে আসে। এই জাতীয় ক্ষেত্রে সি এর তুলনায় যদি সি ++ তে পারফরম্যান্সে সবসময় একটি ত্রুটি দেখা দেয়, যেহেতু সি ++ এ জাতীয় প্রাথমিক কাজগুলি সম্পাদন করার জন্য যা প্রয়োজন তার চেয়ে বেশি সরবরাহ করে এবং সুতরাং এটি আরও ওভারহেড যুক্ত করে ।
আপনার মূল প্রশ্নের উত্তর :
আমি যা খাচ্ছি না তার জন্য আমি কি অর্থ দিচ্ছি?
এই নির্দিষ্ট ক্ষেত্রে, হ্যাঁ । আপনি সি -++ এর চেয়ে বেশি সি-এর চেয়ে বেশি যে কোনও অফার দিচ্ছেন না সেটির সুবিধা নিচ্ছেন না, তবে এটি কেবল কারণ এই সহজ কোডের কিছু নেই যা সি ++ আপনাকে সহায়তা করতে পারে: এটি এতই সহজ যে আপনার সত্যিকার অর্থেই সি ++ লাগবে না।
ওহ, এবং আরও একটি জিনিস!
সি ++ এর সুবিধাগুলি প্রথম নজরে সুস্পষ্ট নাও লাগতে পারে, যেহেতু আপনি খুব সাধারণ এবং ছোট প্রোগ্রাম লিখেছেন তবে কিছুটা জটিল উদাহরণ দেখুন এবং পার্থক্যটি দেখুন (উভয় প্রোগ্রামই হুবহু একই কাজ করে):
সি :
#include <stdio.h>
#include <stdlib.h>
int cmp(const void *a, const void *b) {
return *(int*)a - *(int*)b;
}
int main(void) {
int i, n, *arr;
printf("How many integers do you want to input? ");
scanf("%d", &n);
arr = malloc(sizeof(int) * n);
for (i = 0; i < n; i++) {
printf("Index %d: ", i);
scanf("%d", &arr[i]);
}
qsort(arr, n, sizeof(int), cmp)
puts("Here are your numbers, ordered:");
for (i = 0; i < n; i++)
printf("%d\n", arr[i]);
free(arr);
return 0;
}
সি ++ :
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(void) {
int n;
cout << "How many integers do you want to input? ";
cin >> n;
vector<int> vec(n);
for (int i = 0; i < vec.size(); i++) {
cout << "Index " << i << ": ";
cin >> vec[i];
}
sort(vec.begin(), vec.end());
cout << "Here are your numbers:" << endl;
for (int item : vec)
cout << item << endl;
return 0;
}
আশা করি আপনি এখানে আমার অর্থ কী তা পরিষ্কার করে দেখতে পারবেন। সিটিতে কীভাবে আপনাকে নিম্ন স্তরে মেমরি পরিচালনা করতে হবে malloc
এবং free
কীভাবে আপনাকে সূচীকরণ এবং আকারগুলি সম্পর্কে আরও যত্নবান হতে হবে এবং ইনপুট এবং প্রিন্টিংয়ের সময় কীভাবে আপনাকে খুব সুনির্দিষ্ট হতে হবে তা লক্ষ করুন ।