PDA

View Full Version : سوال: تبدیل نوع صریح با تبدیل نوع ضمنی چه فرقی دارد؟



complexcoding
پنج شنبه 28 اردیبهشت 1391, 01:22 صبح
سلام
تبدیل نوع صریح با تبدیل نوع ضمنی در سی پلاس پلاس چه فرقی دارد؟

char ch=(char)65.7;
char ch=97.8;

خوب این دو با هم چه فرقی دارند؟

mehdi.mousavi
سه شنبه 02 خرداد 1391, 23:37 عصر
سلام تبدیل نوع صریح با تبدیل نوع ضمنی در سی پلاس پلاس چه فرقی دارد؟

char ch=(char)65.7;
char ch=97.8;

خوب این دو با هم چه فرقی دارند؟

سلام.
در هر دوی اینها، Coercion (http://en.wikipedia.org/wiki/Type_conversion) رخ میده، یعنی data type ای دارید که نمی تونید دست نخورده در data type دیگه قرار بدید (به حالت برعکسش promotion میگن). اما در اولی، شما دارید explicitly به compiler میگید که از "از دست رفتن داده ها به هنگام تبدیل double به char آگاه هستم، پی ادامه بده، چون میدونم دارم چیکار میکنم". اما در دومی، Compiler سعی میکنه مقدار double رو خودش بطور خودکار به char تبدیل کنه، اما شما رو از "از دست دادن احتمالی بخشی از داده به هنگام تبدیل" توسط Warning ای هنگام Compile مطلع می کنه. (در VS2010، اخطار C4244 صادر میشه). غیر از این موضوع، تفاوتی بین دو خط فوق وجود نداره.

موفق باشید.

Ananas
سه شنبه 02 خرداد 1391, 23:58 عصر
سلام.
ممنون از توضیحاتتون.

char ch=(char)65.7;
char ch=char(65.7);

لطفا فرق این دوتا رو هم بفرمایید. اگه تو نتیجه فرقی نداره کدومش درست تر و بهتره؟

mehdi.mousavi
چهارشنبه 03 خرداد 1391, 11:16 صبح
سلام. ممنون از توضیحاتتون.

char ch=(char)65.7;
char ch=char(65.7);

لطفا فرق این دوتا رو هم بفرمایید. اگه تو نتیجه فرقی نداره کدومش درست تر و بهتره؟

سلام و خواهش میکنم. :)
خط اول و خط دوم کدی که شما در بالا به اون اشاره کرده اید، هیچ تفاوتی با هم نمیکنه (اما پاسخم رو تا انتها بخونید!) و نتیجه یکسانی داره و باعث میشه عدد 65 در ch ریخته بشه. به اولی "c-like cast notation" و به دومی "functional notation" گفته میشه. اما این مساله در مورد data type های اصلی برقراره و وقتی کار به cast کردن (به هر یک از دو شیوه فوق) به Pointer ها، Reference ها و Object ها میرسه، این مدل cast کردن نتایج (احتمالا) غیر منتظره ای رو در پی داره چون type دو گونه از pointer ای که دارن به هم تبدیل میشن در چنین حالتی چک نمیشه و کد علیرغم اینکه از نظر Syntax مشکلی نداره و Compile میشه، اما در اجرا به خطا میخوره... به همین دلیل هستش که dynamic_cast (http://msdn.microsoft.com/en-us/library/cby9kycs%28v=vs.100%29.aspx)، static_cast (http://msdn.microsoft.com/en-us/library/c36yw7x9)، const_cast (http://msdn.microsoft.com/en-us/library/bz6at95h)، reinterpret_cast (http://msdn.microsoft.com/en-us/library/e0w9f63b) معرفی شد تا جلوی چنین اشتباهاتی گرفته بشه.

بنابراین، اگر از data type های اصلی استفاده می کنید، اهمیتی نداره کدامیک از دو notation فوق رو برای cast کردن انتخاب کنید، اما در مواردی که با pointer ها سر و کار دارید و میخواهید pointer ای رو به pointer دیگه ای cast کنید، بهتر این هستش که از هیچ یک از دو Notation فوق استفاده نکنید و از یکی از 4 اپراتور نامبرده استفاده کنید.

موفق باشید.

Ananas
شنبه 06 خرداد 1391, 17:09 عصر
متشکر.
یه سوال دیگه: من بعضی وقتا برای استفاده از یک محل حافضه به عنوان نوعی داده دیگه به شکل زیر کد رو مینویسم :

double d = 3.14159265358979;
__int64 i64 = *((__int64 *)(&d));

به نظرتون این روش که یکبار به اشاره گر تبدیل کنیم و بعد دوباره محتویات رو بخونیم تو سرعت اجرا تاثیر خاصی میگذاره؟ بعضی وقتا برای آرایه ها این طوری مینویسم و یا برای struct . به نظرتون اشکالی هم پیش میاد؟
یه مثال دیگه :
#pragma hdrstop
#pragma argsused

#include <tchar.h>
#include <stdio.h>
#include <iostream>
using namespace std;

#pragma pack(push, 1)
typedef struct TVec3D
{
public :
float x, y, z;
} *PVec3D;
typedef struct TVec2D
{
public :
float x, y;
float Length();
} *PVec2D;

float TVec2D::Length()
{
return sqrt(x * x + y * y);
};

int _tmain(int argc, _TCHAR* argv[])
{
TVec3D xyz;
xyz.x = 1;
xyz.y = 2;
xyz.z = 3;
//-----------------------------------------------------------
cout << ((TVec2D *)(__int64(&xyz) + sizeof(float)))->Length();
//v is TVec2D(xyz.y, xyz.z);
//-----------------------------------------------------------
getchar();
return 0;
}


چند خط آخر که با حاشیه مشخص شده منظورم هست.
البته من همیشه این کا رو نمیکنم. مشخصا اینجا برای مثال بود. حالا به نظرتون اون دو تا عدد رو که برای تابع TVec2D::Length لازم داریم با نوشتن کمتر و با ارسال به یک تابع دیگه که دو تا عدد رو میگیره بنویسیم بهتر و سریعتر میشه یا از همین ناحیه از حافظه استفاده کنیم و تو متغیر دیگه ای کپی نکنیم؟ البته اینجا دو تا عدد داریم ولی ممکنه ماتریس 4 در 4 و یا داده های طولانی تری داشته باشیم اون وقت چی؟