"অচল" সি এর অর্থ কী?


1135

আমি staticসি কোডে বিভিন্ন জায়গায় ব্যবহৃত শব্দটি দেখেছি ; এটি কি সি # তে একটি স্থির ফাংশন / শ্রেণির মতো (যেখানে প্রয়োগটি সামগ্রীর মধ্যে ভাগ করা যায়)?



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

5
@ প্যালেকের একটি এসও নীতি রয়েছে যে ট্যাগ তালিকায় উপস্থিত আইটেমগুলি শিরোনামে অপ্রয়োজনীয়। সাইটটি স্বয়ংক্রিয়ভাবে আসল ওয়েব সাইটে সি যুক্ত করবে। "সি স্ট্যাটিক" এর জন্য একটি গুগল এই উত্তরটিকে শীর্ষ হিট হিসাবে দেয়। কেন এটি পরিবর্তিত হয়েছিল তার কারণ হ'ল এই প্রশ্নটি এখন এসও সি ল্যাঙ্গুয়েজ FAQ এর অংশ এবং যুক্ত সমস্ত পোস্টই কিছুটা পালিশ হয়ে যায়।
লন্ডিন

1
@ লন্ডিন আমি শিরোনামে "সি" রাখতে পছন্দ করি কারণ এসও কেবলমাত্র শিরোনামে একটি ট্যাগ যুক্ত করে (সর্বাধিক সাধারণ?)। যদি কোনও দিন "সিনট্যাক্স" সি এর চেয়ে বেশি প্রশ্নে পৌঁছায় (যেহেতু এটি ক্রস ভাষার জিনিস)? আমি বরং স্পষ্ট আচরণটি ব্যবহার করব :-) সম্পাদনা করুন: আহ তবে অন্যথায় মেটা প্রশ্ন রয়েছে: meta.stackexchange.com/questions/19190/…
Ciro Santilli

উত্তর:


1519
  1. একটি ফাংশনের অভ্যন্তরে একটি স্থির পরিবর্তনশীল তার অনুরোধের মধ্যে এর মান রাখে।
  2. একটি স্ট্যাটিক গ্লোবাল ভেরিয়েবল বা একটি ফাংশন কেবলমাত্র প্রদর্শিত ফাইলটিতে "দেখা" হয়

(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শ্রেণিবদ্ধ বৈশিষ্ট্য (একই শ্রেণীর সমস্ত বস্তুর মধ্যে ভাগ করা) এবং পদ্ধতিগুলি সংজ্ঞায়িত করতেও ব্যবহৃত হয়। সি তে কোনও শ্রেণি নেই, সুতরাং এই বৈশিষ্ট্যটি অপ্রাসঙ্গিক।


179
প্যাক্স, ওপি স্থিতিশীল সম্পর্কে জানে না, তাই আপনি তাকে সংকলন ইউনিট এবং ফাইলগুলির মধ্যে পার্থক্যের মধ্যে নিমগ্ন করার পরামর্শ দিচ্ছেন? :-)
এলি বেন্ডারস্কি

138
সংকলক ইউনিট হ'ল সংকলক দেখতে পাওয়া একক ফাইল। আপনার .c ফাইলটিতে অন্যান্য .c ফাইল অন্তর্ভুক্ত থাকতে পারে তবে প্রিপ্রসেসরগুলি অন্তর্ভুক্ত করে বাছাই করার পরে সংকলকটি শেষ পর্যন্ত কেবল একটি "সংকলন ইউনিট" দেখতে পায়।
এলি বেন্ডারস্কি

81
@robUK: সংকলক এমনকি .h ফাইলগুলি সম্পর্কেও জানে না - এগুলি প্রসেসরটিতে .c ফাইলগুলিতে একত্রিত হয়। সুতরাং হ্যাঁ আপনি বলতে পারেন যে .c ফাইল, এতে অন্তর্ভুক্ত সমস্ত শিরোলেখ একটি একক সংকলন ইউনিট।
এলি বেন্ডারস্কি

