#include <stdio.h>
int main() {
float a = 1234.5f;
printf("%d\n", a);
return 0;
}
এটি একটি প্রদর্শিত হয় 0!! কীভাবে সম্ভব? যুক্তি কী?
আমি ইচ্ছাকৃতভাবে একটি করা আছে %dমধ্যে printfআচরণ অধ্যয়ন করতে বিবৃতি printf।
উত্তর:
এটি কারণ এমনটি %dপ্রত্যাশা করে intতবে আপনি একটি ফ্ল্যাট সরবরাহ করেছেন।
ফ্লোট মুদ্রণ করতে %e/ %f/ ব্যবহার করুন %g।
কেন 0 মুদ্রিত হয়: ভাসমান পয়েন্ট নম্বরটি doubleপ্রেরণের আগে রূপান্তরিত হয় printf। সামান্য এরিয়ানে ডাবল প্রতিনিধিত্বের সংখ্যা 1234.5
00 00 00 00 00 4A 93 40
এ %d32-বিট পূর্ণসংখ্যা গ্রহণ করে, তাই শূন্যটি মুদ্রিত হয়। (পরীক্ষা হিসাবে, আপনি printf("%d, %d\n", 1234.5f);আউটপুট পেতে পারে 0, 1083394560।)
6.5.2.2/7 থেকে প্রিন্টফের প্রোটোটাইপ হিসাবে কেন floatরূপান্তরিত হয়?doubleint printf(const char*, ...)
কোনও ফাংশন প্রোটোটাইপ ঘোষকের মধ্যে উপবৃত্তাকার স্বরলিপিটি সর্বশেষ ঘোষিত প্যারামিটারের পরে যুক্তির ধরণের রূপান্তর বন্ধ করে দেয়। ডিফল্ট আর্গুমেন্ট প্রচারগুলি পেছনের আর্গুমেন্টে সঞ্চালিত হয়।
এবং 6.5.2.2/6 থেকে,
যদি কথিত ফাংশনটিকে বোঝায় এমন অভিব্যক্তিটির কোনও প্রোটোটাইপ অন্তর্ভুক্ত না থাকে তবে প্রতিটি যুক্তিতে পূর্ণসংখ্যা প্রচার হয় এবং প্রকারের যুক্তিগুলিতে
floatপ্রচার হয়double। এই বলা হয় ডিফল্ট যুক্তি প্রচার ।
(এটি জানতে পেরে ধন্যবাদ অলোক।)
printfএকটি বৈকল্পিক ফাংশন, এবং মানটি বলে যে ভেরিয়াদিক ফাংশনগুলির জন্য, একটি পাস floatকরার doubleআগে রূপান্তরিত হয় ।
printf()পূজা অনির্ধারিত আচরণ ।
টেকনিক্যালি ভাষী সেখানে নেই , প্রতিটি গ্রন্থাগার কার্যকরী নিজস্ব, সেইজন্য এবং, অধ্যয়ন করার চেষ্টা আপনার পদ্ধতি করছেন আপনি কি করছেন অনেক ব্যবহার হতে যাচ্ছে না দ্বারা 'র আচরণ। আপনি আপনার সিস্টেমে এর আচরণ সম্পর্কে অধ্যয়ন করার চেষ্টা করতে পারেন, এবং যদি তা হয় তবে আপনার ডকুমেন্টেশনটি পড়া উচিত এবং আপনার লাইব্রেরির জন্য এটি উপলভ্য থাকলে সোর্স কোডটি দেখে নেওয়া উচিত । printfprintfprintfprintf
উদাহরণস্বরূপ, আমার ম্যাকবুকে আমি 1606416304আপনার প্রোগ্রামের সাথে আউটপুট পাই ।
এটি বলার পরে, আপনি যখন floatকোনও বৈকল্পিক ফাংশনে floatএকটি পাস করেন , এটি একটি হিসাবে পাস হয় double। সুতরাং, আপনার প্রোগ্রামটি aএকটি হিসাবে ঘোষণার সমতুল্য double।
এটির বাইটগুলি পরীক্ষা doubleকরতে, আপনি এখানে একটি সাম্প্রতিক প্রশ্নের উত্তরটি দেখতে পারেন O
আসুন এটি করা যাক:
#include <stdio.h>
int main(void)
{
double a = 1234.5f;
unsigned char *p = (unsigned char *)&a;
size_t i;
printf("size of double: %zu, int: %zu\n", sizeof(double), sizeof(int));
for (i=0; i < sizeof a; ++i)
printf("%02x ", p[i]);
putchar('\n');
return 0;
}
আমি যখন উপরের প্রোগ্রামটি চালাই, তখন আমি পাই:
size of double: 8, int: 4
00 00 00 00 00 4a 93 40
সুতরাং, প্রথম চারটি বাইটগুলি double0 এ পরিণত হয়েছে , এটিই সম্ভবত আপনি 0আপনার printfকলটির আউটপুট হিসাবে পেয়েছেন ।
আরও আকর্ষণীয় ফলাফলের জন্য, আমরা প্রোগ্রামটি কিছুটা পরিবর্তন করতে পারি:
#include <stdio.h>
int main(void)
{
double a = 1234.5f;
int b = 42;
printf("%d %d\n", a, b);
return 0;
}
আমি যখন আমার ম্যাকবুকে উপরের প্রোগ্রামটি চালাই, তখন আমি পাই:
42 1606416384
একটি লিনাক্স মেশিনে একই প্রোগ্রাম সহ, আমি পাই:
0 1083394560
intআর্গুমেন্টগুলি বিভিন্ন রেজিস্টারে doubleআর্গুমেন্টের চেয়ে পাস হয় । printfসাথে যুক্তিটি %dগ্রহণ করে intযেটি 42 এবং দ্বিতীয়টি %dসম্ভবত আবর্জনা মুদ্রণ করে যেহেতু দ্বিতীয় intযুক্তি ছিল না ।
%dসুনির্দিষ্টভাবে উল্লেখ করা বলেprintf একটি পূর্ণসংখ্যা প্রত্যাশিত। সুতরাং ভাসমানের প্রথম চার (বা দুটি, প্ল্যাটফর্মের উপর নির্ভর করে) বাইটগুলি একটি পূর্ণসংখ্যা হিসাবে ব্যাখ্যা করা হয়। সেগুলি যদি শূন্য হয় তবে একটি শূন্য মুদ্রিত হয়
1234.5 এর বাইনারি উপস্থাপনাটি এরকম
1.00110100101 * 2^10 (exponent is decimal ...)
সি সংকলক সহ যা floatআইইইই 7575৫ ডাবল মান হিসাবে বাস্তবে প্রতিনিধিত্ব করে , বাইটগুলি হবে (যদি আমি কোনও ভুল না করি)
01000000 10010011 01001010 00000000 00000000 00000000 00000000 00000000
সামান্য সমাপ্তি (যেমন সর্বনিম্ন তাৎপর্যপূর্ণ বাইট প্রথম আসবে) সহ একটি ইন্টেল (x86) সিস্টেমে এই বাইট ক্রমটি বিপরীত হয় যাতে প্রথম চারটি বাইট শূন্য হয়। printfঅর্থাত , কী ছাপে ...
আইইইই 7575৫ অনুযায়ী ভাসমান পয়েন্ট উপস্থাপনার জন্য এই উইকিপিডিয়া নিবন্ধটি দেখুন ।
কারণ আপনি অপরিজ্ঞাত আচরণটি করেছেন: আপনি মুদ্রণ () পদ্ধতির চুক্তির লঙ্ঘন করে এর পরামিতিগুলির ধরণের বিষয়ে মিথ্যা কথা বলেছিলেন, তাই সংকলক যা খুশি তা করতে নির্দ্বিধায়। এটি প্রোগ্রামটি আউটপুট তৈরি করতে পারে "ডক্সজালক একটি নিয়নহেড !!!" এবং প্রযুক্তিগতভাবে এটি এখনও সঠিক হবে।
কারণটি হ'ল printf()একটি দুর্দান্ত বোবা ফাংশন। এটি মোটেই প্রকার পরীক্ষা করে না। যদি আপনি বলেন প্রথম যুক্তিটি একটি int(এবং এটিই আপনি যা বলছেন %d) তবে এটি আপনাকে বিশ্বাস করে এবং এটির জন্য প্রয়োজনীয় বাইটগুলি লাগে int। এই ক্ষেত্রে, আপনার মেশিনটি চার-বাইট intএবং আট-বাইট ব্যবহার করে double(এটি floatএকটি doubleঅভ্যন্তরে রূপান্তরিত হয় printf()), প্রথম চারটি বাইট aকেবল শূন্য হবে এবং এটি মুদ্রিত হবে।
%d দশমিক হয়
%f ভাসা হয়
এখানে আরও দেখুন ।
আপনি 0 পেয়ে যাচ্ছেন কারণ ভাসমান এবং পূর্ণসংখ্যা পৃথকভাবে উপস্থাপিত হয়।
আপনার কেবল প্রাসঙ্গিক ডেটা প্রকারের (যথাযথ, ভাসা, স্ট্রিং ইত্যাদি) সাথে উপযুক্ত ফর্ম্যাট স্পেসিফায়ার (% d,% f,% s, ইত্যাদি) ব্যবহার করতে হবে।
আপনি% f চান না% d
আরে এটি কিছু মুদ্রণ করতে হয়েছিল তাই এটি একটি 0 মুদ্রিত। সি 0 এ মনে রাখবেন সব কিছু!
এটি কোনও পূর্ণসংখ্যা নয়। ব্যবহার করার চেষ্টা করুন %f।