টাইপডেফ স্থির দৈর্ঘ্যের অ্যারে


210

আমাকে একটি 24-বিট ডেটা টাইপ সংজ্ঞায়িত করতে হবে I আমি char[3]প্রকারটি উপস্থাপন করতে ব্যবহার করছি । আমি কি টাইপ char[3]করতে পারি type24? আমি একটি কোড নমুনা চেষ্টা করেছিলাম। আমি typedef char[3] type24;আমার হেডার ফাইলটি রেখেছি। সংকলক এটি সম্পর্কে কোনও অভিযোগ করেনি। তবে যখন আমি void foo(type24 val) {}আমার সি ফাইলে কোনও ফাংশন সংজ্ঞায়িত করেছি, তখন এটি অভিযোগ করেছিল। আমি এর type24_to_int32(type24 val)পরিবর্তে ফাংশনগুলি সংজ্ঞায়িত করতে সক্ষম হতে চাই type24_to_int32(char value[3])

উত্তর:


320

টাইপিডেফ হবে

typedef char type24[3];

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

আরও ভাল সমাধান হতে পারে

typedef struct type24 { char x[3]; } type24;

আপনি সম্ভবত এর unsigned charপরিবর্তে ব্যবহার করতে চান char, যেহেতু পরবর্তীটির প্রয়োগ-সংজ্ঞায়িত স্বাক্ষর রয়েছে।


10
টাইপয়েফড অ্যারেগুলিকে পরামিতি হিসাবে যুক্ত করার সাথে জড়িত কোণার কেসগুলির বর্ণনা করার মতো কোনও সুন্দর নথী রয়েছে? উদাহরণস্বরূপ, একটি ফাংশন একটি প্যারামিটার নেয় যদি type24 foo, কি মাপ, ধরন এবং অর্থ হবে foo, *foo, **foo, &foo, এবং &&foo? বছরের পর বছর ধরে এই জাতীয় কোনও অভিব্যক্তির অর্থ এবং বৈধতা পরিবর্তিত হয়েছে?
সুপারক্যাট

4
সম্ভবত 24-বিট ডেটা টাইপ হিসাবে কাঠামো প্যাকিং ক্যাভিয়েট উল্লেখ করার যোগ্য, আরজিবি চিত্রের ডেটার মতো আলাদাভাবে সংজ্ঞায়িত প্যাকিং শব্দার্থক দিয়ে কিছুতে মানচিত্রের উদ্দেশ্যে হতে পারে।
sh1

2
@ sh1: সমস্ত আধুনিক রিয়েল-ওয়ার্ল্ড এবিআই সম্পর্কে আমি অবগত রয়েছি - এমনকি মিসাইলযুক্ত অ্যাক্সেস খুব ব্যয়বহুল - এমনকি কাঠামোগুলি তাদের সদস্যদের কাঠামো ব্যতীত শক্তিশালী প্রান্তিককরণের প্রয়োজনীয়তা অর্জন করে না। অবশ্যই ওপি বা অন্য কেউ এই পদ্ধতির ব্যবহার করছে তাদের দাবিটি যাচাই করা উচিত যদি এটি তাদের প্রোগ্রামের আচরণ এবং বহনযোগ্যতার জন্য গুরুত্বপূর্ণ হয়ে থাকে।
আর .. গীটহাব বন্ধ করুন সহায়তা আইসিসি

4
@ আর .. এর একটি অংশ বিভ্রান্তিমূলক - সি তে অ্যারেগুলি সর্বদা রেফারেন্স দ্বারা পাস করা হয়, অর্থাত্ যদি আপনি কোনও ফাংশনের আর্গুমেন্ট হিসাবে পাস হওয়া অ্যারেটি পরিবর্তন করেন তবে আপনি কেবলমাত্র ফাংশনটির প্রসঙ্গে নয় বিশ্বব্যাপী এটি করেন। এটি বলা হচ্ছে, একটি যুক্তিও দিতে পারে যে সি অ্যারেগুলিতে সর্বদা মান দ্বারা পাস করা হয় যেহেতু আমরা কেবল প্রথম উপাদানটির ঠিকানাটি পাস করি, যা কলি স্ট্যাকের স্ট্যাকের অনুলিপি করা হয়। তবে উভয় ক্ষেত্রেই উত্তরটি বিভ্রান্তিকর।
বাইবো 4'14

1
@ বোবোগো: এটি প্যাকিং নয়, এটি কেবল অযৌক্তিক প্যাডিংয়ের সন্নিবেশ নয়। কাঠামোর প্রান্তিককরণটি তার সদস্যদের মধ্যে সর্বাধিক প্রান্তিককরণ, যার সকলেরই প্রান্তিককরণ রয়েছে 1.
আর .. গিথহাব স্টপ হেল্পিং আইসিসি

49

তুমি চাও

typedef char type24[3];