6
@ টনিড সম্ভবত এটি বিভ্রান্তিকর, তবে সংকলনটি কীভাবে কাজ করে এটি। এটি সাধারণত এক .cএবং শিরোলেখের ফাইলগুলির একগুচ্ছ হতে পারে তবে শয়তান সবসময়ই তেমন থাকে যা সাধারণ নয়
পিটার্ফ

7
@ টনিডি সংকলক সংকলন করে। প্রিপ্রোসেসর প্রিপ্রোসেসিং করে। টুলচেনকে 'সংকলক' বললে এটি কী হয় বা কী তা পরিবর্তন করে না।
মাইলস রাউথ

231

এখানে আরও একটি ব্যবহার coveredেকে নেই, এবং এটি কোনও ফাংশনের আর্গুমেন্ট হিসাবে অ্যারের প্রকারের ঘোষণার অংশ হিসাবে:

int someFunction(char arg[static 10])
{
    ...
}

এই প্রসঙ্গে, এটি নির্দিষ্ট করে যে এই ফাংশনে পাস হওয়া আর্গুমেন্টগুলিতে অবশ্যই charকমপক্ষে 10 টি উপাদান রয়েছে এমন ধরণের অ্যারে হতে হবে। আরও তথ্যের জন্য আমার প্রশ্ন এখানে দেখুন


3
আমি মনে করি না সি এর অ্যারে যুক্তি আছে? লিনাস টোরভাল্ডস লোকেদের এই কাজটি করার জন্য ক্ষিপ্তভাবে প্রকাশ করে।
সুপ্রজামী

13
@jamieb: সি অ্যারে আর্গুমেন্ট নেই, কিন্তু এই নির্দিষ্ট সিনট্যাক্স মানে যে ফাংশন আশা arg[0]মাধ্যমে arg[9]মান আছে (যা যে বোঝা ফাংশন একটি নাল পয়েন্টার গ্রহণ করে না)। সংকলকগণ এই তথ্যটি কোনওভাবে অপ্টিমাইজেশনের জন্য ব্যবহার করতে পারে এবং স্থির বিশ্লেষকরা এই তথ্যটি কাজে লাগাতে পারেন যাতে ফাংশনটিকে কখনই নাল পয়েন্টার দেওয়া হয় না (বা যদি তা বলতে পারে তবে নির্দিষ্টর চেয়ে কম উপাদানযুক্ত অ্যারে))
ড্রিমলাক্স

19
@ কিউস - এটি একটি নতুন ওভারলোড হওয়া অর্থ যা staticC99 এ দেওয়া হয়েছিল । এটি দেড় দশকেরও বেশি পুরনো, তবে সমস্ত সংকলক লেখকরা C99 এর সমস্ত বৈশিষ্ট্যকে গ্রহণ করেন নি - সুতরাং পুরোপুরি C99 অজানা।
শুভ গ্রিন কিড নেপস

@ সুপ্রজামি আমি "অ্যারে আর্গুমেন্ট" বলতে কী বোঝাতে চাইছি তা আমি 100% নিশ্চিত নই , তবে যদি আপনি বোঝাতে চান int arr[n];তবে এটি একটি ভিএলএ (পরিবর্তনশীল দৈর্ঘ্যের অ্যারে) , যা C99 এ যুক্ত হয়েছিল। আপনি কি বোঝাতে চেয়েছিলেন?
রাস্তাজেদি

170

সংক্ষিপ্ত উত্তর ... এটি নির্ভর করে।

  1. স্থির সংজ্ঞায়িত স্থানীয় ভেরিয়েবলগুলি ফাংশন কলগুলির মধ্যে তাদের মান হারাবে না। অন্য কথায় এগুলি গ্লোবাল ভেরিয়েবল, তবে তারা যে স্থানীয় ফাংশনটিতে সংজ্ঞায়িত হয়েছে তা স্কোপড।

  2. স্থিতিশীল গ্লোবাল ভেরিয়েবলগুলি সি ফাইলে সংজ্ঞায়িত করা হয় তার বাইরে দৃশ্যমান হয় না।

  3. স্ট্যাটিক ফাংশনগুলি সি ফাইলে সংজ্ঞায়িত করা হয় তার বাইরে দৃশ্যমান হয় না।


