কেন আমাদের সিতে ভেরিয়েবলের ডেটা টাইপ উল্লেখ করতে হবে


19

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

#include<stdio.h>
main()
{
  float X=5.2;
  float Y=5.1;
  float Z;
  Z=Y+X;
  printf("%f",Z);

}

আমাকে কম্পাইলারটি জানাতে হয়েছিল ভেরিয়েবল এক্স এর ধরণ type

  • সংকলক Xনিজে থেকে প্রকারটি নির্ধারণ করতে পারে না ?

হ্যাঁ, আমি যদি এটি করি তবে এটি করতে পারে:

#define X 5.2

আমি এখন আমার প্রোগ্রামটি লিখতে পারি সংকলককে প্রকারটি না বলে X:

#include<stdio.h>
#define X 5.2
main()
{
  float Y=5.1;
  float Z;
  Z=Y+X;
  printf("%f",Z);

}  

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

  • যখন আমরা কিছু (মূল) তে ঘোষণা করি তখন কেন আমাদের উপাত্তের ধরণ উল্লেখ করতে হবে? সংকলকটি কেন নিজের main()মতো করে কোনও ভেরিয়েবলের ডেটা টাইপ নির্ধারণ করতে পারে না #define

14
আসলে এই দুটি প্রোগ্রাম সমতুল্য নয়, এতে তারা কিছুটা আলাদা আউটপুট দিতে পারে! 5.2এটি হ'ল double, সুতরাং প্রথম প্রোগ্রামটি ডাবল লিটারেলগুলিকে floatযথার্থতার সাথে চক্রাকার করে দেয় , তারপরে এগুলিকে ফ্লোট হিসাবে যুক্ত করে, যখন দ্বিতীয়টি 5.1 এর ডাবল উপস্থাপনা ফিরে আসে doubleএবং সংযোজন doubleব্যবহার করে এটি 5.2 মানের সাথে যুক্ত করে double, তারপরে সেই গণনার ফলাফলকে floatসুস্পষ্ট করে দেয় । যেহেতু বিভিন্ন স্থানে রাউন্ডিং ঘটে, ফলাফল ডফার হতে পারে। এটি অন্যথায় অভিন্ন প্রোগ্রামের আচরণকে প্রভাবিত করে পরিবর্তনশীলগুলির প্রকারের জন্য কেবল একটি উদাহরণ।

12
আপনি যখন তা করবেন #define X 5.2, Xনা একটি পরিবর্তনশীল একটি ধ্রুবক, তাই এটি আক্ষরিক সঙ্গে প্রাক প্রসেসর হতে প্রতিস্থাপিত হয়, কিন্তু 5.2যে কোন জায়গায় উল্লেখ করেছে X। আপনি পুনরায় নিয়োগ দিতে পারবেন না X
স্ক্রিপ্টিন

16
ঠিক যেমন একটি নোট: এটি একটি আশীর্বাদ এবং একটি অভিশাপ। একদিকে, আপনাকে কয়েকটি অক্ষর টাইপ করতে হবে যখন সংকলকটি সত্যিই আপনার জন্য এটি করতে পারত (সি ++ এর autoআসলে আপনি যা চান তা করেন)। অন্যদিকে, আপনি যদি মনে করেন যে আপনার কোডটি কী করছে এবং আপনি আসলে অন্য কিছু টাইপ করেছেন তবে স্ট্যাটিক টাইপিং এটি একটি বিশাল সমস্যা হওয়ার আগেই এর আগে ত্রুটি ঘটবে। প্রতিটি ভাষা ভারসাম্য রোধ করে: স্ট্যাটিক টাইপিং, টাইপ ইনফেরেন্স, ডায়নামিক টাইপিং। কিছু কাজের জন্য অতিরিক্ত টাইপিংয়ের পক্ষে এটি যথার্থ। অন্যদের জন্য, এটি একটি নষ্ট।
কর্ট অ্যামোন - মনিকা

ওকামল এবং / অথবা হাস্কেল শিখুন .... আপনি তাদের ধরণের অনুমিতি দক্ষতা সম্পর্কে খুশি হবেন।
বেসাইল স্টারিনকিভিচ

উত্তর:


46

