Lesson 3 Data Types Introduction to Computer and Program Design James C.C. Cheng Department of Computer Science National Chiao Tung University
Lesson 3 Data Types
Introduction to Computer and Program Design
James C.C. Cheng Department of Computer Science
National Chiao Tung University
The basic data types� l There are 13 basic data types in C
u In C++, bool represents boolean value, true or false.
¡ The size of bool depends on compiler, 1 byte in most case.
� 2
Name� Size (byte)� Range�
char� 1� -128 to 127�
unsigned char� 1� 0 to 255�
short� 2� -32768 to 32767�
unsigned short� 2� 0 to 65535�
int� 4� -231 to 231 - 1�
unsigned int� 4� 0 to 232 - 1�
long� 4� -231 to 231 - 1�
unsigned long� 4� 0 to 232 - 1�
__int64, long long� 8� -263 to 263 – 1�
unsigned __int64� 8� 0 to 264 - 1�
float� 4� ±(1.175494351e-38 to 3.402823466e38 )�
double� 8� ±(2.2250738585072014e-308 to 1.7976931348623158e308 )�
long double� 12 in DevC++, 8 in MSC� x86 80-bit extended precision format
The basic data types�
l sizeof operator u return the number of byte for a variable or a data type
size_t sizeof( name ); ¡ size_t
Ø In 32-bit environment: unsigned long
Ø In 64-bit environment: unsigned long long
¡ sizeof(type name)
Ø ex: sizeof(int); sizeof(double);
¡ sizeof(variable name) Ø ex: int x; sizeof(x); double d; sizeof(d);
Integers�
l The integer data types are: u bool, char, short, int, long, __int64
¡ bool in C99: #include <stdbool.h>
u unsigned char, unsigned short, unsigned int, unsigned long, unsigned __int64
4
5
Integers l Decimal system
u Each digit = {0, 1, …, 9 } u 347210 = ( 3 x 103 ) + ( 4 x 102 ) + ( 7 x 101 ) + ( 2 x 100 )
l Binary system u Each digit = {0, 1} u Binary è Decimal
¡ 10112 = (1 x 23)10 + (0 x 22)10 + (1 x 21)10 + (1 x 20)10 = 1110
u Decimal à Binary ¡ 13 mod 2 = 1 ¡ 13/2 = 6 mod 2 = 0 ¡ 6/2 = 3 mod 2 = 1 ¡ 3/2 = 1 mod 2 = 1 ¡ 1/2 =0
u Addition: 1+0 = 12 ; 1+1 = 102 u Subtraction: 1-0 = 12 ; 10-1 = 12
1310 = 11012
Integers� l Hexadecimal system
u Each digit = {0-9, A, B, C, D, E, F} u Hex è Decimal
¡ 3A7C = (3 x 163)10 + (10 x 162)10 + (7 x 161)10 + (12 x 160)10 = 1497210
u Decimal è Hex ¡ Method 1: the same as Decà binary ¡ Method 2: decèbinèhex
u Addition ¡ (2+7)16 = 916 ¡ (1+9)16 = A16 ¡ (2+B)16 = D16 ¡ (9+9)16 = 1216
u Subtraction ¡ (5-2)16 = 316 ¡ (F-2)16 = D16 ¡ (10-1)16 = F16 6
7
Integers l Binary è Hex
u Grouping each 4 digits from the smallest digit ¡ 11001110101101 = 0011,0011,1010,1101
u Check the hex ó bin table ¡ 0011,0011,1010,1101 = 33AD
Hex Binary
0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
A 1010
B 1011
C 1100
D 1101
E 1110
F 1111
8
Integers l The limits of unsigned integers
u 1 bit: ¡ 0, 1
u 4 bit: ¡ 0 ~ (24 – 1)10 = 0 ~ 1510
u 1 byte: ¡ 0 ~ (28 – 1)10 = 0 ~ 25510
u 2 byte: ¡ 0 ~ (216 – 1)10 = 0 ~ 65,53510
u 4 byte: ¡ 0 ~ (232 – 1)10 = 0 ~ 4,294,967,29510
u 8 byte: ¡ 0 ~ (264 – 1)10 = 0 ~ 18,446,744,073,709,551,61510
#include <limits.h> … unsigned char uc = UCHAR_MAX; unsigned short us = USHRT_MAX; unsigned int u = UINT_MAX; unsigned long ul = ULONG_MAX; unsigned long long ull = ULLONG_MAX;
Integers�
l The limits of signed integers�
9
#include <limits.h> … char c = CHAR_MIN; c = CHAR_MAX; short s = SHRT_MIN; s = SHRT_MAX; int i = INT_MIN; i = INT_MAX; long l = LONG_MIN; l = LONG_MAX; long long ll = LLONG_MIN; ll = LLONG_MAX;
10
Integers l Signed integer
u How to store a signed integer?
u Method 1: Sign bit
¡ The range is ±( 0 ~ 27 – 1) = ± (0 ~ 127)
¡ pros: simple
¡ cons:
Ø negative zero
Ø Addition and subtraction problems 1001,10112 + 0001,10112 = 1011,01102 è -27+27 = -54 …!?
1 0 0 1 1 0 1 1
0 0 0 1 1 0 1 1 Sign bit
= -27
= 27
11
Integers l Signed integer
u Method 2: One’s complement
¡ 27 = 0001,10112
¡ -27 = -(0001,10112) à 0/1 inversion à 1110,01002
¡ The range is ±( 0 ~ 27 – 1) = ± (0 ~ 127)
¡ Pros:
Ø Simple
Ø No addition and subtraction problems
1110,01002 + 0001,10112 = 1111,11112 è -27 + 27 = -0
1110,01002 + 0000,00012 = 1110,01012 è -27 + 1 = -26
¡ Cons:
Ø Negative zero
12
Integers l Signed integer
u Method 3: Two’s complement
¡ 27 = 0001,10112
¡ -27 = 1,0000,00002 - 0001,10112 = 1110,01012
¡ The range is - 27 ~ -1, 0, 1 ~ (27 – 1) = -128 ~ 127
¡ Pros:
Ø No negative zero
Ø No addition and subtraction problems
1110,01012 + 0001,10112 =
1,0000,00002 (max 8 bit) = 0000,00002 è -27 + 27 = 0
1110,01012 + 0000,00012 = 1110,01102
= -(1,0000,00002 - 1110,01102 ) = -(0001,1010)2 è -27 + 1 = -26
¡ Cons:
Ø It needs more conversion cost
Integers�
l Constants: u bool bT = true, bF = false, bTrue = 5438, bFalse = 0;
¡ The zero is false; Non-zero is true.
u char cA = ‘A’, cB = 66, cC= 65603, cD = 0x43, cE = 0105, cEnter = ‘\n’; ¡ Hex constant: Using the prefix "0x" ¡ Octal constant: Using the prefix "0"
u short i = 10, j = 32767, k = -32768, s = 32768, t = -32769;�
u int x = 10, y = -100, z = 0x02AB2F;
int nMax = 2147483647;
int nMinA = -2147483648; // It causes a warning message
int nMinB = (-2147483647 – 1); // OK!
13
- 2147483648 è - ( 2147483648 )�
Integers� l Constants:
u long n = 120, m = 12345L, a = 0xFFFFL;
¡ long integer constant : Using the suffix “L”
¡ __int64 nn = 10, mm = 9876543210LL;
¡ long long constant : Using the suffix “LL”
¡ 64-bit integer in scanf and printf: ll or I64
14
__int64 nn = 10; long long mm = 9876543210LL ; scanf("%I64d%lld", &nn, &mm); printf("%lld, %I64d \n", nn, mm); // OK, using “ll” or “I64” // Notice that "l" is lowercase. "L" means "long double", %Ld ==> %d nn = 7; mm = 1; printf("%d, %I64d \n", nn, mm); // In x86, the second output is wrong!?
07, 00, 00, 00� 00, 00, 00, 00� 01, 00, 00, 00� 00, 00, 00, 00�
nn mm
Integers�
l Constants: u unsigned char, unsigned short and unsigned int
u unsigned long : The suffix is “UL”
u unsigned __int64 :
¡ In Dev C++, the suffix is “LLU”
¡ In VC++, the suffix is “ULL” �
15
unsigned char uc = -1; unsigned short us = -1; unsigned int ui = -1; printf("%u, %u, %u\n", uc, us, ui);
unsigned long un0 = 123UL, un1 = -1UL; printf("%u, %u\n", un0, un1);
unsigned long long unn0 = 9876543210000001234LLU unsigned long long unn1 = -1LLU; printf("%llu, %I64u\n", unn0 , unn1 );
Integers�
l integers in printf and scanf u In printf
¡ <= 4byte argument è 4byte ¡ long long è 8 byte
u %d: singed decimal
u %i: signed decimal integer (In scanf, including hex and octal)
u %u: unsigned integer
u %o: unsigned octal integer
u %x: unsigned lowercase hex integer (in scanf, including lowercase and uppercase)
u %X: uppercase unsigned hex integer (Only in printf)
u %c: character
u %p: Address in hex digits. 32-bit: 8-digit, 64-bit: 16-digit (only in printf)
u %n: output the number of characters written/read so far, the argument shall be an integer point. ¡ In VC++, this function is disabled. 16
Integers�
l integers in printf and scanf u data length:
¡ hh: chat ¡ h: short
¡ l: long
¡ ll long long
17
char c = -1; printf("%02hhX\n", c); // Failed in DevC++ short s = -1; printf("%04hX\n", s); long l = -1L; printf("%08lX\n", l); long long ll = -1LL; printf("%016llX\n", ll);
Integers�
l Implicit typecast u small à large
u signed à unsigned�
18
short s1 = 10; int n1 = 0xFF0000; if(n1 > s1) // short ! int printf("Hello\n"); long long nn = 0x7FFFFFFF00000000ULL; if(nn > n1) // int ! long long printf("World!\n");
unsigned int u= 0; int i = -1; if(i>u) // int ! unsigned int printf("-1 > 0\n");
Float point numbers�
l float , 32-bit IEEE-754 float point number l double , 64-bit IEEE-754 float point number
l long double u In VC++, long double = double
u In GCC 4.3 or above, sizeof( long double) is 12 byte,
¡ In x86 environment, it only uses 10 byte
Ø Why it need 12 byte? In 32-bit environment, the data access unit is 4 byte.
¡ x86 80-bit extended precision format
19
20
Float point numbers l Decimal fraction ó Binary?
0.5 10 = 2-1 10 = 0.1 2
0.25 10 = 2-2 10 = 0.01 2
0.125 10 = 2-3 10 = 0.001 2
….
u 0.10112 = (1 x 2-1) 10 + (0 x 2-2) 10 + (1 x 2-3) 10 + (1 x 2-4) 10 = 0.510 + 0.12510 + 0.062510 = 0.687510
u 0.37510 = 0.011 0.375 * 2 = 0.75 0.75 * 2 = 1.5 0.5 * 2 = 1.0
u Some decimal fraction cannot be converted to binary system 0.410 = 0.001100110011……2
= 0.00112
21
Float point numbers l Decimal fraction ó Binary?
integer part ó binary
fraction part ó binary
u 13.562510 = 1101.10012 ¡ 1310 = 1101
¡ 0.562510 = 0.10012
22
Float point numbers l IEEE 754 (The IEEE Standard for Floating-Point Arithmetic)
u IEEE, Institute of Electrical and Electronics Engineers 國際電子電機學會 u 32-bit IEEE-754
¡ Sign: 1bit ¡ Exponent: 8 bit (127 offset) ¡ Fraction: 23 bit
u 64-bit IEEE-754 ¡ Sign: 1bit ¡ Exponent: 11 bit (1023 offset) ¡ Fraction: 52 bit
mantissa
Float point numbers�
l IEEE 754 (The IEEE Standard for Floating-Point Arithmetic) u Example:�
23
13.562510 = 1101.10012 = 1.10110012 * 23 For 32 bit float: = (-1)0 * 1.10110012 * 2130-127 à Sign = 0 à Exponent = 130 = 100000102 à Fraction = 10110010…02
For 64 bit float: = (-1)0 * 1.10110012 * 21026-1023 à Sign = 0 à Exponent = 1026= 100,0000,00102 à Fraction = 10110010…02
0 1 0 0 0 0 0 1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 à 0x41590000
, , , , , , 0 1 0 0 0 0 0 0 0 0 1 0 1 0 1 1 0 0 1 0 0 0 0 0 …� 0 à 0x402B20...0
, , , , , , ,
Float point numbers�
l x86 0-bit extended precision format ( for gcc's long double) u Sign: 1bit u Exponent: 15 bit (16383 offset) u Integer part: 1bit
¡ In 80387 or above, this bit always be 1 u Fraction: 63 bit
u Value = (-1)sign × 2exponent – 16383 × (1.fraction)2 u Reference:
¡ http://en.wikipedia.org/wiki/Extended_precision
24
…� 1 …� Sign Exponent Integer Fraction
Float point numbers�
l Addition and subtraction u 13.562510 + 0.1562510 = 13.7187510
= (-1)0 * 23 * 1.10110012 + (-1)0 * 2-3 * 1.012 = 23 * 1.10110012 + 23 * 2-6 * 1.012
= 23 * 1.10110012 + 23 * 0.000001012
= 23 * 1.101101112
= 13.7187510
u 13.562510 - 0.1562510 = 13.4062510 = (-1)0 * 23 * 1.10110012 + (-1)1 * 2-3 * 1.012
= 23 * 1.10110012 + (-1) * 23 * 2-6 * 1.012
= 23 * 1.10110012 + (-1) * 23 * 0.000001012
= 23 * 1.10110012 + 23 * 1.111110112
= 23 * 11.101011012 è(Overflow)è 23 * 1.101011012 = 13. 4062510
25
} 2's complement
Float point numbers�
l Truncation and Rounding u Example:
26
1234567.210 = 1,0010,1101,0110,1000,0111. 0011,0011,0011... 2 = 1. 0010,1101,0110,1000,0111 0011,0011,0011... 2 * 220 For 32 bit float: = (-1)0 * 1. 0010,1101,0110,1000,0111 0011,0011,0011... 2 * 2147-127 à Sign = 0 à Exponent = 147 = 100100112 à Fraction (23 bit) = 0010,1101,0110,1000,0111 0011,0011,0011 2 Truncation
= 0010,1101,0110,1000,0111 010 2 Rounding è(1234567.25)
1234567.1510 = 1,0010,1101,0110,1000,0111. 0010,0110,0110,... 2 = 1. 0010,1101,0110,1000,0111 0010,0110,0110... 2 * 220 For 32 bit float: = (-1)0 * 1. 0010,1101,0110,1000,0111 0010,0110,0110... 2 * 2147-127 à Sign = 0 à Exponent = 147 = 100100112 à Fraction (23 bit) = 0010,1101,0110,1000,0111 0010,0110,0110 2 Truncation
= 0010,1101,0110,1000,0111 001 2 è(1234567.125)
27
Float point numbers l Limits
Float Values (b = bias)
Sign Exponent (e ) Fraction (f ) Value
0 00..00 00..00 0
0 00..00 00..01~ Positive Denormalized Real
11..11 0.f × 2(-b+1)
0 00..01~
XX..XX Positive Normalized Real
11..10 1.f × 2(e-b) 0 11..11 00..00 +Infinity
0 11..11 00..01~
NaN 11..11
28
Float point numbers l Limits
Sign Exponent (e) Fraction (f) Value
1 00..00 00..00 -0
1 00..00 00..01~ Negative Denormalized Real
11..11 -0.f × 2(-b+1)
1 00..01~
XX..XX Negative Normalized Real
11..10 -1.f × 2(e-b) 1 11..11 00..00 -Infinity
1 11..11 00..01~
NaN 11.11
Float point numbers�
l Limits�
29
#include <float.h> … float f = FLT_MIN; f = FLT_MAX; double d = DBL_MIN; d = DBL_MAX; long double ld = LDBL_MIN; ld = LDBL_MAX; printf("%f\n", f); printf("%f\n", d); printf("%Lf\n", ld); // only in GCC 4.3 or above
30
Float point numbers l printf()
u float will be converted to double
u %f, %e, %E, %g, and %G need 8 byte argument
u %+width+.precision + {f/e/E/g/G},
¡ width: the minimum number of characters printed, if width is not given, all characters of the value are printed.
¡ precision:
Ø for f/e/E : the number of digits after the decimal point,
Ø for g/G: the maximum number of significant digits printed.
Ø default is six
float r = 0.00000123; printf("%10.8f, %4.2e, %4.2g\n", r, r, r);
0.00000123, 1.23e-006, 1.2e-006 Output:
Float point numbers�
l scanf() u %f: float, 4 byte data
u %lf: double 8 byte data
u %Lf: long double ¡ Only in GCC 4.3 or above è *.c file
¡ G++ does not accept %Lf�
31
Float point numbers�
l Constants: u float f = 1.1234f;
¡ Using the suffix "f" u double r0 = 1.12345, r1 = 123, r2 = 0x64, r3 = 123LLU;
¡ Without any prefix and suffix
l Typecast u integer à float
u float à double
32
float fx = 33.3f; printf("%f\n", fx * 2 / 3 );
#include <float.h> … float fx = 0.0f; double dx = fx + DBL_MIN; printf("%f\n", dx);
Float point numbers� l Never check a floating number to EQUAL a value
33
float A = 1.2f; float B = 12.0f; scanf("%f%f", &A, &B); // type 1.2 and 12 float D = A - B / 10.0f; // D = 1.2 – 12/10.0 should be zero if(D == 0.0) // Oops! printf("!\n"); else printf("%f\n", D); // This line will be show up
Float point numbers�
l Be careful with using a floating number to be an iterator �
34
float i; for(i=0.0f; i<=1.0f; i+=0.1f) printf("%f\n", i); // How many lines will be displayed?
35
Union l One memory space to be accessed as different data types l The size of the union is at least the size of the largest member. �
union U{ unsigned long i; float f; }; int main(){ U u; u.f = 13.5625f; printf("%08X\n", u.i); // 41590000 printf("%08X\n", u.f); // In x86: 00000000 printf("%08X%08X\n", u.f); // In x86: 00000000402B2000 // Three printing method for float. Which one is the best? };
Characters� l ASCII (American Standard Code for Information Interchange)
u '0'~'9': 48~57
u 'A'~'Z': 65~90
u 'a'~'z': 97~122
u http://en.wikipedia.org/wiki/ASCII
l Constants:
u Using the single quotation marks ' '
�
36
char a = 'A'; printf("%c: %d\n", a, a); a = '9'; printf("%c: %d\n", a, a); a = 'xyz'; printf("%c: %d\n", a, a); a = "uvw"; // Compiling error!
char a = 50, b = 70, c= 100; printf("%c%c%c\n", a, b, c);
Characters� l Escape Sequences
u \n: (10) newline
u \t: (9) tab
u \b: (8) backspace
u \r: (13) return key ¡ In MS Windows, the end of line consists of two characters: \r\n (13, 10)
u \': single quotation
u \": double quotation
u \\: backslash
u \0: null
u \OOO: OOO is 3-digit octal ASCII ¡ char e = '\050',
u \xOO: OO is 2-digit hex ASCII ¡ char i = '\x41',
37
char a = '\n', b = '\t', c= '\b'; char d = '\r', i = '\'', j = '\"'; char f = '\\', g = '\0';
Strings� l A character array l The last character of a string must be \0
l Constant string: Using the double quotation marks " "
l String declaration and initialization:
38
char s1[5] = "abcd"; // a writable char array char s2[5] = {'A', 'B', 'C', 'D', 0}; // a writable char array char s3[] = "xyz"; // a writable char array char s4[] = { 'X', 'Y', 'Z', 0}; // a writable char array char* s5 = "uvw"; // a char pointer that points a read-only data printf("%s\n%s\n%s\n%s\n%s\n", s1, s2, s3, s4, s5); s1[0] = 'T'; // OK! s5[0] = 'T'; // Runtime error char* s6 = { 'U', 'V', 'W', 0}; // Compiler error
Strings�
l Misuse �
39
char *s1 = "abcd"; char s2[] = "ABCD"; printf("%s\n%s\n", s1, s2);
s1 = s2; // The pointer can be an l-value printf("%s\n%s\n", s1, s2); // ABCD, ABCD s2[0] = 'T'; // Watch the side effect! printf("%s\n%s\n", s1, s2); // TBCD, TBCD
char s1[] = "abcd"; char s2[] = "ABCD"; s1 = s2; // Compiling error! The array name cannot be an l-value
side effect A expression returns one or more additional values. That means it modifies some observable state.
Strings� l scanf()
u %[ ]: Read the specified characters ¡ Input ends when a non-matching character is reached or the field width is reached.
40
char A[20] = {0}; // Declare a string of 20 zero characters scanf("%s", A); // type "ABC EFG XYZ" printf("%s\n", A);
char A[20] = {0}, B[20] = {0}, C[20] = {0}; scanf("%s%s%s", A , B, C); // type "ABC EFG XYZ" printf("%s %s %s\n", A, B, C);
char A[20] = {0}, B[20] = {0}, C[20] = {0}; scanf("%[0-9]%[A-Z]%[a-z]", A , B, C); printf("%s%s%s\n", A, B, C); scanf("%[ -~, '\t']", A);
// Read ASCII 9 and 32 to 126 printf("%s\n", A); scanf("%[ -~, '\t', '\n' ]", A); // Oops….
Strings�
l scanf() u %[^ ]: Read the characters except the specified characters
41
char A[20] = {0}, B[20] = {0}, C[20] = {0}; scanf("%[^0-9]%[^A-Z]%[^a-z]", A , B, C); printf("%s %s %s\n", A, B, C); scanf("%[^'\n']", A); // Read all characters except '\n' printf("%s\n", A);
Strings�
l gets() u char* gets ( char *s);
u It reads characters from the stdin and stores them into s until a newline character or the end-of-file is reached.
u On success, it returns s. Otherwise, it returns NULL�
42
#include <stdio.h> … char A[100] = {0}; while( gets(A) != NULL ){ printf("%s\n", A); }
Typecast� l Change the data type of variable
¡ x = (x's type name) y;
u Ex:
43
int n = 1234; float f = (float) n; char c = (char) f; double d = (double) c;
#define� l The text replacement
l Usage: #define replacement target_text
l Ex:�
#define PI 3.14159
#define EXP 2.71828
#define NULL_STR
double p = PI;
printf("%f\n", p); // 3.14159
printf("%f\n", EXP); // 2.71828
printf("%f\n", NULL_STR); // Compile Error
printf("%f\n", NULL_STREXP); // Compile Error
printf("%f\n", NULL_STR EXP); // 2.71828 44
#define� l Macro, 巨集 l Ex:
#define MIN_INT(x) (-2147483647 – 1)�
#define INC(x) (++x)
#define ADD(x, y) (x+y)
#define MIN(x, y) (x<y?x:y)
#define _MIN(x, y) x<y?x:ytice
float x = PI * MIN(2.0f, 3.0f); // x = 6.28298
float y = PI * _MIN(2.0f, 3.0f); // y = 3.0 !?
45
請注意括號!
#define� l Do not use #define to define a data type l Ex:
46
#define uint unsigned int uint a, b ; // OK! a and b are unsigned int
char *s1 = " Hello ", *s2 = " World "; #define CSTR char * CSTR s3 = " OK ", s4 = " oops ";
// s4 is not a char *
typedef� l To define a datatype l The usage:
typedef original_typename new_typename;
l EX:
47
注意要加分號
typedef unsigned int uint; uint a, b ; // OK! a and b are unsigned int typedef char * cstr; cstr sA = "Hello", sB = "world!"; printf("%s, %s\n", sA, sB ); // OK!
練習題� l 設計一個函式,名為inverseN,用來反轉一個unsigned long
例如:12345則回傳54321;12321則回傳12321;0則回傳0 須注意overflow,若數字2223334445則回傳0並顯示overflow。 請用最節省空間方式完成,不可用64bit整數、字串及陣列
l 給一個double陣列A,用來儲存某數學函數的運算結果,即A[i] = f(ix)。 請寫一個函式來計算f 的微分:𝑓′(𝑥)≅ 𝑓(𝑥+𝑑)−𝑓(𝑥−𝑑)/2𝑑 è𝑓′(𝑖𝑥)≅ 𝐴[𝑖+1]−𝐴[𝑖−1]/2 void dev(const double* A, double* B, int n); 其中A為輸入陣列,B為微分結果,n為陣列元素個數。 A[i] = 0 if i < 0 or i >= n
48
練習題�
l 請設計generic min & max functions,可處理所有C語言的基本資料型態,並回傳最大值及最小值。 void GMin(const void *pa, const void *pb, void *pOut, size_t n); void GMax(const void *pa, const void *pb, void *pOut, size_t n); pa及pb兩者為指向同一資料型態的輸入,pOut為輸出,n為資料大小(byte)
l 請以上題來實作generic 的bubble sort void bbsort(void *p, int n, size_t m, char dir); p為指向欲排序的資料陣列,n為陣列元素個數,m為每個元素的資料大小(byte) 若dir為0,則由小排到大,若不為0 ,則由大排到小
49