8
সুতরাং "স্ট্যাটিক ফাংশন" এবং "ব্যক্তিগত ফাংশন" অর্থ একই জিনিস? একইভাবে "স্ট্যাটিক গ্লোবাল ভেরিয়েবল" এবং "বেসরকারী গ্লোবাল ভেরিয়েবলগুলি" একই জিনিস?
ব্যবহারকারী 1599964

40
এটি সি সম্পর্কে। সি তে কোনও ব্যক্তিগত / পাবলিক নেই
ক্রিস

19
@ user1599964 privateসি তে নেই যদিও আপনার উপমাটি ভাল: স্থিতিশীল কোনও প্রদত্ত ফাইলে জিনিসগুলিকে "ব্যক্তিগত" করে তোলে। এবং সি এর ফাইলগুলি প্রায়শই সি ++ এর ক্লাসে ম্যাপ করে।
সিরো সান্তিলি 冠状 病毒 审查 六四 事件

66

মাল্টি-ফাইল ভেরিয়েবল স্কোপ উদাহরণ

এখানে আমি চিত্রিত করেছি যে একাধিক ফাইল জুড়ে স্থিতিশীল কীভাবে ফাংশন সংজ্ঞাগুলির সুযোগকে প্রভাবিত করে।

এসি

#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_LOCALhttp://www.sco.com/developers/gabi/2003-12-17/ch4.symtab.html এ ইএলএফ স্পেশায় নথিভুক্ত করা হয়েছে :

STB_LOCAL স্থানীয় চিহ্নগুলি তাদের সংজ্ঞা সম্বলিত অবজেক্ট ফাইলের বাইরে দৃশ্যমান নয়। একে অপরের সাথে হস্তক্ষেপ না করে একই নামের স্থানীয় চিহ্নগুলি একাধিক ফাইলে থাকতে পারে

যা প্রতিনিধিত্ব করার জন্য এটি একটি নিখুঁত পছন্দ করে তোলে static

স্থির ছাড়া চলকগুলি STB_GLOBALহ'ল, এবং চশমাটি বলে:

লিঙ্ক এডিটরটি যখন বেশ কয়েকটি স্থান পরিবর্তনযোগ্য অবজেক্ট ফাইল সংযুক্ত করে, তখন এটি একই নামের সাথে STB_GLOBAL প্রতীকগুলির একাধিক সংজ্ঞা দেয় না।

যা একাধিক অ স্থিত সংজ্ঞাতে লিঙ্ক ত্রুটির সাথে সুসংগত।

যদি আমরা এর সাহায্যে অপ্টিমাইজেশানটি ক্র্যাঙ্ক করি -O3তবে siপ্রতীকটি পুরোপুরি প্রতীক টেবিল থেকে সরিয়ে দেওয়া হবে: এটি বাহিরের বাইরে থেকে ব্যবহার করা যাবে না। আজ কেন কোনও অপ্টিমাইজেশন নেই কেন স্থির ভেরিয়েবলগুলি প্রতীক টেবিলের কাছে রাখবেন? এগুলি কি কোনও কিছুর জন্য ব্যবহার করা যায়? সম্ভবত ডিবাগিংয়ের জন্য।

আরো দেখুন

সি ++ বেনামে নামস্থান

সি ++ তে আপনি স্ট্যাটিকের পরিবর্তে বেনামে নেমস্পেস ব্যবহার করতে চাইতে পারেন যা একই রকম প্রভাব অর্জন করে তবে প্রকারের সংজ্ঞাগুলি গোপন করে: অজ্ঞাত / বেনাম নেমস্পেস বনাম স্থির ফাংশন


39

এটা নির্ভর করে:

int foo()
{
   static int x;
   return ++x;
}

ফাংশনটি 1, 2, 3, ইত্যাদি ফেরত আসবে --- ভেরিয়েবল স্ট্যাকের মধ্যে নেই।