আপনি ভেরিয়েবল ডিক্লোরেশনগুলির সাথে #defineএস তুলনা করছেন , যা ভুল। এর #defineসাহায্যে আপনি সনাক্তকারী এবং উত্স কোডের স্নিপেটের মধ্যে একটি ম্যাপিং তৈরি করতে পারেন। সি প্রিপ্রসেসর তারপরে সরবরাহকারী স্নিপেটের সাহায্যে সেই শনাক্তকারীর যে কোনও উপস্থিতি অক্ষরে অক্ষরে স্থান দেবে। লেখা

#define FOO 40 + 2
int foos = FOO + FOO * FOO;

লেখার মতো সংকলকটিতে একই জিনিস শেষ হয়

int foos = 40 + 2 + 40 + 2 * 40 + 2;

এটিকে স্বয়ংক্রিয় অনুলিপি এবং পেস্ট হিসাবে ভাবেন।

এছাড়াও, সাধারণ ভেরিয়েবলগুলি পুনরায় নিয়োগ দেওয়া যেতে পারে, যখন ম্যাক্রো দিয়ে তৈরি করা #defineযায় না (যদিও আপনি এটি পুনরায় করতে পারেন #define)। এক্সপ্রেশনটি FOO = 7একটি সংকলক ত্রুটি হবে, যেহেতু আমরা "মূল্যায়নগুলি" বরাদ্দ করতে পারি না: 40 + 2 = 7এটি অবৈধ।

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

"স্ট্যাক" নামে পরিচিত স্মৃতিটির একটি প্রসার রয়েছে। প্রতিটি স্থানীয় ভেরিয়েবল স্ট্যাকের একটি অঞ্চলের সাথে মিলে যায়। এখন প্রশ্ন এই অঞ্চলটি কত বাইট হতে হবে? সি তে, প্রতিটি ধরণের একটি সু-সংজ্ঞায়িত আকার থাকে যার মাধ্যমে আপনি কোয়েরি করতে পারেন sizeof(type)। সংকলকটিকে প্রতিটি ভেরিয়েবলের ধরণ জানতে হবে যাতে এটি স্ট্যাকের সঠিক পরিমাণের স্থান সংরক্ষণ করতে পারে।

কেন ধ্রুবকগুলির সাথে #defineধরণের টীকাগুলির প্রয়োজন নেই? এগুলি স্ট্যাকের মধ্যে সংরক্ষণ করা হয় না। পরিবর্তে, #defineঅনুলিপি এবং পেস্টের চেয়ে কিছুটা বেশি রক্ষণযোগ্য পদ্ধতিতে সোর্স কোডের পুনরায় ব্যবহারযোগ্য স্নিপেটগুলি তৈরি করে। যেমন সোর্স কোডে লিটারেল "foo"বা 42.87ফলে বাইনারি একটি পৃথক তথ্য বিভাগে বিশেষ নির্দেশাবলী যেমন পারেন ইনলাইন কম্পাইলার দ্বারা সংরক্ষণ করা হয়, অথবা।

তবে, আক্ষরিকের প্রকারভেদ রয়েছে। একটি স্ট্রিং আক্ষরিক একটি char *42এটি একটি intতবে ছোট প্রকারের জন্য (রূপান্তরকরণ সংকীর্ণকরণ) ব্যবহার করা যেতে পারে। 42.8একটি হবে double। আপনার যদি আক্ষরিক থাকে এবং এটির জন্য আলাদা ধরণের থাকতে চান (উদাহরণস্বরূপ 42.8একটি floatবা 42একটি তৈরি করতে unsigned long int), তবে আপনি প্রত্যয় ব্যবহার করতে পারেন - আক্ষরিকের পরে একটি চিঠি যা সংকলক সেই আক্ষরিক সাথে কীভাবে আচরণ করে তা পরিবর্তিত করে। আমাদের ক্ষেত্রে, আমরা বলতে পারি 42.8fবা করতে পারি 42ul

