Sunday, October 09, 2005

address ใน C/C++ กับ +, - operator

เวลาที่เราเราแสดงผลตัวแปรที่เป็น pointer ปรกติค่าที่พิมพ์ได้ก่อน dereference จะเป็นค่าตำแหน่งของตัวแปรที่มันชี้อยู่ เช่น

int i = 10;
int *p = &i;

cout << p << endl;

ผลที่ได้จะคล้าย ๆ กะค่าข้างล่างนี้
ffbefa80

ทีนี้มีข้อสงสัยอยู่หนึ่งอย่างคือ ถ้าเราเอาเลขของ pointer 2 ตัวนี้มาลบกันในขณะที่เป็น pointer อยู่ หรือนำค่า pointer มาบวกกับตัวเลขจะเกิดอะไรขึ้น ขั้นแรกเรามาดูก่อนกะ operator + กับ pointer

int i = 10;
int *p = &i;
cout << p << endl;
cout << p + 1 << endl;

ผลลัพธ์ที่ได้ไม่ใช่
ffbefa80
ffbefa81

นะครับแต่ผลที่ได้จะคล้าย ๆ กะค่าข้างล่างนี้
ffbefa80
ffbefa84 คือค่าที่เพิ่มขึ้นมาจะเป็น 1*sizeof(datatype) นั้น ๆ เช่นเดียวกันกับ operator - คือถ้าเอา address ของตัวแปรนั้น ๆ มาลบกันค่าที่ได้ก็ไม่ใช่ ค่าที่เป็น address มาลบกันเฉย ๆ แต่จะเป็น ค่าในลักษณะเดียวกันกับ operator +

มาดู Program ตัวอย่างกันดีกว่า

#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
int a;
int b;

cout << "&a = " << setw(8) << setfill('0') << hex << &a << endl
<< "&b = " << setw(8) << setfill('0') << hex << &b << endl
<< "&a - &b = " << (&a - &b) << endl
<< endl;
return 0;
}

&a = ffbefa80
&b = ffbefa7c
&a - &b = 1

Friday, October 07, 2005

union กะที่ใช้ที่น่าสนใจ

union ในภาษา C/C++ เป็นส่วนที่มีที่ใช้ไม่ค่อยมากมายนัก วันนี้ผมจะมาแสดงที่ใช้งานนึงที่น่าสนใจของ union

ก่อนอื่นก็ขอพูดถีึง union ก่อนนะครับ union เป็น type นึงของ data ก็ตามชื่อคือ มัน union ใช้พื้นที่จัดเก็บร่วมกันใน union type นั้น ๆ ขนาดของมันก็จะมีขนาดเท่ากับ max ของขนาดที่อยู่ใน union นั้น ๆ แต่ถ้ามีขนาดเท่ากัน เราสามารถนำมันไปใช้งานได้ตามตัวอย่างข้างล่างนี้คือ เรารู้ว่า data type นึงของเรามีขนาดเท่าไหร่ เราก็ประกาศ char array ให้มีขนาดเท่ากันเพื่อที่มันจะ share พื้นที่กันได้เต็มที ในตัวอย่างแสดงให้เห็นว่า เราสามารถ แสดง int ออกมาเป็น char array ได้โดยไม่ต้องเขียนอะไรเพิ่มมากเลยเพียงแค่ใช้ union นอกจากนี้เรายังสามารถ demonstrate endianess ของแต่ละ cpu architecture ด้วย

#include <iostream>
#include <iomanip>

using namespace std;
union testunion
{
int i;
char c[4];
};

int main()
{
union testunion a;
a.i = 0x01020304;

cout << setw(8) << hex << setfill('0') << a.i << " : "
<< setw(2) << setfill('0') << hex << (int)a.c[0]
<< setw(2) << setfill('0') << hex << (int)a.c[1]
<< setw(2) << setfill('0') << hex << (int)a.c[2]
<< setw(2) << setfill('0') << hex << (int)a.c[3] << endl;
return 0;
}

Windows Intel (of course)
01020304 : 04030201

Solaris Sparc
01020304 : 01020304

Solaris Intel
01020304 : 04030201


หวังว่า ตัวอย่างนี้จะทำให้เข้าใจการ concept และการใช้งานของ union ได้มากขึ้น

Wednesday, October 05, 2005

XOR เอาไปทำอะไรได้บ้าง

bitwise XOR operator หรือ ^ เป็น operator ที่ไม่ค่อยได้เห็นที่ใช้เท่าไหร่นัก

1st tip วันนี้จะเป็นการใช้ XOR เพื่อทำการ swap ค่าของตัวแปร

ก่อนอื่นก็ขออธิบายว่า XOR มันทำงานอย่างไร XOR operands ทั้ง 2 ตัวถ้าค่าเหมือนกันจะ return false ไม่เหมือนกัน return true

ตัวอย่างเช่น
true xor true ==> false
true xor false ==> true
etc.

หรือถ้าเขียนเป็น 1 กะ 0 ก็จะได้

1 xor 1 ==> 0
1 xor 0 ==> 1

xor มีคุณสมบัติอีกอย่างนึงคือ ค่าใดก็แล้วแต่ ถ้านำไป xor กะค่าอื่น 2 ครั้ง ค่าที่ได้ก็จะกลับคืนไปเป็นค่าเดิม
เช่น
1 xor 0 ==> 1 นำไป xor 0 อีกที ก็จะได้ 1
1 xor 1 ==> 0 นำไป xor 1 อีกทีี ก็จะได้ 1

น่าแปลกนะครับ และนี่ก็เป็นคุณสมบัติที่ทำให้เราสามารถเอาไปใช้เพื่อทำการ swap ค่า

ถ้าให้

a xor b xor b ==> a
b xor a xor a ==> b

มาถึงการ swap ละครับ โดยทั่วไปการ swap ค่าก็จะทำได้โดย

temp = a;
a = b;
b = temp;

เราก็จะได้ค่า a สลับกะ b แต่ในที่นี้เราต้องทำการเพิ่มตัวแปรเข้าไปอีก 1 ตัว

สมมติเรามีตัวแปรแค่ 2 ตัวละครับ เราก็สามารถทำได้ดังนี้ครับ

a = a ^ b; // a' = a ^ b
b = a ^ b; // b' = a' ^ b ซึ่งก็คือ b' = a ^ b ^ b ซึ่งก็เป็น a นั่นเอง
a = a ^ b; // a'' = a' ^ b' ซึ่งก็คือ a'' = a ^ b ^ a ซึ่งก็เป็น b นั่นเอง

นี่เป็นที่ใช้หนึ่งของ XOR

Introduction

Blog นี้ผมตั้งใจจะมีไว้ บันทึก เกร็ดเล็ก เกร็ดน้อย ของการ programming ทุกภาษาที่ผมรู้จัก รวมไปถึง concept ในการคิดด้วย