আমি static
সি কোডে বিভিন্ন জায়গায় ব্যবহৃত শব্দটি দেখেছি ; এটি কি সি # তে একটি স্থির ফাংশন / শ্রেণির মতো (যেখানে প্রয়োগটি সামগ্রীর মধ্যে ভাগ করা যায়)?
আমি static
সি কোডে বিভিন্ন জায়গায় ব্যবহৃত শব্দটি দেখেছি ; এটি কি সি # তে একটি স্থির ফাংশন / শ্রেণির মতো (যেখানে প্রয়োগটি সামগ্রীর মধ্যে ভাগ করা যায়)?
উত্তর:
(1) হ'ল আপনি যদি নবাগত হন তবে আরও বিদেশী বিষয়, সুতরাং এখানে একটি উদাহরণ দেওয়া হল:
#include <stdio.h>
void foo()
{
int a = 10;
static int sa = 10;
a += 5;
sa += 5;
printf("a = %d, sa = %d\n", a, sa);
}
int main()
{
int i;
for (i = 0; i < 10; ++i)
foo();
}
এই মুদ্রণ:
a = 15, sa = 15
a = 15, sa = 20
a = 15, sa = 25
a = 15, sa = 30
a = 15, sa = 35
a = 15, sa = 40
a = 15, sa = 45
a = 15, sa = 50
a = 15, sa = 55
a = 15, sa = 60
এটি এমন ক্ষেত্রে কার্যকর হয় যেখানে কোনও ফাংশনকে আমন্ত্রণগুলির মধ্যে কিছুটা অবস্থা রাখা দরকার এবং আপনি বিশ্বব্যাপী ভেরিয়েবল ব্যবহার করতে চান না। সাবধান, তবে, এই বৈশিষ্ট্যটি খুব অল্প পরিমাণে ব্যবহার করা উচিত - এটি আপনার কোডটি থ্রেড-নিরাপদ নয় এবং বোঝা আরও শক্ত করে তোলে।
(২) "অ্যাক্সেস নিয়ন্ত্রণ" বৈশিষ্ট্য হিসাবে ব্যাপকভাবে ব্যবহৃত হয়। আপনার যদি কিছু কার্যকারিতা প্রয়োগ করে .c ফাইল থাকে তবে এটি ব্যবহারকারীদের কাছে সাধারণত কয়েকটি "জনসাধারণ" ফাংশন প্রকাশ করে। এর বাকী কাজগুলি করা উচিত static
, যাতে ব্যবহারকারী তাদের অ্যাক্সেস করতে সক্ষম না করে। এটি এনক্যাপসুলেশন, একটি ভাল অনুশীলন।
উইকিপিডিয়া উদ্ধৃত :
সি প্রোগ্রামিং ল্যাঙ্গুয়েজে স্ট্যাটিকটি বিশ্বব্যাপী ভেরিয়েবল এবং ফাংশনগুলির সাহায্যে ফাইলগুলিতে তাদের স্কোপ সেট করতে ব্যবহৃত হয়। স্থানীয় ভেরিয়েবলগুলিতে, স্ট্যাটিকটি স্বয়ংক্রিয়ভাবে বরাদ্দ মেমরির পরিবর্তে স্থির বরাদ্দ মেমরিতে ভেরিয়েবলটি সংরক্ষণ করতে ব্যবহৃত হয়। ভাষাটি উভয় ধরণের মেমরির প্রয়োগের নির্দেশ দেয় না, স্থায়ীভাবে বরাদ্দ করা মেমরিটি সাধারণত প্রোগ্রামের ডেটা বিভাগে সংকলন সময়ে সংরক্ষিত থাকে, যখন স্বয়ংক্রিয়ভাবে বরাদ্দ হওয়া মেমরিটি সাধারণত ট্রান্সিয়েন্ট কল স্ট্যাক হিসাবে প্রয়োগ করা হয়।
এবং আপনার দ্বিতীয় প্রশ্নের উত্তর দিতে, এটি সি # এর মতো নয়।
সি ++ তে তবে static
শ্রেণিবদ্ধ বৈশিষ্ট্য (একই শ্রেণীর সমস্ত বস্তুর মধ্যে ভাগ করা) এবং পদ্ধতিগুলি সংজ্ঞায়িত করতেও ব্যবহৃত হয়। সি তে কোনও শ্রেণি নেই, সুতরাং এই বৈশিষ্ট্যটি অপ্রাসঙ্গিক।
.c
এবং শিরোলেখের ফাইলগুলির একগুচ্ছ হতে পারে তবে শয়তান সবসময়ই তেমন থাকে যা সাধারণ নয় ।
এখানে আরও একটি ব্যবহার coveredেকে নেই, এবং এটি কোনও ফাংশনের আর্গুমেন্ট হিসাবে অ্যারের প্রকারের ঘোষণার অংশ হিসাবে:
int someFunction(char arg[static 10])
{
...
}
এই প্রসঙ্গে, এটি নির্দিষ্ট করে যে এই ফাংশনে পাস হওয়া আর্গুমেন্টগুলিতে অবশ্যই char
কমপক্ষে 10 টি উপাদান রয়েছে এমন ধরণের অ্যারে হতে হবে। আরও তথ্যের জন্য আমার প্রশ্ন এখানে দেখুন ।
arg[0]
মাধ্যমে arg[9]
মান আছে (যা যে বোঝা ফাংশন একটি নাল পয়েন্টার গ্রহণ করে না)। সংকলকগণ এই তথ্যটি কোনওভাবে অপ্টিমাইজেশনের জন্য ব্যবহার করতে পারে এবং স্থির বিশ্লেষকরা এই তথ্যটি কাজে লাগাতে পারেন যাতে ফাংশনটিকে কখনই নাল পয়েন্টার দেওয়া হয় না (বা যদি তা বলতে পারে তবে নির্দিষ্টর চেয়ে কম উপাদানযুক্ত অ্যারে))
static
C99 এ দেওয়া হয়েছিল । এটি দেড় দশকেরও বেশি পুরনো, তবে সমস্ত সংকলক লেখকরা C99 এর সমস্ত বৈশিষ্ট্যকে গ্রহণ করেন নি - সুতরাং পুরোপুরি C99 অজানা।
int arr[n];
তবে এটি একটি ভিএলএ (পরিবর্তনশীল দৈর্ঘ্যের অ্যারে) , যা C99 এ যুক্ত হয়েছিল। আপনি কি বোঝাতে চেয়েছিলেন?
সংক্ষিপ্ত উত্তর ... এটি নির্ভর করে।
স্থির সংজ্ঞায়িত স্থানীয় ভেরিয়েবলগুলি ফাংশন কলগুলির মধ্যে তাদের মান হারাবে না। অন্য কথায় এগুলি গ্লোবাল ভেরিয়েবল, তবে তারা যে স্থানীয় ফাংশনটিতে সংজ্ঞায়িত হয়েছে তা স্কোপড।
স্থিতিশীল গ্লোবাল ভেরিয়েবলগুলি সি ফাইলে সংজ্ঞায়িত করা হয় তার বাইরে দৃশ্যমান হয় না।
স্ট্যাটিক ফাংশনগুলি সি ফাইলে সংজ্ঞায়িত করা হয় তার বাইরে দৃশ্যমান হয় না।
private
সি তে নেই যদিও আপনার উপমাটি ভাল: স্থিতিশীল কোনও প্রদত্ত ফাইলে জিনিসগুলিকে "ব্যক্তিগত" করে তোলে। এবং সি এর ফাইলগুলি প্রায়শই সি ++ এর ক্লাসে ম্যাপ করে।
মাল্টি-ফাইল ভেরিয়েবল স্কোপ উদাহরণ
এখানে আমি চিত্রিত করেছি যে একাধিক ফাইল জুড়ে স্থিতিশীল কীভাবে ফাংশন সংজ্ঞাগুলির সুযোগকে প্রভাবিত করে।
এসি
#include <stdio.h>
/*
Undefined behavior: already defined in main.
Binutils 2.24 gives an error and refuses to link.
/programming/27667277/why-does-borland-compile-with-multiple-definitions-of-same-object-in-different-c
*/
/*int i = 0;*/
/* Works in GCC as an extension: https://stackoverflow.com/a/3692486/895245 */
/*int i;*/
/* OK: extern. Will use the one in main. */
extern int i;
/* OK: only visible to this file. */
static int si = 0;
void a() {
i++;
si++;
puts("a()");
printf("i = %d\n", i);
printf("si = %d\n", si);
puts("");
}
main.c
#include <stdio.h>
int i = 0;
static int si = 0;
void a();
void m() {
i++;
si++;
puts("m()");
printf("i = %d\n", i);
printf("si = %d\n", si);
puts("");
}
int main() {
m();
m();
a();
a();
return 0;
}
সংকলন এবং চালান:
gcc -c a.c -o a.o
gcc -c main.c -o main.o
gcc -o main main.o a.o
আউটপুট:
m()
i = 1
si = 1
m()
i = 2
si = 2
a()
i = 3
si = 1
a()
i = 4
si = 2
ব্যাখ্যা
si
ফাইলের জন্য পৃথক দুটি ভেরিয়েবল রয়েছেi
যথারীতি স্কোপটি যত ছোট হবে তত ভাল, static
যদি আপনি পারেন তবে সর্বদা ভেরিয়েবল ঘোষণা করুন ।
সি প্রোগ্রামিংয়ে ফাইলগুলি প্রায়শই "শ্রেণি" উপস্থাপন করতে ব্যবহৃত হয় এবং static
ভেরিয়েবলগুলি শ্রেণীর ব্যক্তিগত স্ট্যাটিক সদস্যদের উপস্থাপন করে।
স্ট্যান্ডার্ড এটি সম্পর্কে কি বলে
C99 N1256 খসড়া 6.7.1 "স্টোরেজ-শ্রেণীর নির্দিষ্টকরণকারী" বলছে এটি static
একটি "স্টোরেজ-শ্রেণীর নির্দিষ্টকরণকারী"।
6.2.2 / 3 "সনাক্তকারীদের লিঙ্কেজ" বলতে static
বোঝায় internal linkage
:
যদি কোনও বস্তুর বা কোনও ফাংশনের জন্য কোনও ফাইল স্কোপ শনাক্তকারীর ঘোষণায় স্টোরেজ-শ্রেণীর নির্দিষ্টকরণকারক স্থিতিশীল থাকে, সনাক্তকারীটির অভ্যন্তরীণ সংযোগ থাকে।
এবং 6.2.2 / 2 বলেছেন যে internal linkage
আমাদের উদাহরণের মতো আচরণ করে:
অনুবাদ ইউনিট এবং গ্রন্থাগারগুলির সেটগুলিতে যা একটি সম্পূর্ণ প্রোগ্রাম গঠন করে, বাহ্যিক লিঙ্কেজ সহ একটি নির্দিষ্ট সনাক্তকারীর প্রতিটি ঘোষণা একই বস্তু বা ফাংশনটিকে বোঝায়। একটি অনুবাদ ইউনিটের মধ্যে, অভ্যন্তরীণ লিঙ্কেজ সহ সনাক্তকারীগুলির প্রতিটি ঘোষণা একই বস্তু বা ফাংশনটিকে বোঝায়।
যেখানে "অনুবাদ ইউনিট প্রাকপ্রসেসিংয়ের পরে উত্স ফাইল।
কীভাবে জিসিসি এটি ইএলএফ (লিনাক্স) এর জন্য প্রয়োগ করে?
সঙ্গে STB_LOCAL
বাঁধাই।
যদি আমরা সংকলন করি:
int i = 0;
static int si = 0;
এবং এর সাথে প্রতীক টেবিলটি বিচ্ছিন্ন করুন:
readelf -s main.o
আউটপুট রয়েছে:
Num: Value Size Type Bind Vis Ndx Name
5: 0000000000000004 4 OBJECT LOCAL DEFAULT 4 si
10: 0000000000000000 4 OBJECT GLOBAL DEFAULT 4 i
সুতরাং বাঁধাই তাদের মধ্যে একমাত্র উল্লেখযোগ্য পার্থক্য। Value
এটি কেবল .bss
বিভাগে তাদের অফসেট , সুতরাং আমরা এটির ভিন্নতা প্রত্যাশা করি।
STB_LOCAL
http://www.sco.com/developers/gabi/2003-12-17/ch4.symtab.html এ ইএলএফ স্পেশায় নথিভুক্ত করা হয়েছে :
STB_LOCAL স্থানীয় চিহ্নগুলি তাদের সংজ্ঞা সম্বলিত অবজেক্ট ফাইলের বাইরে দৃশ্যমান নয়। একে অপরের সাথে হস্তক্ষেপ না করে একই নামের স্থানীয় চিহ্নগুলি একাধিক ফাইলে থাকতে পারে
যা প্রতিনিধিত্ব করার জন্য এটি একটি নিখুঁত পছন্দ করে তোলে static
।
স্থির ছাড়া চলকগুলি STB_GLOBAL
হ'ল, এবং চশমাটি বলে:
লিঙ্ক এডিটরটি যখন বেশ কয়েকটি স্থান পরিবর্তনযোগ্য অবজেক্ট ফাইল সংযুক্ত করে, তখন এটি একই নামের সাথে STB_GLOBAL প্রতীকগুলির একাধিক সংজ্ঞা দেয় না।
যা একাধিক অ স্থিত সংজ্ঞাতে লিঙ্ক ত্রুটির সাথে সুসংগত।
যদি আমরা এর সাহায্যে অপ্টিমাইজেশানটি ক্র্যাঙ্ক করি -O3
তবে si
প্রতীকটি পুরোপুরি প্রতীক টেবিল থেকে সরিয়ে দেওয়া হবে: এটি বাহিরের বাইরে থেকে ব্যবহার করা যাবে না। আজ কেন কোনও অপ্টিমাইজেশন নেই কেন স্থির ভেরিয়েবলগুলি প্রতীক টেবিলের কাছে রাখবেন? এগুলি কি কোনও কিছুর জন্য ব্যবহার করা যায়? সম্ভবত ডিবাগিংয়ের জন্য।
আরো দেখুন
static
ফাংশনগুলির জন্য অ্যানালগাস : https://stackoverflow.com/a/30319812/895245static
সঙ্গে extern
, যা নেই "বিপরীত": আমি কিভাবে সোর্স ফাইল মধ্যে ভাগ ভেরিয়েবল extern ব্যবহার করবেন?সি ++ বেনামে নামস্থান
সি ++ তে আপনি স্ট্যাটিকের পরিবর্তে বেনামে নেমস্পেস ব্যবহার করতে চাইতে পারেন যা একই রকম প্রভাব অর্জন করে তবে প্রকারের সংজ্ঞাগুলি গোপন করে: অজ্ঞাত / বেনাম নেমস্পেস বনাম স্থির ফাংশন
এটা নির্ভর করে:
int foo()
{
static int x;
return ++x;
}
ফাংশনটি 1, 2, 3, ইত্যাদি ফেরত আসবে --- ভেরিয়েবল স্ট্যাকের মধ্যে নেই।
static int foo()
{
}
এর অর্থ এই ফাংশনটির কেবলমাত্র এই ফাইলটিতে সুযোগ রয়েছে। সুতরাং এসি এবং বিসি-তে বিভিন্ন foo()
গুলি থাকতে পারে এবং ফুও ভাগ করে নেওয়া বস্তুগুলিতে প্রকাশিত হয় না। সুতরাং আপনি যদি এসি-তে foo সংজ্ঞায়িত করেন তবে আপনি এটি b.c
অন্য কোনও জায়গা থেকে বা এটি অ্যাক্সেস করতে পারবেন না ।
বেশিরভাগ সি লাইব্রেরিতে সমস্ত "ব্যক্তিগত" ফাংশন স্থির এবং বেশিরভাগ "পাবলিক" হয় না।
লোকেরা বলতে থাকে যে সিতে 'স্ট্যাটিক' এর দুটি অর্থ রয়েছে। আমি এটি দেখার একটি বিকল্প উপায় প্রস্তাব করি যা এটির একক অর্থ দেয়:
এর দুটি অর্থ হতে পারে বলে মনে হচ্ছে যে কারণটি হ'ল, সিতে, প্রতিটি আইটেম যেখানে 'স্ট্যাটিক' প্রয়োগ করা যেতে পারে তার মধ্যে এই দুটি বৈশিষ্ট্যের মধ্যে একটি রয়েছে , সুতরাং মনে হয় যে সেই নির্দিষ্ট ব্যবহারের সাথে অন্যটি জড়িত।
উদাহরণস্বরূপ, ভেরিয়েবল বিবেচনা করুন। ফাংশনের বাইরে ঘোষিত চলকগুলি ইতিমধ্যে অধ্যবসায় রয়েছে (ডেটা বিভাগে), সুতরাং 'স্ট্যাটিক' প্রয়োগ করা কেবলমাত্র তাদের বর্তমান স্কোপ (সংকলনের ইউনিট) এর বাইরে দৃশ্যমান করতে পারে না। বিপরীতে, ফাংশনগুলির ভিতরে ঘোষিত ভেরিয়েবলগুলির ইতিমধ্যে বর্তমান সুযোগ (ফাংশন) এর বাইরে অ-দৃশ্যমানতা থাকে, সুতরাং 'স্ট্যাটিক' প্রয়োগ করা কেবল তাদের স্থির রাখতে পারে।
ফাংশনগুলিতে 'স্ট্যাটিক' প্রয়োগ করা ঠিক এটি বৈশ্বিক চলকগুলিতে প্রয়োগের মতো - কোডটি অগত্যা অবিরাম হয় (অন্তত ভাষার মধ্যে) তবে কেবলমাত্র দৃশ্যমানতা পরিবর্তন করা যায়।
দ্রষ্টব্য: এই মন্তব্যগুলি কেবল সি এর ক্ষেত্রে প্রযোজ্য সি ++ এ, শ্রেণি পদ্ধতিতে 'স্ট্যাটিক' প্রয়োগ করা মূলত কীওয়ার্ডটিকে অন্যরকম অর্থ প্রদান করছে। একইভাবে C99 অ্যারে-আর্গুমেন্ট এক্সটেনশনের জন্য।
static
দেয় ।
উইকিপিডিয়া থেকে:
সি প্রোগ্রামিং ল্যাঙ্গুয়েজে স্ট্যাটিকটি বিশ্বব্যাপী ভেরিয়েবল এবং ফাংশনগুলির সাহায্যে ফাইলগুলিতে তাদের স্কোপ সেট করতে ব্যবহৃত হয়। স্থানীয় ভেরিয়েবলগুলিতে, স্ট্যাটিকটি স্বয়ংক্রিয়ভাবে বরাদ্দ মেমরির পরিবর্তে স্থির বরাদ্দ মেমরিতে ভেরিয়েবলটি সংরক্ষণ করতে ব্যবহৃত হয়। ভাষাটি উভয় ধরণের মেমরির প্রয়োগের নির্দেশ দেয় না, স্থায়ীভাবে বরাদ্দ করা মেমরিটি সাধারণত প্রোগ্রামের ডেটা বিভাগে সংকলন সময়ে সংরক্ষিত থাকে, যখন স্বয়ংক্রিয়ভাবে বরাদ্দ হওয়া মেমরিটি সাধারণত ট্রান্সিয়েন্ট কল স্ট্যাক হিসাবে প্রয়োগ করা হয়।
static
বিভিন্ন প্রসঙ্গে বিভিন্ন জিনিস মানে।
আপনি একটি সি ফাংশনে একটি স্ট্যাটিক ভেরিয়েবল ঘোষণা করতে পারেন। এই পরিবর্তনশীলটি কেবল ফাংশনে দৃশ্যমান তবে এটি গ্লোবালের মতো আচরণ করে যে এটি কেবল একবার আরম্ভ করা হয়েছিল এবং এটি এর মান ধরে রাখে। এই উদাহরণে, আপনি যতবার কল করবেন foo()
তখন বর্ধমান সংখ্যা মুদ্রণ করবে print স্ট্যাটিক ভেরিয়েবলটি একবারই শুরু করা হয়।
void foo ()
{
static int i = 0;
printf("%d", i); i++
}
স্ট্যাটিকের আরেকটি ব্যবহার হ'ল আপনি যখন একটি .c ফাইলটিতে কোনও ফাংশন বা গ্লোবাল ভেরিয়েবল প্রয়োগ করেন .obj
তবে ফাইলটি তৈরির বাইরে এর প্রতীকটি দৃশ্যমান হওয়া চাই না । যেমন
static void foo() { ... }
আপনি যদি কোনও ফাংশন স্থিতিতে কোনও ভেরিয়েবল ঘোষণা করেন তবে এর মানটি ফাংশন কল স্ট্যাকের মধ্যে সংরক্ষণ করা হবে না এবং আপনি যখন আবার ফাংশনটি কল করবেন তখন এখনও উপলব্ধ থাকবে।
আপনি যদি বিশ্বব্যাপী পরিবর্তনশীল স্থিতিশীল ঘোষণা করেন তবে এর সুযোগটি আপনি যে ফাইলটিতে ঘোষণা করেছেন তার মধ্যে সীমাবদ্ধ থাকবে। এটি একটি নিয়মিত গ্লোবাল থেকে কিছুটা নিরাপদ যা আপনার পুরো প্রোগ্রাম জুড়েই পড়া এবং সংশোধন করা যেতে পারে।
আমি একটি পুরানো প্রশ্নের উত্তর দিতে ঘৃণা করি, তবে "দ্য সি প্রোগ্রামিং ল্যাঙ্গুয়েজ" এর A4.1 বিভাগে কেএন্ডআর কীভাবে এটি ব্যাখ্যা করে তা কেউ উল্লেখ করেছে বলে আমি মনে করি না।
সংক্ষেপে, স্ট্যাটিক শব্দটি দুটি অর্থ সহ ব্যবহৃত হয় :
static
কীওয়ার্ড ( কীওয়ার্ড হিসাবে কোডে এটির জন্য বড় জোর দেওয়া) একটি ঘোষণার সাথে ব্যবহার করা হয়, তখন এটি সেই বস্তুর অভ্যন্তরীণ লিঙ্কেজ দেয় যাতে এটি কেবল সেই অনুবাদ ইউনিটের মধ্যেই ব্যবহার করা যায়। তবে কীওয়ার্ডটি যদি কোনও ফাংশনে ব্যবহৃত হয় তবে এটি বস্তুর স্টোরেজ শ্রেণি পরিবর্তন করে (বস্তু কেবলমাত্র সেই ফাংশনের মধ্যেই দৃশ্যমান হবে)। স্ট্যাটিকের বিপরীতে হ'ল extern
মূলশব্দ, যা কোনও বস্তুকে বাহ্যিক সংযোগ দেয়।পিটার ভ্যান ডের লিন্ডেন "বিশেষজ্ঞ সি প্রোগ্রামিং" এ এই দুটি অর্থ প্রদান করেছেন:
register
একটি স্টোরেজ-শ্রেণী সুনির্দিষ্টভাবে উল্লেখ করা (C99 6.7.1 সংগ্রহস্থল-শ্রেণী নির্দিষ্টকরী)। এবং এটি কেবল একটি ইঙ্গিতের চেয়ে বেশি, উদাহরণস্বরূপ আপনি সংযোজনকারী কোনও নিবন্ধক বরাদ্দ রাখুক বা না করুক না কেন &
স্টোরেজ ক্লাস সহ কোনও বস্তুর উপরে ঠিকানা-অপারেটর প্রয়োগ করতে পারবেন register
না।
সি-তে স্ট্যাটিকের দুটি ব্যবহারের সুযোগের উপর নির্ভর করে দুটি অর্থ রয়েছে। বিশ্বব্যাপী সুযোগে, যখন কোনও বস্তু ফাইল পর্যায়ে ঘোষণা করা হয়, তার অর্থ হ'ল সেই বস্তুটি কেবলমাত্র সেই ফাইলের মধ্যেই দৃশ্যমান।
অন্য যে কোনও সুযোগে এটি এমন একটি বস্তু ঘোষনা করে যা নির্দিষ্ট স্কোপটি প্রবেশ করানোর সময় বিভিন্ন সময়ের মধ্যে তার মান ধরে রাখে। উদাহরণস্বরূপ, যদি কোনও পদ্ধতির মধ্যে কোনও ইনটকে ডেলচার করা হয়:
void procedure(void)
{
static int i = 0;
i++;
}
পদ্ধতির প্রথম কলটিতে 'i' এর মান শূন্যে শুরু করা হয়, এবং পদ্ধতিটি कॉल করার পরে প্রতিটি সময় মানটি ধরে রাখা হয়। যদি 'আমি' মুদ্রিত হয় তবে এটি 0, 1, 2, 3, এর ক্রম আউটপুট করবে ...
এটি লক্ষ করা গুরুত্বপূর্ণ যে ফাংশনে স্থিতিশীল ভেরিয়েবলগুলি সেই ফাংশনে প্রথম প্রবেশের সময় সূচনা হয় এবং তাদের কল শেষ হওয়ার পরেও অব্যাহত থাকে; রিকার্সিভ ফাংশনগুলির ক্ষেত্রে স্থির পরিবর্তনশীল কেবল একবার আরম্ভ হয় এবং সমস্ত পুনরাবৃত্ত কলগুলিতে এবং এমনকি ফাংশনটির কল শেষ হওয়ার পরেও স্থির থাকে।
যদি ভেরিয়েবলটি কোনও ফাংশনের বাইরে তৈরি করা হয়, তবে এর অর্থ হ'ল প্রোগ্রামার কেবল উত্স-ফাইলটিতে ভেরিয়েবলটি ব্যবহার করতে সক্ষম হয় ভেরিয়েবলটি ঘোষিত হয়েছে।
যদি আপনি এটি কোনও mytest.c
ফাইলে ঘোষণা করেন :
static int my_variable;
তারপরে এই পরিবর্তনশীলটি কেবল এই ফাইল থেকে দেখা যাবে। ভেরিয়েবলটি অন্য কোথাও রফতানি করা যায় না।
যদি আপনি কোনও ফাংশনের অভ্যন্তরে ঘোষিত হন তবে চলকটির মানটি প্রতিবার ফাংশনটির জন্য ডাকা হয়।
স্ট্যাটিক ফাংশনটি ফাইলের বাইরে থেকে রফতানি করা যায় না। সুতরাং কোনও *.c
ফাইলে আপনি ফাংশনগুলি এবং ভেরিয়েবলগুলি স্থিতিকর ঘোষণা করে তা লুকিয়ে রাখছেন।
সিতে স্ট্যাটিক ভেরিয়েবলগুলি প্রোগ্রামটির আজীবন থাকে।
যদি কোনও ফাংশনে সংজ্ঞায়িত করা হয় তবে তাদের স্থানীয় সুযোগ রয়েছে, অর্থাত্ সেগুলি কেবল সেই ফাংশনের অভ্যন্তরে প্রবেশ করা যায়। স্ট্যাটিক ভেরিয়েবলের মান ফাংশন কলগুলির মধ্যে সংরক্ষণ করা হয়।
উদাহরণ স্বরূপ:
void function()
{
static int var = 1;
var++;
printf("%d", var);
}
int main()
{
function(); // Call 1
function(); // Call 2
}
উপরের প্রোগ্রামে, var
ডেটা বিভাগে সংরক্ষণ করা হয়। এর জীবদ্দশায় পুরো সি প্রোগ্রাম।
ফাংশন কল 1 var
পরে, 2 var
হয়ে। ফাংশন কল 2 পরে, 3 হয়ে।
var
ফাংশন কলগুলির মধ্যে এর মানটি ধ্বংস হয় না।
যদি var
অ স্ট্যাটিক এবং স্থানীয় ভেরিয়েবলের মধ্যে থাকে তবে এটি সি প্রোগ্রামে স্ট্যাক সেগমেন্টে সংরক্ষণ করা হবে। যেহেতু ফাংশনটি ফিরে আসার পরে ফাংশনের স্ট্যাক ফ্রেমটি নষ্ট হয়ে যায়, এর মানটিও var
নষ্ট হয়।
প্রারম্ভিক স্ট্যাটিক ভেরিয়েবলগুলি সি প্রোগ্রামের ডেটা সেগমেন্টে সংরক্ষণ করা হয় তবে অবিচ্ছিন্নতরগুলি বিএসএস বিভাগে সংরক্ষিত থাকে।
স্ট্যাটিক সম্পর্কে অন্য তথ্য: কোনও পরিবর্তনশীল যদি বৈশ্বিক এবং স্থির হয় তবে এর সি প্রোগ্রামের জীবনকাল থাকে তবে এর ফাইলের সুযোগ থাকে। এটি কেবলমাত্র সেই ফাইলটিতে দৃশ্যমান।
এটি চেষ্টা করার জন্য:
static int x;
int main()
{
printf("Accessing in same file%d", x):
}
extern int x;
func()
{
printf("accessing in different file %d",x); // Not allowed, x has the file scope of file1.c
}
run gcc -c file1.c
gcc -c file2.c
এখন তাদের ব্যবহার করে লিঙ্ক করার চেষ্টা করুন:
gcc -o output file1.o file2.o
এটি লিঙ্কারের ত্রুটি দেয় কারণ x ফাইলের সুযোগ 1 ফাইল 1। আছে এবং লিঙ্কার ফাইল 2.c এ ব্যবহৃত ভেরিয়েবল এক্সের রেফারেন্সটি সমাধান করতে সক্ষম হবে না।
তথ্যসূত্র:
static int var = 1;
প্রতিটি সময়ই মানটিকে এক
স্ট্যাটিক ভেরিয়েবল হ'ল একটি বিশেষ চলক যা আপনি কোনও ফাংশনে ব্যবহার করতে পারেন এবং এটি কলগুলির মধ্যে ডেটা সংরক্ষণ করে এবং এটি কলগুলির মধ্যে এটি মুছবে না। উদাহরণ স্বরূপ:
void func(){
static int count; // If you don't declare its value, the value automatically initializes to zero
printf("%d, ", count);
++count;
}
void main(){
while(true){
func();
}
}
আউটপুট:
0, 1, 2, 3, 4, 5, ...
printf("%d, ", count); count++;
`প্রিন্টএফ ("% d, ", গণনা ++) দিয়ে প্রতিস্থাপন করতে পারেন (এটি বিবেচ্য নয়: পি)।
স্ট্যাটিক ভেরিয়েবলগুলির মান সংরক্ষণ করার সম্পত্তি রয়েছে ক্ষেত্রের বাইরে যাওয়ার পরেও রাখে! সুতরাং, স্থিতিশীল ভেরিয়েবলগুলি তাদের পূর্ববর্তী মানটি পূর্বের স্কোপে সংরক্ষণ করে এবং নতুন স্কোপে আর আরম্ভ হয় না।
উদাহরণস্বরূপ এটি দেখুন - প্রোগ্রামটি চলাকালীন একটি স্ট্যাটিক ইন্ট ভেরিয়েবল স্মৃতিতে থেকে যায়। একটি ফাংশন কল যেখানে ভেরিয়েবল ঘোষিত হয়েছিল সেখানে যখন একটি স্বাভাবিক বা অটো ভেরিয়েবল নষ্ট হয়।
#include<stdio.h>
int fun()
{
static int count = 0;
count++;
return count;
}
int main()
{
printf("%d ", fun());
printf("%d ", fun());
return 0;
}
এটি আউটপুট দেবে: 1 2
স্থির হিসাবে ঘোষিত হওয়ায় 1 মেমরিতে থাকে
স্ট্যাটিক ভেরিয়েবলগুলি (গ্লোবাল ভেরিয়েবলের মতো) স্পষ্টভাবে আরম্ভ না করা হলে 0 হিসাবে আরম্ভ করা হয়। উদাহরণস্বরূপ নীচের প্রোগ্রামে, x এর মান 0 হিসাবে মুদ্রিত হবে, যখন y এর মান কিছু আবর্জনা। আরও বিশদ জন্য এটি দেখুন।
#include <stdio.h>
int main()
{
static int x;
int y;
printf("%d \n %d", x, y);
}
এটি আউটপুট দেবে: 0 [কিছু_গারবাজ_ভ্যালু]
এইগুলিই আমি খুঁজে পেলাম যেগুলি কোনও নবজাতকের জন্য উপরে ব্যাখ্যা করা হয়নি!
সি প্রোগ্রামিংয়ে, static
একটি সংরক্ষিত কীওয়ার্ড যা আজীবন পাশাপাশি দৃশ্যমানতা উভয়ই নিয়ন্ত্রণ করে। যদি আমরা কোনও ফাংশনের অভ্যন্তরে কোনও পরিবর্তনশীল স্থির হিসাবে ঘোষণা করি তবে এটি কেবলমাত্র সেই ফাংশন জুড়েই দৃশ্যমান হবে। এই ব্যবহারে, এই স্ট্যাটিক ভেরিয়েবলের জীবনকাল শুরু হবে যখন কোনও ফাংশন কল হবে এবং এটি সেই ফাংশনটি সম্পাদনের পরে ধ্বংস হয়ে যাবে। আপনি নিম্নলিখিত উদাহরণটি দেখতে পারেন:
#include<stdio.h>
int counterFunction()
{
static int count = 0;
count++;
return count;
}
int main()
{
printf("First Counter Output = %d\n", counterFunction());
printf("Second Counter Output = %d ", counterFunction());
return 0;
}
উপরের প্রোগ্রামটি আমাদের এই আউটপুট দেবে:
First Counter Output = 1
Second Counter Output = 1
কারণ আমরা ফাংশনটি কল করার সাথে সাথে এটি শুরু করে দেবে count = 0
। এবং যখন আমরা counterFunction
এটি কার্যকর করি এটি গণনা ভেরিয়েবল ধ্বংস করে দেয়।