আমার যদি এমন কোনও ফাংশন থাকে যা ফলাফল intএবং ফলাফল তৈরি করে string, আমি কীভাবে উভয়কে একটি ফাংশন থেকে ফিরিয়ে দেব?
যতদূর আমি বলতে পারি আমি কেবল একটি জিনিস ফিরতে পারি, ফাংশন নামের আগের ধরণ অনুসারে।
আমার যদি এমন কোনও ফাংশন থাকে যা ফলাফল intএবং ফলাফল তৈরি করে string, আমি কীভাবে উভয়কে একটি ফাংশন থেকে ফিরিয়ে দেব?
যতদূর আমি বলতে পারি আমি কেবল একটি জিনিস ফিরতে পারি, ফাংশন নামের আগের ধরণ অনুসারে।
উত্তর:
আমি জানি না আপনার stringকী, তবে আমি ধরে নেব যে এটি নিজের স্মৃতি পরিচালনা করে।
আপনার দুটি সমাধান রয়েছে:
1: structআপনার প্রয়োজনীয় সমস্ত ধরণের সমন্বিত এমন একটি ফেরৎ দিন।
struct Tuple {
int a;
string b;
};
struct Tuple getPair() {
Tuple r = { 1, getString() };
return r;
}
void foo() {
struct Tuple t = getPair();
}
2: মানগুলি পাস করার জন্য পয়েন্টার ব্যবহার করুন।
void getPair(int* a, string* b) {
// Check that these are not pointing to NULL
assert(a);
assert(b);
*a = 1;
*b = getString();
}
void foo() {
int a, b;
getPair(&a, &b);
}
আপনি কোনটি বেছে বেছে বেছে বেছে বেছে বেছে বেছে বেছে বেছে বেছে বেছে বেছে বেছে বেছে বেছে বেছে বেছে বেছে বেছে বেছে বেছে বেছে বেছে বেছে বেছে কোনটি বেছে বেছে ব্যবহার করেন।
char *এবং একটি হিসাবে প্রেরণ করব size_tযদি না এটি ফাংশনটির নিজস্ব স্ট্রিং এবং / অথবা ফিরে আসার জন্য বরাদ্দ দেওয়া একেবারে জরুরী NULL।
getPairতারপরে অবনমিত হয় । আপনি যা করছেন তার উপর নির্ভর করে (ওপি কখনই এটি কোনও সি প্রশ্ন হিসাবে স্পষ্ট করে না), বরাদ্দটি উদ্বেগের বিষয় হতে পারে তবে এটি সাধারণত সি ++ জমিতে হয় না (রিটার্ন ভ্যালু অপ্টিমাইজেশন এই সমস্তটি সংরক্ষণ করে) এবং সি জমিতে ডেটা অনুলিপি সাধারণত স্পষ্টভাবে ঘটে (মাধ্যমে strncpyবা যাই হোক না কেন)।
Option 1: ইনট এবং স্ট্রিং সহ স্ট্রাক্ট ঘোষণা করুন এবং স্ট্রাক ভেরিয়েবলটি ফিরিয়ে দিন।
struct foo {
int bar1;
char bar2[MAX];
};
struct foo fun() {
struct foo fooObj;
...
return fooObj;
}
Option 2: আপনি দুটির মধ্যে একটিকে পয়েন্টারের মাধ্যমে পাস করতে পারেন এবং পয়েন্টারের মাধ্যমে প্রকৃত প্যারামিটারে পরিবর্তন করতে পারেন এবং অন্যটিকে যথারীতি ফিরে আসতে পারেন:
int fun(char **param) {
int bar;
...
strcpy(*param,"....");
return bar;
}
বা
char* fun(int *param) {
char *str = /* malloc suitably.*/
...
strcpy(str,"....");
*param = /* some value */
return str;
}
Option 3: অপশনটির অনুরূপ ২. আপনি উভয়ই পয়েন্টারের মাধ্যমে পাস করতে পারেন এবং ফাংশন থেকে কিছুই ফিরিয়ে দিতে পারেন:
void fun(char **param1,int *param2) {
strcpy(*param1,"....");
*param2 = /* some calculated value */
}
int fun(char *param, size_t len)
strcpyউদাহরণস্বরূপ আমরা কীভাবে ব্যবহার করি তার অনুরূপ কিছু ।
যেহেতু আপনার ফলাফলের ধরণগুলির মধ্যে একটি স্ট্রিং (এবং আপনি সি ব্যবহার করছেন, সি ++ নয়), সুতরাং আমি পয়েন্টারগুলিকে আউটপুট পরামিতি হিসাবে পাস করার পরামর্শ দিই। ব্যবহার:
void foo(int *a, char *s, int size);
এবং এটিকে কল করুন:
int a;
char *s = (char *)malloc(100); /* I never know how much to allocate :) */
foo(&a, s, 100);
সাধারণভাবে, কলিং ফাংশনে বরাদ্দ করতে পছন্দ করুন , ফাংশনের ভিতরেই নয়, যাতে আপনি বিভিন্ন বরাদ্দের কৌশল হিসাবে যতটা সম্ভব উন্মুক্ত হতে পারেন।
দুটি ভিন্ন পন্থা:
আমি মনে করি যে # 1 যা চলছে সে সম্পর্কে এটি আরও কিছুটা স্পষ্ট, যদিও আপনার কাছে অনেকগুলি ফেরতের মান থাকলে এটি ক্লান্তিকর হতে পারে। সেক্ষেত্রে বিকল্প # 2 মোটামুটিভাবে ভালভাবে কাজ করে, যদিও এই উদ্দেশ্যে বিশেষায়িত স্ট্রাক্ট তৈরির সাথে কিছু মানসিক ওভারহেড জড়িত রয়েছে।
string, এটি সি ++ ধরে নেওয়া নিরাপদ হতে পারে ...
ফাংশন প্রসঙ্গে পরামিতি পাস করে।
উদাহরণ:
void incInt(int *y)
{
(*y)++; // Increase the value of 'x', in main, by one.
}
এছাড়াও গ্লোবাল ভেরিয়েবল ব্যবহার করে তবে এটি প্রস্তাবিত নয়।
উদাহরণ:
int a=0;
void main(void)
{
//Anything you want to code.
}
void main(void)ওহ কিভাবে জ্বলছে!
mainএকটি স্থিতি কোড ফেরত দেওয়ার কথা। * নিক্সের অধীনে, এটি হিসাবে ঘোষণা করা আরও স্বাভাবিক usual int main(int argc, char *argv[])আমি বিশ্বাস করি উইন্ডোজের অনুরূপ কনভেনশন রয়েছে।
একটি পদ্ধতির ম্যাক্রো ব্যবহার করা হয়। এটি একটি শিরোনাম ফাইলে রাখুনmultitype.h
#include <stdlib.h>
/* ============================= HELPER MACROS ============================= */
/* __typeof__(V) abbreviation */
#define TOF(V) __typeof__(V)
/* Expand variables list to list of typeof and variable names */
#define TO3(_0,_1,_2,_3) TOF(_0) v0; TOF(_1) v1; TOF(_2) v2; TOF(_3) v3;
#define TO2(_0,_1,_2) TOF(_0) v0; TOF(_1) v1; TOF(_2) v2;
#define TO1(_0,_1) TOF(_0) v0; TOF(_1) v1;
#define TO0(_0) TOF(_0) v0;
#define TO_(_0,_1,_2,_3,TO_MACRO,...) TO_MACRO
#define TO(...) TO_(__VA_ARGS__,TO3,TO2,TO1,TO0)(__VA_ARGS__)
/* Assign to multitype */
#define MTA3(_0,_1,_2,_3) _0 = mtr.v0; _1 = mtr.v1; _2 = mtr.v2; _3 = mtr.v3;
#define MTA2(_0,_1,_2) _0 = mtr.v0; _1 = mtr.v1; _2 = mtr.v2;
#define MTA1(_0,_1) _0 = mtr.v0; _1 = mtr.v1;
#define MTA0(_0) _0 = mtr.v0;
#define MTA_(_0,_1,_2,_3,MTA_MACRO,...) MTA_MACRO
#define MTA(...) MTA_(__VA_ARGS__,MTA3,MTA2,MTA1,MTA0)(__VA_ARGS__)
/* Return multitype if multiple arguments, return normally if only one */
#define MTR1(...) { \
typedef struct mtr_s { \
TO(__VA_ARGS__) \
} mtr_t; \
mtr_t *mtr = malloc(sizeof(mtr_t)); \
*mtr = (mtr_t){__VA_ARGS__}; \
return mtr; \
}
#define MTR0(_0) return(_0)
#define MTR_(_0,_1,_2,_3,MTR_MACRO,...) MTR_MACRO
/* ============================== API MACROS =============================== */
/* Declare return type before function */
typedef void* multitype;
#define multitype(...) multitype
/* Assign return values to variables */
#define let(...) \
for(int mti = 0; !mti;) \
for(multitype mt; mti < 2; mti++) \
if(mti) { \
typedef struct mtr_s { \
TO(__VA_ARGS__) \
} mtr_t; \
mtr_t mtr = *(mtr_t*)mt; \
MTA(__VA_ARGS__) \
free(mt); \
} else \
mt
/* Return */
#define RETURN(...) MTR_(__VA_ARGS__,MTR1,MTR1,MTR1,MTR0)(__VA_ARGS__)
এটি একটি ফাংশন থেকে চারটি ভেরিয়েবলের কাছে ফিরে আসা এবং চারটি ভেরিয়েবলের জন্য তাদের নির্ধারণ করা সম্ভব করে। উদাহরণ হিসাবে, আপনি এগুলি এগুলি ব্যবহার করতে পারেন:
multitype (int,float,double) fun() {
int a = 55;
float b = 3.9;
double c = 24.15;
RETURN (a,b,c);
}
int main(int argc, char *argv[]) {
int x;
float y;
double z;
let (x,y,z) = fun();
printf("(%d, %f, %g\n)", x, y, z);
return 0;
}
এটি এটি প্রিন্ট করে:
(55, 3.9, 24.15)
সমাধানটি পোর্টেবল হিসাবে কার্যকর নাও হতে পারে কারণ এর জন্য ভের্যাডিক ম্যাক্রোগুলির জন্য এবং পরে-বিবৃতি পরিবর্তনশীল ঘোষণার জন্য C99 বা তার পরে প্রয়োজন। তবে আমি মনে করি এটি এখানে পোস্ট করা যথেষ্ট আকর্ষণীয় ছিল। আরেকটি সমস্যা হ'ল সংকলকটি যদি আপনাকে ভুল মান নির্ধারণ করে তবে আপনাকে সতর্ক করবে না, তাই আপনাকে সতর্কতা অবলম্বন করতে হবে।
ইউনিয়নগুলি ব্যবহার করে অতিরিক্ত উদাহরণ এবং কোডের একটি স্ট্যাক-ভিত্তিক সংস্করণ আমার গিথুব সংগ্রহস্থলে উপলভ্য ।
__typeof__
stringকি আপনি কি বোঝাতে চেয়েছেন "আমি সি ++ ব্যবহার করছি এবং এই হলstd::stringবর্গ" বা "আমি সি ব্যবহার করছি এবং এই একটি হলchar *পয়েন্টার বাchar[]অ্যারে।"