সি প্রকারের ঘোষণাগুলি সেভাবে অদ্ভুত। আপনি টাইপটি ঠিক সেই জায়গায় রেখেছিলেন যেখানে ভেরিয়েবলের নামটি চলে যাবে যদি আপনি সেই ধরণের ভেরিয়েবল ঘোষণা করে থাকেন।


33

আর থেকে .. এর উত্তর :

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

এটির অ্যারে যে ব্যবহারকারীরা দেখতে পান না তারা সম্ভবত এরকম কিছু লিখবেন (যা ব্যর্থ হয়):

#include <stdio.h>

typedef int twoInts[2];

void print(twoInts *twoIntsPtr);
void intermediate (twoInts twoIntsAppearsByValue);

int main () {
    twoInts a;
    a[0] = 0;
    a[1] = 1;
    print(&a);
    intermediate(a);
    return 0;
}
void intermediate(twoInts b) {
    print(&b);
}

void print(twoInts *c){
    printf("%d\n%d\n", (*c)[0], (*c)[1]);
}

এটি নিম্নলিখিত সতর্কতাগুলির সাথে সংকলন করবে:

In function intermediate’:
warning: passing argument 1 of print from incompatible pointer type [enabled by default]
    print(&b);
     ^
note: expected int (*)[2]’ but argument is of type int **’
    void print(twoInts *twoIntsPtr);
         ^

এবং নিম্নলিখিত আউটপুট উত্পাদন করে:

0
1
-453308976
32767

13

অ্যারে সি এর মান অনুসারে ফাংশন প্যারামিটার হিসাবে পাস করা যায় না

আপনি একটি স্ট্রাক্টরে অ্যারে রাখতে পারেন:

typedef struct type24 {
    char byte[3];
} type24;

এবং তারপরে এটি মান দ্বারা পাস করুন তবে অবশ্যই এটি ব্যবহার করা কম সুবিধাজনক: x.byte[0]পরিবর্তে x[0]

আপনার ফাংশনটি type24_to_int32(char value[3])আসলে পয়েন্টার দিয়ে যায়, মান দিয়ে নয়। এটি হুবহু সমতুল্য type24_to_int32(char *value), এবং এটি 3উপেক্ষা করা হবে।

আপনি পয়েন্টার দ্বারা সুখী পাসিং হন, আপনি পারে অ্যারে দিয়ে বিদ্ধ কি:

type24_to_int32(const type24 *value);

এটি পয়েন্টার-থেকে-অ্যারে পাস করবে, পয়েন্টার-থেকে-প্রথম-উপাদানটি নয়, সুতরাং আপনি এটি হিসাবে ব্যবহার করুন:

(*value)[0]

আমি নিশ্চিত না যে এটি সত্যিই একটি লাভ, যেহেতু আপনি যদি দুর্ঘটনাক্রমে লিখেন value[1]তবে বোকামি কিছু ঘটে।


2
আমি মনে করি decayকোথাও শব্দটির উল্লেখ করে এই উত্তরটির উন্নতি করা যেতে পারে (এবং সম্ভবত এটি বিন্যাস করে যে অ্যারে ফিরিয়ে দেওয়ার জন্য পরিস্থিতি আরও খারাপ - যা কিছুতেই কাজ করে না)।
ফ্রেরিচ রাবাবে

9

ফাংশন আর্গুমেন্ট বা টেমপ্লেট প্যারামিটার হিসাবে অ্যারে টাইপটি সঠিকভাবে ব্যবহার করতে, টাইপডেফের পরিবর্তে একটি কাঠামো তৈরি করুন, তারপরে operator[]স্ট্রাক্টটিতে একটি যুক্ত করুন যাতে আপনি অ্যারেটিকে কার্যকারিতার মতো রাখতে পারেন:

typedef struct type24 {
  char& operator[](int i) { return byte[i]; }
  char byte[3];
} type24;

type24 x;
x[2] = 'r';
char c = x[2];

14
এটি একটি সি প্রশ্ন, সি ++ নয়। আমরাও char&না operator[]যে সি বিদ্যমান
মাইকেল মরিস

3

টাইপেডেফ অ্যারে কেন বিভ্রান্তিকরভাবে বেমানান হতে পারে তার একটি ছোট উদাহরণ এখানে। অন্যান্য উত্তরগুলি একতরফা প্রদান করে।

#include <stdio.h>
typedef char type24[3];

int func(type24 a) {
        type24 b;
        printf("sizeof(a) is %zu\n",sizeof(a));
        printf("sizeof(b) is %zu\n",sizeof(b));
        return 0;
}

int main(void) {
        type24 a;
        return func(a);
}

এটি আউটপুট উত্পাদন করে

sizeof(a) is 8
sizeof(b) is 3

কারণ প্যারামিটার হিসাবে টাইপ 24 একটি পয়েন্টার। (সি-তে, অ্যারেগুলি সর্বদা পয়েন্টার হিসাবে পাস করা হয়)) জিসিসি 8 সংকলক, ডিফল্টরূপে একটি সতর্কতা জারি করবে, ধন্যবাদ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.