Variable size/Set: Difference between revisions
(Things like hash tables are now stored in a more optimised manner.) |
(Add Python ctypes) |
||
Line 43: | Line 43: | ||
In Perl, memory is readily and happily traded for expressiveness and ease of use. |
In Perl, memory is readily and happily traded for expressiveness and ease of use. |
||
=={{header|Python}}== |
|||
For compatibility with the calling conventions of external C functions, the [http://docs.python.org/library/ctypes.html?highlight=ctypes#module-ctypes ctypes module] has functions that map data types and sizes between Python and C: |
|||
<table class="docutils" border="1"> |
|||
<tr> |
|||
<th class="head">ctypes type</th> |
|||
<th class="head">C type</th> |
|||
<th class="head">Python type</th> |
|||
</tr> |
|||
<tr> |
|||
<td>c_char</td> |
|||
<td>char</td> |
|||
<td>1-character string</td> |
|||
</tr> |
|||
<tr> |
|||
<td>c_wchar</td> |
|||
<td>wchar_t</td> |
|||
<td>1-character unicode string</td> |
|||
</tr> |
|||
<tr> |
|||
<td>c_byte</td> |
|||
<td>char</td> |
|||
<td>int/long</td> |
|||
</tr> |
|||
<tr> |
|||
<td>c_ubyte</td> |
|||
<td>unsigned char</td> |
|||
<td>int/long</td> |
|||
</tr> |
|||
<tr> |
|||
<td>c_short</td> |
|||
<td>short</td> |
|||
<td>int/long</td> |
|||
</tr> |
|||
<tr> |
|||
<td>c_ushort</td> |
|||
<td>unsigned short</td> |
|||
<td>int/long</td> |
|||
</tr> |
|||
<tr> |
|||
<td>c_int</td> |
|||
<td>int</td> |
|||
<td>int/long</td> |
|||
</tr> |
|||
<tr> |
|||
<td>c_uint</td> |
|||
<td>unsigned int</td> |
|||
<td>int/long</td> |
|||
</tr> |
|||
<tr> |
|||
<td>c_long</td> |
|||
<td>long</td> |
|||
<td>int/long</td> |
|||
</tr> |
|||
<tr> |
|||
<td>c_ulong</td> |
|||
<td>unsigned long</td> |
|||
<td>int/long</td> |
|||
</tr> |
|||
<tr> |
|||
<td>c_longlong</td> |
|||
<td>__int64 or long long</td> |
|||
<td>int/long</td> |
|||
</tr> |
|||
<tr> |
|||
<td>c_ulonglong</td> |
|||
<td>unsigned __int64 or |
|||
unsigned long long</td> |
|||
<td>int/long</td> |
|||
</tr> |
|||
<tr> |
|||
<td>c_float</td> |
|||
<td>float</td> |
|||
<td>float</td> |
|||
</tr> |
|||
<tr> |
|||
<td>c_double</td> |
|||
<td>double</td> |
|||
<td>float</td> |
|||
</tr> |
|||
<tr> |
|||
<td>c_longdouble</td> |
|||
<td>long double</td> |
|||
<td>float</td> |
|||
</tr> |
|||
<tr> |
|||
<td>c_char_p</td> |
|||
<td>char * (NUL terminated)</td> |
|||
<td>string or None</td> |
|||
</tr> |
|||
<tr> |
|||
<td>c_wchar_p</td> |
|||
<td>wchar_t * (NUL terminated)</td> |
|||
<td>unicode or None</td> |
|||
</tr> |
|||
<tr> |
|||
<td>c_void_p</td> |
|||
<td>void *</td> |
|||
<td>int/long or None</td> |
|||
</tr> |
|||
</table> |
|||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
Revision as of 05:01, 7 July 2009
You are encouraged to solve this task according to the task description, using any language you may know.
Demonstrate how to specify the minimum size of a variable or a data type.
Ada
<lang ada> type Response is (Yes, No); -- Definition of an enumeration type with two values for Response'Size use 1; -- Setting the size of Response to 1 bit, rather than the default single byte size </lang>
C
<lang c>#include <stdint.h>
int_least32_t foo;</lang>
Here foo is a signed integer with at least 32 bits. stdint.h also defines minimum-width types for at least 8, 16, 32, and 64 bits, as well as unsigned integer types.
D
In D, any variables of static array of zero length has a size of zero. But such data is useless, as no base type element can be accessed.
<lang d>
typedef long[0] zeroLength ;
writefln(zeroLength.sizeof) ; // print 0
</lang>
NOTE: a dynamic array variable's size is always 8 bytes, 4(32-bit) for length and 4 for a reference pointer of the actual storage somewhere in runtime memory.
The proper candidates of minimum size variable are empty structure, 1-byte size data type variable (include byte, ubyte, char and bool), and void, they all occupy 1 byte.
<lang d>
byte b ;
ubyte ub ;
char c ;
bool t ;
</lang>
bool is logically 1-bit size, but it actually occupy 1 byte.
void can't be declared alone, but void.sizeof gives 1.
An empty structure is logically zero size, but still occupy 1 byte.
<lang d>
struct Empty { }
writefln(Empty.sizeof) ; // print 1
</lang>
Perl
I suppose you could use vec() or similar to twiddle a single bit. The thing is, as soon as you store this in a variable, the SV (the underlying C implementation of the most simple data type) already takes a couple dozen of bytes.
In Perl, memory is readily and happily traded for expressiveness and ease of use.
Python
For compatibility with the calling conventions of external C functions, the ctypes module has functions that map data types and sizes between Python and C:
ctypes type | C type | Python type |
---|---|---|
c_char | char | 1-character string |
c_wchar | wchar_t | 1-character unicode string |
c_byte | char | int/long |
c_ubyte | unsigned char | int/long |
c_short | short | int/long |
c_ushort | unsigned short | int/long |
c_int | int | int/long |
c_uint | unsigned int | int/long |
c_long | long | int/long |
c_ulong | unsigned long | int/long |
c_longlong | __int64 or long long | int/long |
c_ulonglong | unsigned __int64 or unsigned long long | int/long |
c_float | float | float |
c_double | double | float |
c_longdouble | long double | float |
c_char_p | char * (NUL terminated) | string or None |
c_wchar_p | wchar_t * (NUL terminated) | unicode or None |
c_void_p | void * | int/long or None |
Tcl
In Tcl, most values are (Unicode) strings. Their size is measured in characters, and the minimum size of a string is of course 0. However, one can arrange, via write traces, that the value of a variable is reformatted to bigger size. Examples, from an interactive tclsh session: <lang Tcl>% proc format_trace {fmt _var el op} {upvar 1 $_var v; set v [format $fmt $v]}
% trace var foo w {format_trace %10s} % puts "/[set foo bar]/" / bar/
% trace var grill w {format_trace %-10s} % puts "/[set grill bar]/" /bar /</lang> ..or limit its size to a certain length: <lang Tcl>% proc range_trace {n _var el op} {upvar 1 $_var v; set v [string range $v 0 [incr n -1]]}
% trace var baz w {range_trace 2} % set baz Frankfurt Fr</lang>