AC:

static int foo()
{
}

এর অর্থ এই ফাংশনটির কেবলমাত্র এই ফাইলটিতে সুযোগ রয়েছে। সুতরাং এসি এবং বিসি-তে বিভিন্ন foo()গুলি থাকতে পারে এবং ফুও ভাগ করে নেওয়া বস্তুগুলিতে প্রকাশিত হয় না। সুতরাং আপনি যদি এসি-তে foo সংজ্ঞায়িত করেন তবে আপনি এটি b.cঅন্য কোনও জায়গা থেকে বা এটি অ্যাক্সেস করতে পারবেন না ।

বেশিরভাগ সি লাইব্রেরিতে সমস্ত "ব্যক্তিগত" ফাংশন স্থির এবং বেশিরভাগ "পাবলিক" হয় না।


18
স্ট্যাক বা হিপ নয় এক্স উল্লেখ করার জন্য +1। এটি স্থির মেমরি স্পেসে।
গুব00st

1
@ গুব00 স্ট্যাটিক মেমরি স্পেস? আপনি "ডেটা বিভাগ" বলতে চেয়েছিলেন ...?
ইউশা আলেয়ুব

24

লোকেরা বলতে থাকে যে সিতে 'স্ট্যাটিক' এর দুটি অর্থ রয়েছে। আমি এটি দেখার একটি বিকল্প উপায় প্রস্তাব করি যা এটির একক অর্থ দেয়:

  • আইটেমটিতে 'স্ট্যাটিক' প্রয়োগ করা সেই আইটেমটিকে দুটি বৈশিষ্ট্যযুক্ত করতে বাধ্য করে: (ক) এটি বর্তমান সুযোগের বাইরে দৃশ্যমান নয়; (খ) এটি অবিচল।

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

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

ফাংশনগুলিতে 'স্ট্যাটিক' প্রয়োগ করা ঠিক এটি বৈশ্বিক চলকগুলিতে প্রয়োগের মতো - কোডটি অগত্যা অবিরাম হয় (অন্তত ভাষার মধ্যে) তবে কেবলমাত্র দৃশ্যমানতা পরিবর্তন করা যায়।

দ্রষ্টব্য: এই মন্তব্যগুলি কেবল সি এর ক্ষেত্রে প্রযোজ্য সি ++ এ, শ্রেণি পদ্ধতিতে 'স্ট্যাটিক' প্রয়োগ করা মূলত কীওয়ার্ডটিকে অন্যরকম অর্থ প্রদান করছে। একইভাবে C99 অ্যারে-আর্গুমেন্ট এক্সটেনশনের জন্য।


আপনার (ক) সর্বোপরি অনর্থক। এর ক্ষেত্রের বাইরে যে কোনও ভেরিয়েবল দৃশ্যমান। এটি কেবল সুযোগের সংজ্ঞা। আপনি যা বলতে চাচ্ছেন তাকে সি স্ট্যান্ডার্ডে লিংকেজ বলা হয় । একটি সনাক্তকারীকে অভ্যন্তরীণ লিঙ্কেজstatic দেয় ।
জেনস

16

উইকিপিডিয়া থেকে:

সি প্রোগ্রামিং ল্যাঙ্গুয়েজে স্ট্যাটিকটি বিশ্বব্যাপী ভেরিয়েবল এবং ফাংশনগুলির সাহায্যে ফাইলগুলিতে তাদের স্কোপ সেট করতে ব্যবহৃত হয়। স্থানীয় ভেরিয়েবলগুলিতে, স্ট্যাটিকটি স্বয়ংক্রিয়ভাবে বরাদ্দ মেমরির পরিবর্তে স্থির বরাদ্দ মেমরিতে ভেরিয়েবলটি সংরক্ষণ করতে ব্যবহৃত হয়। ভাষাটি উভয় ধরণের মেমরির প্রয়োগের নির্দেশ দেয় না, স্থায়ীভাবে বরাদ্দ করা মেমরিটি সাধারণত প্রোগ্রামের ডেটা বিভাগে সংকলন সময়ে সংরক্ষিত থাকে, যখন স্বয়ংক্রিয়ভাবে বরাদ্দ হওয়া মেমরিটি সাধারণত ট্রান্সিয়েন্ট কল স্ট্যাক হিসাবে প্রয়োগ করা হয়।


