typedef و define در ++C - هفت خط کد انجمن پرسش و پاسخ برنامه نویسی

typedef و define در ++C

+9 امتیاز
نحوه استفاده از typedef در c++ چطوریه ...؟

نحوه استفاده define در c++ چطوریه ... ؟

 

فرقشون و کاربردشون چطوریه ؟
سوال شده شهریور 9, 1393  بوسیله ی Amin (امتیاز 453)   10 17 43
دوباره تگ گذاری شد شهریور 10, 1393 بوسیله ی BlueBlade

1 پاسخ

+7 امتیاز
 
بهترین پاسخ

typedef برای این استفاده میشه که برای یک نوع خاص یک اسم  متفاوت بزاریم .

 

نحوه استفاده :

typedef old_type_name  new_type_name;

 

مثال  :

typedef char*  CPtr;
typedef int Node;
typedef std::vector<int>  vec;
typedef std::vector<std::string> string_vector;
typedef std::pair<Node,Node> Edge;
//...

 

یکی از جاهایی که typedef  استفاده میشه  زمانی هستش که  میخواهید یک container تو در تو استفاده کنید . 

مثلا برای   یک وکتور از مپ  بدون typedef این جور کدی باید نوشت : 

#include <string>
#include <iostream>
#include <vector>
#include <map>
int main()
{
	std::vector<std::map<std::pair<int, int>, std::string>> data;
	//por kardan
	std::map<std::pair<int, int>, std::string> inner_data;
	inner_data[std::make_pair(5, 2)] = "test1";
	inner_data[std::make_pair(2, 2)] = "test2";
	inner_data[std::make_pair(1, 4)] = "test3";
	data.push_back(inner_data);
	data.push_back(inner_data);

	//baraye peymayesh :
	for (std::vector<std::map<std::pair<int, int>, std::string>>::const_iterator it=data.begin();
		it  != data.end(); ++it){
		const std::map<std::pair<int, int>, std::string>& element = *it;
		for (std::map<std::pair<int, int>, std::string>::const_iterator inner_it = element.begin();
			inner_it != element.end(); ++inner_it){
			const std::pair<int,int>& p = inner_it->first;
			const std::string& str = inner_it->second;
			std::cout << p.first << " " << p.second << " " << str<<'\n';
		}
	}
	return 0;
}

حالا فرض کنید این loop ها قرار باشه 10 جای دیگه هم نوشته بشن چقدر کد عجیبی میشه !

با typedef مشه تمام انواع رو یک اسم کوچکتر  بهشون داد و کد رو تمیز تر و کوتاه تر نوشت .

 همون کد قبلی اینبار با استفاده از typedef  :

#include <string>
#include <iostream>
#include <vector>
#include <map>

typedef   std::pair<int, int>            Pair;
typedef   std::map<Pair, std::string>    Map;
typedef   std::vector<Map>               Container;
typedef   Container::const_iterator      Container_CIterator;
typedef   Map::const_iterator            Map_CIterator;

int main()
{
	Container data;
	//por kardan
	Map inner_data;
	inner_data[std::make_pair(5, 2)] = "test1";
	inner_data[std::make_pair(2, 2)] = "test2";
	inner_data[std::make_pair(1, 4)] = "test3";
	data.push_back(inner_data);
	data.push_back(inner_data);

	//baraye peymayesh :
	for (Container_CIterator it = data.begin();it  != data.end(); ++it)
	{
		const Map& element = *it;

		for (Map_CIterator inner_it = element.begin();
			inner_it != element.end(); ++inner_it)
		{
			const Pair& p = inner_it->first;
			const std::string& str = inner_it->second;
			std::cout << p.first << " " << p.second << " " << str<<'\n';
		}
	}
	return 0;
}

از typedef برای اشاره گر های به تابع هم میشه استفاده کرد

 مثلا برای ساختن اشاره گر به تابع  زیر :

int foo(int,int);

بجای 

int(*bar)(int,int)=foo;

میشه به شکل زیر نوشت که خواناتر هم هست !

typedef int(*function_type)(int,int);
function_type bar=foo;

مثلا این رو ببینید :

struct T2 { T2(int){ } };
int  (*(*name)(T2))(int);

کد بالا رو به این شکل هیچ کسی نمی تونه بفهمه چیه ولی وقتی با typedef استفاده می کنیم :

typedef int (*return_type) (int);
typedef return_type(*function_type) (T2);

function_type name;

