আমি কেন PROGMEM এর সাথে অ্যারের পরিবর্তে পয়েন্টার ব্যবহার করতে পারি না?


11

আমি বর্তমানে স্ট্রিং স্টোরেজের জন্য র্যামের পরিবর্তে ফ্ল্যাশ ব্যবহার করার জন্য কয়েকটি লাইব্রেরি পরিবর্তন করছি যাতে আমার কোনও প্রকল্পের আরআরএমে চলে না যায়।

লাইব্রেরির কয়েকটি স্ট্রিং এইভাবে ঘোষণা করা হয়েছে:

const char *testStringA = "ABC";

আমি সাধারণত এটি করা দেখি তার থেকে আলাদা This

const char testStringB[] = "DEF";

যাইহোক, আমি মনে করি যে ঘোষণায় কনস্ট এবং ইনিশিয়েশনের সময় এই দুটি সমতুল্য। উভয় কোডে সূক্ষ্ম কাজ।

আমি এগুলি ফ্ল্যাশ-এ স্থানান্তরিত করার চেষ্টা করেছি:

const prog_char *testStringC PROGMEM = "GHI";

আমি তখন দেখতে পেলাম যে এটি কাজ করে না। এটি মুদ্রিত হওয়ার পরে গাবলডেগুক তৈরি করছিল।

তবে এর আরও সাধারণ ধাঁচ অনুসরণ করে:

const prog_char testStringD[] PROGMEM = "JKL";

ঠিকভাবে কাজ করে.

আমি বিচ্ছিন্নতাতে দেখতে পাচ্ছি:

00000068 <testStringC>:
  68:   04 01                                               ..

0000006a <_ZL11testStringD>:
  6a:   4a 4b 4c 00                                         JKL.

সুতরাং এটি স্পষ্ট করে যে পয়েন্টার এবং PROGMEM এর ফলাফল স্ট্রিং / অ্যারে শুরু করা হচ্ছে না।

কেন?

উদাহরণ কোড:

#include <avr/pgmspace.h>

const int BUFFER_LEN = 20;

const char *testStringA = "ABC";
const char testStringB[] = "DEF";
const prog_char *testStringC PROGMEM = "GHI";
const prog_char testStringD[] PROGMEM = "JKL";

void setup()
{
    Serial.begin(9600);
}

void loop()
{
    char buffer[BUFFER_LEN];

    Serial.println(testStringA);
    Serial.println(testStringB);

    strncpy_P(buffer, testStringC, BUFFER_LEN);
    Serial.println(buffer);

    strncpy_P(buffer, testStringD, BUFFER_LEN);
    Serial.println(buffer);

    delay(1000);

}

উত্তর:


6

ঠিক আছে, স্ট্যাক ওভারফ্লো প্রশ্ন সি: চর পয়েন্টার এবং অ্যারের মধ্যে পার্থক্য সম্পর্কে উত্তরের এই প্রশ্নের উত্তর বুদ্ধি দিয়ে দেওয়া হয়েছে ।

মূলত, আপনি যা দিয়ে প্রোগ্রাম হিসাবে ঘোষণা করছেন,

const prog_char testStringD[] PROGMEM = "JKL";

এটি অ্যারে এবং মেমরি উভয়ই এটি নির্দেশ করে, এটি হ'ল অ্যারের উপাদানগুলি, বর্তমানের স্কোপ স্ট্যাক উভয়ই। যেখানে সাথে:

const prog_char* testStringC PROGMEM = "GHI";

আপনি এমন একটি ধ্রুব স্ট্রিংয়ের জন্য একটি PROGMEM পয়েন্টার ঘোষণা করেন যা মেমোরিতে অন্য কোথাও থাকতে পারে তবে PROGMEM স্ট্রিং হিসাবে ঘোষিত হয় না।

আমি হয়নি না যে পরীক্ষা, কিন্তু আপনি ডিক্লেয়ার করার চেষ্টা করা উচিত:

const prog_char* testStringC PROGMEM = F("GHI");

প্রকৃতপক্ষে PROGMEM স্থানের মধ্যে পয়েন্ট স্ট্রিং বরাদ্দ করতে। আমার ধারণা, এটি কাজ করা উচিত, আরডুইনোর F()ম্যাক্রো ব্যবহার করে যা প্রচুর পরিমাণে বয়লারপ্লিট কোড যুক্ত করে অ্যারে ঘোষণার মতোই একই ফলাফল পেতে পারে।

মন্তব্যে যেমন বলা হয়েছে, বৈশ্বিক প্রসঙ্গে না হলে PSTR()ম্যাক্রোর পরিবর্তে F()ম্যাক্রো ব্যবহার করা যেতে পারে ।

সহজ আরও ভাল: অ্যারে ঘোষণা ব্যবহার করুন, পয়েন্টারটি নয়!

সিএফ যে অন্য উত্তর , __flashযোগ্যতা তৃতীয় সমাধান ;-)


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

এফ () ফ্ল্যাশস্ট্রিংহেল্পারকে ফিরিয়ে দেয় যা মূলত একই রকম, তবে পিএসটিআর () ব্যবহার করে সূক্ষ্মভাবে কাজ করে (যতক্ষণ আপনি কোনও ফাংশনের অভ্যন্তরে কনসেটগুলি আনেন)।
সাইবার্বিবনস

প্রকৃতপক্ষে, আমি আসলে প্রথমে PSTR()ম্যাক্রোর পরামর্শ দিয়েছিলাম তবে F()জমা দেওয়ার আগে পরিবর্তিত হয়েছি, কারণ আপনার কনসেন্টগুলি আপনার প্রশ্নাবলীতে বিশ্বব্যাপী, তাই আমি উভয় প্রসঙ্গে কাজ করা উচিত এমন একটিটির সাথে লেগে থাকতে পছন্দ করি।
zmo

3

এই লাইনটি কি:

const prog_char *testStringC PROGMEM = "GHI";

না হ'ল স্ট্রিংয়ের অক্ষরগুলিকে এসআরএমে অনুলিপি করার জন্য প্রলোগ কোডটি লিখতে হয় এবং তারপরে ফ্ল্যাশ-এ সঞ্চিত পয়েন্টারটি এই এসআরএম লোকেশনে সূচনা করে । আপনাকে অবশ্যই স্বাভাবিক উপায়ের মাধ্যমে পয়েন্টারটি লোড করতে হবে এবং তারপরে যথারীতি পয়েন্টারটিকে অবজ্ঞা করুন।

const char *str = pgm_read_word(&testStringC);
Serial.println(str);

এই লাইন:

const prog_char testStringD[] PROGMEM = "JKL";

ফ্ল্যাশে অক্ষরের অ্যারে তৈরি করে , এটি আপনাকে প্রত্যাশার সাথে অ্যাক্সেস করার অনুমতি দেয়।

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