কিছু ভাষার সি হিসাবে স্ট্যাটিক টাইপিং থাকে তবে টীকা টীকাটি optionচ্ছিক। উদাহরণগুলি হ'ল এমএল, হাস্কেল, স্কালা, সি #, সি ++ 11 এবং গো। ওটা কিভাবে কাজ করে? ম্যাজিক? না, একে "টাইপ অনুমান" বলা হয়। সি # এবং গো-তে সংকলক একটি অ্যাসাইনমেন্টের ডান হাতের দিকে তাকাচ্ছে এবং এর প্রকারটি হ্রাস করে। এটি মোটামুটি সোজা যদি ডান হাতটি যেমন আক্ষরিক হয় 42ul। তারপরে এটি স্পষ্ট যে ভেরিয়েবলের ধরণটি কী হওয়া উচিত। অন্যান্য ভাষায় আরও জটিল অ্যালগরিদম থাকে যা ভেরিয়েবল কীভাবে ব্যবহৃত হয় তা বিবেচনায় নেয়। উদাহরণস্বরূপ যদি আপনি এটি করেন x/2তবে xস্ট্রিং হতে পারে না তবে কয়েকটি সংখ্যার প্রকারের থাকতে হবে।


ব্যাখ্যা করার জন্য আপনাকে ধন্যবাদ। আমি যে বিষয়টি বুঝতে পারি তা হ'ল যখন আমরা কোনও ভেরিয়েবলের (স্থানীয় বা বৈশ্বিক) প্রকারটি ঘোষণা করি, আমরা আসলে সংকলকটি বলছি, স্ট্যাকের মধ্যে এই ভেরিয়েবলের জন্য কতটা স্থান সংরক্ষণ করা উচিত। অন্যদিকে আমাদের #defineএকটি ধ্রুবক রয়েছে যা সরাসরি বাইনারি কোডে রূপান্তরিত হয় - তবে এটি দীর্ঘতর হতে পারে - এবং এটি মেমরিতে যেমন রয়েছে তেমন সংরক্ষণ করা হয়।
ব্যবহারকারী 106313

2
@ ব্যবহারকারী31782 - বেশ নয়। আপনি যখন কোনও ভেরিয়েবল ঘোষণা করেন টাইপটি কম্পাইলারকে জানায় যে ভেরিয়েবলের কী বৈশিষ্ট্য রয়েছে। এই বৈশিষ্ট্যগুলির মধ্যে একটি আকার; অন্যান্য বৈশিষ্ট্যগুলির মধ্যে এটি কীভাবে মানগুলি উপস্থাপন করে এবং সেই মানগুলিতে কী কী অপারেশন সম্পাদন করা যায় তা অন্তর্ভুক্ত।
পিট বেকার

@ পেটবেকার তাহলে কম্পাইলার কীভাবে এই অন্যান্য বৈশিষ্ট্যগুলি জানতে পারে #define X 5.2?
ব্যবহারকারী 106313

1
কারণ আপনার কাছে ভুল টাইপটি printfপেরিয়ে অনির্ধারিত আচরণ শুরু হয়েছিল। আমার মেশিনে যা স্নিপেট প্রতিটি সময় আলাদা মান প্রিন্ট করে, আইডিয়নে এটি শূন্য প্রিন্ট করার পরে ক্র্যাশ হয়।
মাত্তেও ইটালিয়া

4
@ ব্যবহারকারী31782 - "দেখে মনে হচ্ছে যে আমি যে কোনও ডেটা ধরণের উপর কোনও ক্রিয়াকলাপ করতে পারি" নংটি X*Yবৈধ নয় Xএবং যদি Yএটি পয়েন্টার হয় তবে এটি ঠিক আছে int; *Xযদি Xহয় তবে তা বৈধ নয় int, তবে এটি পয়েন্টার হলে ঠিক আছে okay
পিট বেকার

4

দ্বিতীয় উদাহরণে এক্স কখনও ভাসা নয়। এটিকে একটি ম্যাক্রো বলা হয়, এটি উত্সটিতে সংজ্ঞায়িত ম্যাক্রো মান 'এক্স' প্রতিস্থাপন করে। # সংজ্ঞা সম্পর্কিত একটি পঠনযোগ্য নিবন্ধটি এখানে

সরবরাহকৃত কোডের ক্ষেত্রে, সংকলনের আগে প্রিপ্রসেসর কোডটি পরিবর্তন করে

Z=Y+X;