16

static বিভিন্ন প্রসঙ্গে বিভিন্ন জিনিস মানে।

  1. আপনি একটি সি ফাংশনে একটি স্ট্যাটিক ভেরিয়েবল ঘোষণা করতে পারেন। এই পরিবর্তনশীলটি কেবল ফাংশনে দৃশ্যমান তবে এটি গ্লোবালের মতো আচরণ করে যে এটি কেবল একবার আরম্ভ করা হয়েছিল এবং এটি এর মান ধরে রাখে। এই উদাহরণে, আপনি যতবার কল করবেন foo()তখন বর্ধমান সংখ্যা মুদ্রণ করবে print স্ট্যাটিক ভেরিয়েবলটি একবারই শুরু করা হয়।

    void foo ()
    {
    static int i = 0;
    printf("%d", i); i++
    }
  2. স্ট্যাটিকের আরেকটি ব্যবহার হ'ল আপনি যখন একটি .c ফাইলটিতে কোনও ফাংশন বা গ্লোবাল ভেরিয়েবল প্রয়োগ করেন .objতবে ফাইলটি তৈরির বাইরে এর প্রতীকটি দৃশ্যমান হওয়া চাই না । যেমন

    static void foo() { ... }

8

আপনি যদি কোনও ফাংশন স্থিতিতে কোনও ভেরিয়েবল ঘোষণা করেন তবে এর মানটি ফাংশন কল স্ট্যাকের মধ্যে সংরক্ষণ করা হবে না এবং আপনি যখন আবার ফাংশনটি কল করবেন তখন এখনও উপলব্ধ থাকবে।

আপনি যদি বিশ্বব্যাপী পরিবর্তনশীল স্থিতিশীল ঘোষণা করেন তবে এর সুযোগটি আপনি যে ফাইলটিতে ঘোষণা করেছেন তার মধ্যে সীমাবদ্ধ থাকবে। এটি একটি নিয়মিত গ্লোবাল থেকে কিছুটা নিরাপদ যা আপনার পুরো প্রোগ্রাম জুড়েই পড়া এবং সংশোধন করা যেতে পারে।


8

আমি একটি পুরানো প্রশ্নের উত্তর দিতে ঘৃণা করি, তবে "দ্য সি প্রোগ্রামিং ল্যাঙ্গুয়েজ" এর A4.1 বিভাগে কেএন্ডআর কীভাবে এটি ব্যাখ্যা করে তা কেউ উল্লেখ করেছে বলে আমি মনে করি না।

সংক্ষেপে, স্ট্যাটিক শব্দটি দুটি অর্থ সহ ব্যবহৃত হয় :

  1. স্ট্যাটিক দুটি স্টোরেজ ক্লাসগুলির মধ্যে একটি (অন্যটি স্বয়ংক্রিয় হচ্ছে)। একটি স্ট্যাটিক অবজেক্ট অনুরোধের মধ্যে তার মান রাখে। সমস্ত ব্লকের বাইরে ঘোষিত অবজেক্টগুলি সর্বদা স্থির থাকে এবং স্বয়ংক্রিয়ভাবে তৈরি করা যায় না।
  2. কিন্তু, যখন static কীওয়ার্ড ( কীওয়ার্ড হিসাবে কোডে এটির জন্য বড় জোর দেওয়া) একটি ঘোষণার সাথে ব্যবহার করা হয়, তখন এটি সেই বস্তুর অভ্যন্তরীণ লিঙ্কেজ দেয় যাতে এটি কেবল সেই অনুবাদ ইউনিটের মধ্যেই ব্যবহার করা যায়। তবে কীওয়ার্ডটি যদি কোনও ফাংশনে ব্যবহৃত হয় তবে এটি বস্তুর স্টোরেজ শ্রেণি পরিবর্তন করে (বস্তু কেবলমাত্র সেই ফাংশনের মধ্যেই দৃশ্যমান হবে)। স্ট্যাটিকের বিপরীতে হ'ল externমূলশব্দ, যা কোনও বস্তুকে বাহ্যিক সংযোগ দেয়।