مشخص میشه که داریم یک اشاره به تابع تعریف می کنیم که ورودیش یک شی از T2 هست و خروجیش یک اشاره گر به تابع که int ورودیش هست و  int هم بر می گردونه .

داخل این لینک هم در مورد typedef توضیحاتی داده شده : typedef چیه ؟

 

using جایگزین typedef  در c++11 :

 

در c++11  کلمه کلیدی جدیدی به اسم using  اضافه شده که کار typedef رو میکنه  using به این شکل کار می کنه :

using new_type_name=old_type_name;

using تفاوت خاصی با typedef نداره ولی تا حدی خوانا تر از typedef  هست .

مثلا همون اشاره گر به تابع بالا رو میشه این شکلی تعریف کرد

struct T2{};
using  return_type   = int(*)(int);
using  function_type = return_type(*)(T2);
function_type name;

یا مثال اول : 

using  Pair = std::pair<int, int>;
using  Map = std::map<Pair, std::string>;
using  Container = std::vector<Map>;
using  Container_CIterator = Container::const_iterator;
using  Map_CIterator = Map::const_iterator;

 

define برای نوشتن ثابت هایی استفاده میشه که زمان کامپایل کد جایگزین محل استفاده شدن میشن (macro ها )

نحوه استفاده از define به شکل زیر هست :

#define name value

برای مثال :

#define  MAX_SIZE 1000
#define MAX_INT32 0x7fffffff
#define FALSE           0
#define abs(a) ((a)>0?(a):(-1*a))  //ghadr motlagh a bargasht dade mishe

کاری هم که define می کنه اینه که زمان کامپایل اسم  ای که استفاده شده با مقدارش عوض میشه یعنی مثلا هر جای کد از MAX_SIZE استفاده کردید زمان کامپایل با مقدار متناظرش که این جا 1000 هست جابه جا میشه.

مثال :

#include <iostream>

#define  MAX_SIZE 50
#define  MAGIC_NUMBER 4
#define  ZERO 0
#define  STR "..."
#define abs(a) ((a)>0?(a):(-1*a))  //ghadr motlagh a bargasht dade mishe

int main()
{
	for (int i = 0; i < MAX_SIZE; i++){
		if (i%MAGIC_NUMBER == ZERO  )
		std::cout << i <<" "<<STR<<'\n';
	}

	std::cout << abs(-5)<<" "<<abs(7) << '\n';
        //khat bala ba in jaygozin mishe 
        // std::cout<< ((-5)>0?(-5):(-1*-5))  <<  ((7)>0?(7):(-1*7));
        //bad compile mishe
}

البته برای تعریف ثابت ها  میشه از const هم استفاده کرد که مزیت هایی هم داره این لینک رو ببینید : const در برابر define

این لینک هم یک مثال خوب دیگه از استفاده از define داخلش هست : فواید استفاده از macro

 

تفاوت define با typedef : 

 

 در typedef  برای یک نوع اسم جدیدی میزاریم که این اسم جدید با همون نوع زمان کامپایل جایگزین میشه .

 define کاری که انجام میده صرفا جایگزینی متن هست  و لزومی نداره که بر روی type ها استفاده بشه .(برای نمونه داخل مثال  بالا برای عدد 1000 ثابت MAX_SIZE گذاشتیم )

یا بصورت واضح تر یعنی این که typedef برای تعریف  نوع داده ها استفاده میشه  . define برای تعریف ماکرو ها .

typedef قواعد scope و typechecking براش برقرار هستش ولی define خیر .

مثال 1 : 

#define SIZE 1000    //dorost
typedef 100 SIZE      //error

مثال 2 :

#define  ptr char* 
int main()
{
	ptr a, b;
	ptr c = b;//error !!
}

داخل مثال بالا بخاطر این که صرفا متن جایگزین میشه نوع a میشه *char ولی نوع b میشه char برای همین خط بعدی ارور داده میشه

ولی داخل مثال بعدی کد کار می کنه :

typedef char* ptr;
int main()
{
	ptr a, b;
	ptr c = b;//ok
}
پاسخ داده شده شهریور 9, 1393 بوسیله ی BlueBlade (امتیاز 15,315)   15 18 89
انتخاب شد شهریور 15, 1393 بوسیله ی Amin
ممنون ...
دستت درد نکنه ...
همون طور که تو لینک زیر گفتم با define میشه دستور رو هم نهان سازی کرد. خیلی کاربرد واسش هست :
http://www.7khatcode.com/179/const-%D8%AF%D8%B1-%D8%A8%D8%B1%D8%A7%D8%A8%D8%B1-%23define?show=179#q179
...