প্রতি

Z=Y+5.2;

এবং এটিই সংকলিত হয়।

এর অর্থ আপনি সেই জাতীয় মানগুলিও কোডের মতো প্রতিস্থাপন করতে পারেন

#define X sqrt(Y)

অথবা এমনকি

#define X Y

3
একে কেবল একটি ম্যাক্রো বলা হয়, ভ্যারিয়েডিক ম্যাক্রো নয়। একটি ভ্যারিয়্যাডিক ম্যাক্রো একটি ম্যাক্রো যা একটি পরিবর্তনশীল সংখ্যক আর্গুমেন্ট গ্রহণ করে, যেমন #define FOO(...) { __VA_ARGS__ }
এইচডিভি

2
আমার খারাপ, ঠিক করবে :)
জেমস স্নেল

1

সংক্ষিপ্ত উত্তর হ'ল ইতিহাস / হার্ডওয়্যার উপস্থাপনের কারণে সি প্রকারের প্রয়োজন।

ইতিহাস: সি 1970 এর দশকের গোড়ার দিকে বিকশিত হয়েছিল এবং এটি সিস্টেম প্রোগ্রামিংয়ের ভাষা হিসাবে উদ্দিষ্ট হয়েছিল। কোডটি আদর্শভাবে দ্রুত এবং হার্ডওয়্যারটির ক্ষমতার সর্বোত্তম ব্যবহার করে।

সংকলনের সময় প্রকারভেদগুলি নির্দেশ করা সম্ভব হত, তবে ইতিমধ্যে ধীর সংকলনের সময়গুলি আরও বেড়ে যেত (এক্স কেসিডির 'সংকলন' কার্টুনের কথা উল্লেখ করুন। এটি সি প্রকাশের পরে কমপক্ষে 10 বছর 'হ্যালো ওয়ার্ল্ড'-এ প্রয়োগ হত ) রানটাইমের সময় প্রকারের অন্তর্ভুক্তিগুলি সিস্টেম প্রোগ্রামিংয়ের লক্ষ্যগুলি ফিট করে না। রানটাইম অনুমানের জন্য অতিরিক্ত রান টাইম লাইব্রেরি প্রয়োজন requires সি প্রথম পিসির অনেক আগে এসেছিল। যার 256 র‌্যাম ছিল। গিগাবাইট বা মেগাবাইট নয় কিলোবাইট।

আপনার উদাহরণে, যদি আপনি প্রকারগুলি বাদ দেন

   X=5.2;
   Y=5.1;

   Z=Y+X;

তারপরে সংকলকটি খুশিতে কাজ করতে পারে যে এক্স ও ওয়াই ভাসমান এবং জেডকে একই করে। প্রকৃতপক্ষে, একটি আধুনিক সংকলকটি এক্স ও ওয়াইয়ের প্রয়োজন নেই এবং কেবল জেডকে 10.3 এ সেট করুন work

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

একটি ভাসমান চেয়ে ডাবল আরও উপযুক্ত হবে? আরও মেমরি লাগে এবং ধীর হয় তবে ফলাফলটির যথার্থতা আরও বেশি হবে।

দশমিক সংখ্যাটি গুরুত্বপূর্ণ ছিল না বলেই হয়ত ফাংশনটির রিটার্ন মানটি (বা দীর্ঘ) হতে পারে, যদিও ফ্লোট থেকে ইনট এ রূপান্তর ব্যয় ছাড়াই নয়।

রিটার্ন মানটি দ্বিগুণ গ্যারান্টিযুক্তও করা যেতে পারে যে ফ্লোট + ফ্লোট ওভারফ্লো হয় না।

এই সমস্ত প্রশ্ন আজ রচিত বিশাল সংখ্যক কোডের পক্ষে অর্থহীন বলে মনে হয় তবে সি তৈরি হওয়ার সময় এটি অতীব গুরুত্বপূর্ণ ছিল।


1
এই যেমন ব্যাখ্যা না কেন টাইপ ঘোষণা ঐচ্ছিক না করা হয়েছে, প্রোগ্রামার তাদের স্পষ্টভাবে ঘোষণা করার পারেন নেবেন বা অনুমান করা কম্পাইলার উপর নির্ভর করতে সক্ষম হবেন
মশা