পিটার ভ্যান ডের লিন্ডেন "বিশেষজ্ঞ সি প্রোগ্রামিং" এ এই দুটি অর্থ প্রদান করেছেন:

  • একটি ফাংশনের অভ্যন্তরে, কলগুলির মধ্যে এর মান ধরে রাখে।
  • ফাংশন স্তরে, কেবল এই ফাইলটিতে দৃশ্যমান।

একটি তৃতীয় স্টোরেজ ক্লাস আছে, রেজিস্টার । কিছু লোক চতুর্থ স্টোরেজ ক্লাসের ক্ষেত্রেও বরাদ্দকৃত ম্যালোক এবং বন্ধুবান্ধব দ্বারা সঞ্চয়স্থানের জন্য কেস তৈরি করে ।
জেনস

@ জেনসের 'রেজিস্টার' সংকলকের কেবল একটি ইঙ্গিত; সি উত্স থেকে রেজিস্ট্রেশন স্টোরেজ প্রয়োগ করা যাবে না। সুতরাং আমি এটিকে স্টোরেজ শ্রেণি হিসাবে বিবেচনা করব না।
জার্মাননাড

1
@GermanNerd আমি তোমার দৃশ্য সঙ্গে ভয় আইএসও সি স্ট্যান্ডার্ড সহমত নন যেমন পরিষ্কারভাবে তোলে registerএকটি স্টোরেজ-শ্রেণী সুনির্দিষ্টভাবে উল্লেখ করা (C99 6.7.1 সংগ্রহস্থল-শ্রেণী নির্দিষ্টকরী)। এবং এটি কেবল একটি ইঙ্গিতের চেয়ে বেশি, উদাহরণস্বরূপ আপনি সংযোজনকারী কোনও নিবন্ধক বরাদ্দ রাখুক বা না করুক না কেন &স্টোরেজ ক্লাস সহ কোনও বস্তুর উপরে ঠিকানা-অপারেটর প্রয়োগ করতে পারবেন registerনা।
জেনস

@ জেনস সম্পর্কে & আমাকে সম্পর্কে মনে করিয়ে দেওয়ার জন্য ধন্যবাদ। আমি হয়ত অনেক বেশি সি ++ করেছি ..... যাইহোক, যখন 'নিবন্ধক' একটি স্টোরেজ-শ্রেণীর নির্দিষ্টকরণকারী, বাস্তবে সংকলক সম্ভবত (অকেজো) 'অটো' স্পেসিফায়ারের জন্য 'রেজিস্টার হিসাবে একই মেশিন কোড তৈরি করবে 'স্পেসিফায়ার। সুতরাং কেবলমাত্র বাকিটি হ'ল কোনও ঠিকানা নিতে সক্ষম না হওয়ার সোর্স-কোড স্তরের সীমাবদ্ধতা। বিটিডাব্লু, এই সামান্য আলোচনা আমাকে নেটবিনে একটি বাগ খুঁজে পেতে পরিচালিত করেছিল; আমার সর্বশেষ আপডেটের পরে, এটি নতুন সি প্রকল্পের জি ++ সরঞ্জাম চেইনে ডিফল্ট!
জার্মাননার্ড

6

সি-তে স্ট্যাটিকের দুটি ব্যবহারের সুযোগের উপর নির্ভর করে দুটি অর্থ রয়েছে। বিশ্বব্যাপী সুযোগে, যখন কোনও বস্তু ফাইল পর্যায়ে ঘোষণা করা হয়, তার অর্থ হ'ল সেই বস্তুটি কেবলমাত্র সেই ফাইলের মধ্যেই দৃশ্যমান।

