พอดีเป็นการบ้านเกี่ยวกับเขียน C สำหรับแก้สมการ Quadratic และต้องเขียนให้เป็น 2 ฟังก์ชั่นครับ ซึ่งการจะ Return ค่ามากกว่า 1 ค่า จะต้องใช้ Pointer แต่ผมยังไม่ค่อยเข้าใจครับ ช่วยดูให้หน่อยครับ
//////////////////////////////////////////////////////////////////////////
int qsolver(double a, double b, double c);
int main()
{
double a, b, c, *x1, *x2, st;
printf("Please enter the value of a: ");
scanf("%lf", &a);
printf("Please enter the value of b: ");
scanf("%lf", &b);
printf("Please enter the value of c: ");
scanf("%lf", &c);
st = qsolver(a, b, c);
if(st == 0)
{
printf("The answers are %lf and %lf.\n", *x1, *x2);
}
else if(st == -1)
{
printf("The equation cannot be solved.\n");
}
}
int qsolver(double a, double b, double c)
{
double *x1, *x2;
if(a==0)
{
return -1;
}
else if((b*b)-(4*a*c)<0)
{
return -1;
}
else if((b*b)-(4*a*c)>=0)
{
*x1=(-b+sqrt((b*b)-(4*a*c)))/(2*a);
*x2=(-b-sqrt((b*b)-(4*a*c)))/(2*a);
return 0;
}
}
f
1 function return ได้ 1 อย่างเท่านั้น
แต่ถ้าอยาก return มากกว่านั้น เช่น int 2 ตัว ก็ประกาศ int[] ออกมา แล้ว return int[] โดย return เป็น pointer
(อ่านโจทย์ผิด ขอแก้ครับ)
อย่างแรกเลยนะครับเรื่องการตั้งชื่อตัวแปรให้สื่อความหมายหน่อย ผมว่าคนมาตรวจอาจจะเลิกตรวจไปเลย. ลองอ่านและทำตามนี้ดูครับ http://en.wikipedia.org/wiki/Hungarian_notation
ช่วยได้มากสุดก็ตัวอย่างที่คล้ายๆกันตามนี้ครับ ลองสังเกตตรงการประกาศ, การส่งค่าที่พารามิเตอร์, การใช้งานตัวแปลทั้งนอกและในฟังก์ชั่น Sum ดูนะครับ
#define SUCCESS 0 int Sum(int* pInput1, int* pInput2, int* pOutput);
int main()
{
int nInput1 = 5; int nInput2 = 6; int nOutput = 0;
Sum(&nInput1 , &nInput1 , &nOutput);
printf("Memory address:\t%d \t%d \t%d\n", &nInput1 , &nInput1 , &nOutput); printf("Value :\t%d \t%d \t%d\n", nInput1 , nInput1 , nOutput); getch();
return SUCCESS;
}
int Sum(int* pInput1, int* pInput2, int* pOutput)
{
*pOutput = *pInput1 + *pInput2;
return SUCCESS;
}
ต้องการค่าจะ Function อื่นทำได้หลายวิธีครับ
ปกติผมนิยมวีธีที่ 1 หรือถ้า return เยอะมากก็ pass struct* เข้าไปเลย
วิธีทำความเข้าใจ ลองเขียนโปรแกรมใหม่ที่ไม่ต้องยุ่งยากขนาดนี้ แค่เอา a=1, b=2 ให้ได้ 2 กับ 3 ออกมาก่อนก็ได้
ป.ล. จริงๆไม่รู้ว่า อยากรู้วิธีนำค่าจาก function ในกรณีที่มีค่าที่สนใจมากกว่า 1 ค่า หรือ อยากรู้ว่า pointer มันทำงานยังไง มากกว่า
:: DigiKin8 ::
ผมจะลองทำดูครับ
ขอบคุณครับ
หรือการบ้านบังคับ return เป็น Pointer เอ่ย
พอดี ยังไม่ได้เรียน Class กับ Array ครับ
หลังจากนี้ก็เริ่มเรียนได้เลยครับ เพราะนั่นคือสิ่งที่มีประโยชน์มาก เทียบได้กับวิตามินบีสิบสองผสมซอยเป๊บไทด์
แนะนำอ่านหนังสือเลยครับ อย่ารอให้อาจารย์สอน
ยังไม่ได้เรียน Class ก็โอเค แต่เรียน Pointer ก่อน Array นี่ผมว่าโคตรแปลกเลยนะ
ไม่ได้เรียน Class นี่ไม่แปลกครับ แต่ไม่ได้เรียน Array นี่แปลกมากกกกกก ชนิดข้อมูลพื้นฐานเลยนะครับ
ตอนแรกจะเข้ามาอธิบายเรื่อง Pointer โดยใช้พื้นฐานจาก Array แต่พอเป็นแบบนี้แล้วก็เลยผิดแผน
ไม่เป็นไรครับ
แต่อยากบอกว่าความรู้ภาษา C พื้นฐานมีเยอะเลยใน Internet แต่ถ้าต้องการคำตอบตรงๆ เลยก็รอท่านอื่นละกันครับ
น่าจะมีมุม CodeGolf แบบไทยๆนะครับ (ไม่ค่อยเกี่ยวกับหัวข้อเลย)
ทำได้แล้วครับ ขอบคุณ susie888, Diaboros_Sorobaid, PiKO, PaPaSEK และทุกคนครับ
สมัยก่อน ผมก็เรียน pointer มา หลังจากนั้น พอหันมาทำ c# ก็ลืมpointerไปหมดเลย
จำได้คร่าวๆว่า
a* คือ pointer ชื่อ a
&a คือ value ของ pointer a
(a + 1)* คือ array index ที่ 1
พวกนี้ ไม่แน่ใจ
a.b คือ internal invoke หรือ เรียก element ใน class
a->b คือ เรียกจากนอก class
จำได้อีก ก็มีพวก linked list มั่วๆเอาลืมไปหมดแล้ว
class list{
public int* value
public int* next
}
จำได้อีกว่า ครั้งแรกที่เขียนโปรแกรมเครื่องคิดเลข ที่ใช้ postfix, suffix. stack ทำตั้งแต่บ่ายสาม ถึงเที่ยงคืน
อ้า ... ขออนุญาตแจ้งตามตรง ผิดทั้งคู่ครับ ^^
a.b ใช้ในกรณีที่ object เป็น stack variable ก็คือ variable ธรรมดา
a->b ใช้ในกรณีที่ a เป็น pointer ครับ
ถ้าเป็นภาษาอื่นใช้ . ทั้งหมดครับ
:D
a.b สำหรับ value type
a->b สำหรับ object type
อยากโหลด borland c++ มาลง 555
object มันก็เป็น value ได้นะครับ
แต่ถ้าเป็น COM object ก็อีกเรื่องนะ (อันนี้ ptr ทั้งหมด) อิอิ
ต้องบอกว่า Value ก็เป็น Object ได้ครับ
แต่ในกรณีนี้ผมมองว่า ถ้าจะตัดสินว่ามันเป็น Object Type หรือ Value Type ก็ต้องดูว่า a มันเป็น PrimitiveData Type หรือเปล่า ซึ่งเขียนเป็น JavaScript ได้ดังนี้(ทำไมต้อง JavaScript?)
var isObjectType = isPrimitive(a)?false:true;
ถ้าเขียนให้งงน้อยลง
var isObjectType = !isPrimitive(a);
หรือถ้าจะให้ไม่งงเลย
a เป็น Object Type เมื่อ a ไม่ได้เป็น Primitive Data Type(น่าจะเขียนแบบนี้แต่แรก ฮ่า ฮ่า)
ถึงข้างบน
C# ไม่มี Primitive Type ครับ
object ก็มี ValueType กับ ReferenceType แต่ทั้งสองแบบเข้าถึงสมาชิกด้วย .
มีแต่ pointer ที่ยังใช้ ->
ถึงคุณ Thaina
ดู Code(ต้นฉบับ) ให้ดีๆ ผมว่าเป็น C ธรรมดานะเพราะมี Main entry point(int main()) อยู่
ที่คุณนึกว่ามันเป็น C# เพราะว่าคุณ susie888 เค้าบอกว่า "พอมาเขียน C# แล้วลืม Pointer" หรือเปล่า
หรือว่าคุณพูดลอยๆ ว่า C# ไม่มี Primmitive Type
เพราะผมเห็นคุณยก JavaScript มาครับ
ซึ่งมันแตกต่างกับภาษา C และภาษาอื่นๆอย่างแน่นอน
ซึ่ง C# ก็ต่างจากภาษา C เช่นกัน ผมแค่ยกมาตั้งเปนตัวอย่างเฉยๆว่า ระบบ object แต่ละภาษามันมีความแตกต่างอยู่มาก
ภาษา C ไม่มีระบบ object ด้วยซ้ำ และออกจะเหมือน C# มากกว่า JS ที่ Primitive ก็ไม่ได้ต่างอะไรกับ struct
ถ้าคุณคำนึงถึง "โค้ดต้นฉบับ" ก็ไม่ควรยก JS มาเทียบ
หรือแม้แต่กับ C++ ที่กำลังพูดถึงอยู่ ก็ต่างกับ JS อีกนั่นแหละ
ผมต่างหากที่อยากพูดว่า คุณพูดถึง JS เพื่ออะไร?
ป.ล.
ในภาษา C++ เนี่ย
object ถือเปน value
ไม่ใช่คำพูดที่ผิดเลยครับ
ผมว่าแล้วว่าคุณต้องตอบแบบนี้ ผมถึงได้เขียนทางออกไว้ให้คุณแล้วด้านบน
555 มะก่อนตอนเรียนผมถนัด C++ เรื่อง pointer นี่ คล่องมากมาย
แต่ พอมาเป็น c# ปุ๊บ ความรู้เก่าเริ่มเลือนลาง
ใน C# มันแบ่งเบื้องต้นเป็น 2 แบบ คือ value type กับ reference type หรือผมชอบเรียกติดปากว่า object type
แต่จำได้ลางๆว่า ใน C++ นั้น primitive type คือ value type แต่เหมือนว่า จะต่างกันตรงที่ string ซึ่ง จอง C# นั้น string ถือเป็น type พิเศษ กึ่ง ref กึ่ง value ส่วน C++ นั้น string ไม่น่าใช่ primitive
แต่พอเปรียบกับ js จะงงๆอยู่ เพราะ js เป็น expando หรือ dynamic type ซึ่ง ผมว่า ไม่ควรมาเปรียบเทียบกัน เพราะมันคนละอย่าง น่าจะเหมือนเหมือนเหมาเอารถบรรทุก กับรถพ่วงเข้าด้วยกัน
ใน C# string มันก็เปน ref type นี่ครับ?
ทำไมถึงบอกว่ากึ่งอะครับ?
ผมว่าใน C++ ทุกอย่างมันเปน ValueType หมดนะ
ต่อให้สร้างคลาสมันก็เปน ValueType ไม่มี ReferenceType เราต้องสร้าง pointer เอาเอง
อันนี้เปนความคิดผมเลยนะว่า ref type จริงๆมันก็คือ define pointer แบบ framework manage ก็แค่นั้น
เวลาใช้ก็ต้อง new ให้มันไปลง heap
string เป็น type พิเศษครับ
ตย
int เวลาเรา set ค้าให้มัน มันจะไปแก้ที่ value ของมันเองโดยตรงเลย เช่น แก้จาก 1 ไป 2 ในmemory ก็เปลี่ยนจากเลข 1 เป็น 2 เราเลยเรียกว่า value type เนื่องจาก value มันเปลี่ยน ซึ่ง ที่ๆทำการเก็บ memory ไว้ เรียกว่า heap เป็น stack ที่เข้าถึงได้เร็ว และเก็บ value type เท่านั้น
เช่น
int num = 0;
num = 3;
การ assign ค่า 3 จะเป็นการแก้ไข value ใน heap จาก 0 เป็น 3
object ทั่วไป สมมุติว่า เราผ่าน object ไปแต่ละmethod มันจะเป็นการส่ง pointer ไป และจะสามารถเรียกใช้ property ของ method นั้นๆได้เลย และ pointer ของ object ไม่ได้เก็บไว้ที่ heap
เช่น
var obj = new List();
obj = new List();
จะเป็นการสั่งให้ pointer ชี้ไปที่ object ใหม่ ไม่ใช่การแก้ไขค่า obj ใน heap
ส่วนที่ string เป็น type พิเศษ(immutable) เมื่อมีการ assign ค่าใหม่ให้มัน
เช่น
string name = "blog";
name = name + "none";
การสร้างค่าใหม่นี้ ไม่ใช่การแก้ไขข้อมูลใน heap แต่เป็นการประกาศ string ตัวใหม่ขึ้นมาแทนที่ เนื่องจาก string แท้จิงแล้วเป็น char[] และ ตัว char[] ไม่ได้ถูกแก้ แต่ .net จะไปสร้าง char[] ใหม่ขึ้นมาแทน
ยกเว้นว่า name[3] = '?' จะเป็นการแก้ value
ก็ไม่เห็นว่า string จะต่างกับ reference type อื่นๆ ตรงไหน นะครับ
ก็แน่นอนว่า string มันต่างกับ value type อยู่แล้ว
base สุดๆ ของ string คือ class String {} นะครับ
อนุมานได้ว่า string ก็จะทำตัวเหมือนกับ ref type ทุกชนิด
และผมก็ยังไม่เห็นว่า string มีคุณสมบัติอะไรพิเศษกว่า ref type ตัวอื่นๆในโลกนี้เลย
ผมขอเดาหน่อยนะว่า คุณอาจจะเข้าใจสับสนกับ primitive type
แต่ C# ไม่มีหลักการ primitive type นะครับ เปนหลักสำคัญของ C# ที่เน้นเลยว่าต่างกับ Java
ถึง int กับ string จะเหมือนว่าเปน primitive type แต่มันก็ "Equally" กับ custom type ตัวอื่นๆ
จากตรงนี้ผมเห็นว่า string ไม่ใช่ type พิเศษ แต่อย่างใด
ตย
int num1 = 5 int num2 = num1; Console.WriteLine("int & int: {0}", (object)num1 == (object)num2); // false
string s1 = "blognone"; string s2 = s1; Console.WriteLine("string & string: {0}", (object)s1 == (object)s2); //true
string s3 = "blognone"; string s4 = s3 + "web"; Console.WriteLine("string & srting: {0}", (object)s3 == (object)s4); //false
ชัดมะคับ ว่าทำไม string เป็น immutable
อีกอย่าง สาเหตุที่ผมไม่เรียก reference type เพราะมันไม่ใช่ reference เสมอไป ตย public static void test(int a){} เป็นการผ่านโดย copy value ใน heap public static void test(object a){} เป็นการผ่านโดยส่ง pointer public static void test(dynamic a){}
มีคำถามขำๆ ให้คิดเล่นๆ คิดว่า มันจะไปเข้า method ไหนครับ? public static void main(){ test(555); }
immutable มันทำให้มันกลายเปน type พิเศษ ตรงไหนเหรอครับ?
ทุก class ใน C# ก็ immutable เหมือนกัน object ก็ด้วย
อ่านดีๆนะว่าผมบอกว่า ผมไม่เห็นว่า string มันเปน "object พิเศษ" ตรงไหน
ไม่ได้พูดว่ามันเปนหรือไม่เปน immutable
ป.ล. ไอ้คำถามนั่นเกี่ยวตรงไหนครับ? ลองภูมิ?
ป.ล.2 string เปน reference type ครับ ช่วยยกตัวอย่างมาดีกว่าว่า ตอนไหนที่มันเปน value type จะ make sense กว่านี้
ตย ข้างบน
int & int อันนี้ ชัดว่าเป็น value type
s1 & s2 อันนี้ชัดว่าเป็น ref type
สาเหตุที่เป็น immute ก็คือเป็น ref type ประเภทเดียวที่ค่าถูกเก็บไว้ใน heap ตรงๆ
คุณพูดอะไรผิดรึเปล่าครับ
ref type ทุกตัว เก็บค่าใน heap ครับ
value type เก็บอยู่ใน stack
เกี่ยวกับเก็บตรง/ไม่ตรง ยังไงครับ?
ย้ำอีกที : string เปน reference type ครับ ช่วยยกตัวอย่างมาดีกว่าว่า ตอนไหนที่มันเปน value type จะ make sense กว่านี้
ผมแนะนำคุณ susie888 ว่าอย่าไปถกกับเค้าครับ
จริงๆ แล้ว string เป็น reference type นะครับ เห็นมันจะพิเศษหน่อยก็ตรงที่เวลาใช้ operation == มันจะเปรียบเทียบ value ไม่ได้เปรียบเทียบ reference อ่ะครับ
อา นั่นเปนระบบ operator override ซึ่งมีหลายคลาสทำเหมือนกันครับ และ class ที่สร้างเองก็ทำได้ด้วยเหมือนกัน
ถ้าพูดถึงพิเศษนี่ผมว่า array พิเศษสุดเลยนะ
ไอ้ [] ของมัน มี array เท่านั้นที่ไม่เหมือนใคร