1
আসলে এটি @ জাগ্রত হয় না। আমি টেক্সটটি টুইট করেছি তবে সেই সময়টি করার কোনও অর্থ নেই। ডোমেন সিটি আসলে 1 বাইট, বা 2 বাইট বা 4 বাইটে স্ট্রিং বা একটি শব্দের মধ্যে 5 বিট হিসাবে 17 সঞ্চয় করার সিদ্ধান্ত নিতে চেয়েছিল for
itj

0

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

অনেক নতুন ভাষায় এমন সিস্টেম রয়েছে যা আপনাকে তাদের ধরণ (রুবি, জাভাস্ক্রিপ্ট, পাইথন ইত্যাদি) নির্দিষ্ট করে না দিয়ে ভেরিয়েবলগুলি ব্যবহার করতে দেয় rub


12
আপনি উল্লিখিত যে কোনও একটি ভাষা (রুবি, জেএস, পাইথন) ভাষার বৈশিষ্ট্য হিসাবে টাইপ অনুকরণ নেই, যদিও বাস্তবায়নগুলি দক্ষতা বাড়াতে এটি ব্যবহার করতে পারে। পরিবর্তে, তারা গতিশীল টাইপিং ব্যবহার করে যেখানে মানগুলির ধরন রয়েছে, তবে ভেরিয়েবল বা অন্যান্য এক্সপ্রেশন নেই।
আমন

2
জেএস আপনাকে প্রকারটি বাদ দিতে দেয় না - এটি আপনাকে যা কিছু তা প্রকাশ করার অনুমতি দেয় না। এটি ডায়নামিক টাইপিং ব্যবহার করে, যেখানে মানগুলিতে প্রকারগুলি থাকে (যেমন: হয় ), ভেরিয়েবল নয় (যেমন কোনও ধরণের মান থাকতে পারে)। এছাড়াও, এ জাতীয় সাধারণ মামলার জন্য টাইপ অনুক্রমের বিষয়টি যেমন সি থেকে প্রকাশের এক দশক আগে সম্ভবত জানা ছিল। truebooleanvar x
স্ক্রিপ্টিন

2
এটি বিবৃতিটি মিথ্যা করে না (কোনও কিছুতে জোর করার জন্য আপনাকে অবশ্যই এটি অনুমতি দিতে হবে)। টাইপ অনুমান বিদ্যমান যে সি এর টাইপ সিস্টেম তার'sতিহাসিক প্রসঙ্গে (একটি নির্দিষ্টভাবে বর্ণিত দার্শনিক যুক্তি বা প্রযুক্তিগত সীমাবদ্ধতার বিপরীতে) ফলাফল হিসাবে পরিবর্তন করে না
ত্রিস্তান বার্নসাইড

2
এই এমএলটি বিবেচনা করে - যা সি এর চেয়ে বেশ পুরানো - এর টাইপ অনুমান রয়েছে, "এটি পুরানো" কোনও ভাল ব্যাখ্যা নয়। যে প্রসঙ্গে সি ব্যবহার করা হয়েছিল এবং বিকাশ করা হয়েছিল (সংকলকটির জন্য খুব ছোট পায়ের ছাপ দাবি করা ছোট মেশিন) সম্ভবত আরও বেশি সম্ভবত বলে মনে হচ্ছে। হেস্কেল, এমএল, হ্যাক সি # তে হরফ সি # রয়েছে এমন ধরণের অনুক্রমের সাথে ভাষার কিছু উদাহরণের পরিবর্তে আপনি কেন গতিশীল টাইপিং ভাষার উল্লেখ করতে পারবেন তা ধারণা নেই - এর মধ্যে আর কোনও অস্পষ্ট বৈশিষ্ট্যই সম্ভবত নেই।
ভু

2
@BradS। ফোরট্রান একটি ভাল উদাহরণ কারণ পরিবর্তনশীল নামের প্রথম অক্ষর নয় হয় একটি টাইপ ঘোষণা, যদি না আপনি ব্যবহার implicit noneযে ক্ষেত্রে আপনি আবশ্যক একটি টাইপ ডিক্লেয়ার।
m
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.