অন্য যে কোনও সুযোগে এটি এমন একটি বস্তু ঘোষনা করে যা নির্দিষ্ট স্কোপটি প্রবেশ করানোর সময় বিভিন্ন সময়ের মধ্যে তার মান ধরে রাখে। উদাহরণস্বরূপ, যদি কোনও পদ্ধতির মধ্যে কোনও ইনটকে ডেলচার করা হয়:

void procedure(void)
{
   static int i = 0;

   i++;
}

পদ্ধতির প্রথম কলটিতে 'i' এর মান শূন্যে শুরু করা হয়, এবং পদ্ধতিটি कॉल করার পরে প্রতিটি সময় মানটি ধরে রাখা হয়। যদি 'আমি' মুদ্রিত হয় তবে এটি 0, 1, 2, 3, এর ক্রম আউটপুট করবে ...


5

এটি লক্ষ করা গুরুত্বপূর্ণ যে ফাংশনে স্থিতিশীল ভেরিয়েবলগুলি সেই ফাংশনে প্রথম প্রবেশের সময় সূচনা হয় এবং তাদের কল শেষ হওয়ার পরেও অব্যাহত থাকে; রিকার্সিভ ফাংশনগুলির ক্ষেত্রে স্থির পরিবর্তনশীল কেবল একবার আরম্ভ হয় এবং সমস্ত পুনরাবৃত্ত কলগুলিতে এবং এমনকি ফাংশনটির কল শেষ হওয়ার পরেও স্থির থাকে।

যদি ভেরিয়েবলটি কোনও ফাংশনের বাইরে তৈরি করা হয়, তবে এর অর্থ হ'ল প্রোগ্রামার কেবল উত্স-ফাইলটিতে ভেরিয়েবলটি ব্যবহার করতে সক্ষম হয় ভেরিয়েবলটি ঘোষিত হয়েছে।


5

যদি আপনি এটি কোনও mytest.cফাইলে ঘোষণা করেন :

static int my_variable;

তারপরে এই পরিবর্তনশীলটি কেবল এই ফাইল থেকে দেখা যাবে। ভেরিয়েবলটি অন্য কোথাও রফতানি করা যায় না।

যদি আপনি কোনও ফাংশনের অভ্যন্তরে ঘোষিত হন তবে চলকটির মানটি প্রতিবার ফাংশনটির জন্য ডাকা হয়।

স্ট্যাটিক ফাংশনটি ফাইলের বাইরে থেকে রফতানি করা যায় না। সুতরাং কোনও *.cফাইলে আপনি ফাংশনগুলি এবং ভেরিয়েবলগুলি স্থিতিকর ঘোষণা করে তা লুকিয়ে রাখছেন।


4

সিতে স্ট্যাটিক ভেরিয়েবলগুলি প্রোগ্রামটির আজীবন থাকে।

যদি কোনও ফাংশনে সংজ্ঞায়িত করা হয় তবে তাদের স্থানীয় সুযোগ রয়েছে, অর্থাত্‍ সেগুলি কেবল সেই ফাংশনের অভ্যন্তরে প্রবেশ করা যায়। স্ট্যাটিক ভেরিয়েবলের মান ফাংশন কলগুলির মধ্যে সংরক্ষণ করা হয়।

উদাহরণ স্বরূপ:

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নষ্ট হয়।

প্রারম্ভিক স্ট্যাটিক ভেরিয়েবলগুলি সি প্রোগ্রামের ডেটা সেগমেন্টে সংরক্ষণ করা হয় তবে অবিচ্ছিন্নতরগুলি বিএসএস বিভাগে সংরক্ষিত থাকে।

স্ট্যাটিক সম্পর্কে অন্য তথ্য: কোনও পরিবর্তনশীল যদি বৈশ্বিক এবং স্থির হয় তবে এর সি প্রোগ্রামের জীবনকাল থাকে তবে এর ফাইলের সুযোগ থাকে। এটি কেবলমাত্র সেই ফাইলটিতে দৃশ্যমান।

এটি চেষ্টা করার জন্য:

file1.c

static int x;

int main()
{
    printf("Accessing in same file%d", x):
}

file2.c

    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 এ ব্যবহৃত ভেরিয়েবল এক্সের রেফারেন্সটি সমাধান করতে সক্ষম হবে না।

তথ্যসূত্র:

  1. http://en.wikipedia.org/wiki/Translation_unit_(programming)
  2. http://en.wikipedia.org/wiki/Call_stack

আমি বুঝতে পারি যে ডেটা অবিরাম রয়েছে, যার অর্থ এটি প্রতিটি ফাংশন কলের পরে তা হারাবে না, তবে কেন static int var = 1;প্রতিটি সময়ই মানটিকে এক
ইমাস

3

স্ট্যাটিক ভেরিয়েবল হ'ল একটি বিশেষ চলক যা আপনি কোনও ফাংশনে ব্যবহার করতে পারেন এবং এটি কলগুলির মধ্যে ডেটা সংরক্ষণ করে এবং এটি কলগুলির মধ্যে এটি মুছবে না। উদাহরণ স্বরূপ:

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, ", গণনা ++) দিয়ে প্রতিস্থাপন করতে পারেন (এটি বিবেচ্য নয়: পি)।
রাস্তাজেদি

2

একটি স্ট্যাটিক ভেরিয়েবল মান বিভিন্ন ফাংশন কলগুলির মধ্যে স্থির থাকে এবং স্কিটগুলি স্থানীয় ব্লকের মধ্যে সীমাবদ্ধ থাকে একটি স্ট্যাটিক ভার সর্বদা মান 0 দিয়ে শুরু হয়


2

এখানে দুটি মামলা রয়েছে:

(1) স্থানীয় ভেরিয়েবল ঘোষিত static: স্ট্যাকের পরিবর্তে ডেটা বিভাগে বরাদ্দ। আপনি যখন ফাংশনটিকে আবার কল করবেন তখন এর মান বজায় থাকবে।

(২) গ্লোবাল ভেরিয়েবল বা ফাংশন ঘোষিত static: বাইরের সংকলন ইউনিটের অদৃশ্য (যেমন সংযোগের সময় প্রতীক টেবিলের স্থানীয় চিহ্ন) are


1

স্ট্যাটিক ভেরিয়েবলগুলির মান সংরক্ষণ করার সম্পত্তি রয়েছে ক্ষেত্রের বাইরে যাওয়ার পরেও রাখে! সুতরাং, স্থিতিশীল ভেরিয়েবলগুলি তাদের পূর্ববর্তী মানটি পূর্বের স্কোপে সংরক্ষণ করে এবং নতুন স্কোপে আর আরম্ভ হয় না।

উদাহরণস্বরূপ এটি দেখুন - প্রোগ্রামটি চলাকালীন একটি স্ট্যাটিক ইন্ট ভেরিয়েবল স্মৃতিতে থেকে যায়। একটি ফাংশন কল যেখানে ভেরিয়েবল ঘোষিত হয়েছিল সেখানে যখন একটি স্বাভাবিক বা অটো ভেরিয়েবল নষ্ট হয়।

#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 [কিছু_গারবাজ_ভ্যালু]

এইগুলিই আমি খুঁজে পেলাম যেগুলি কোনও নবজাতকের জন্য উপরে ব্যাখ্যা করা হয়নি!


-1

সি প্রোগ্রামিংয়ে, 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এটি কার্যকর করি এটি গণনা ভেরিয়েবল ধ্বংস করে দেয়।


2
> উপরের প্রোগ্রামটি আমাদের এই আউটপুটটি দেবে: প্রথম কাউন্টার আউটপুট = 1 দ্বিতীয় কাউন্টার আউটপুট = 1 <সত্য নয়। স্ট্যাটিক ভেরিয়েবলগুলি একবারই শুরু করা হয়। সুতরাং আউটপুট হবে 1, তারপর 2, এবং আরও।
জার্মাননাড
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.