官术网_书友最值得收藏!

Character types

The most basic type in C and C++ is the following character type:

#include <iostream>

int main(void)
{
char c = 0x42;
std::cout << c << '\n';
}

// > g++ scratchpad.cpp; ./a.out
// B

A char is an integer type that, on most platforms, is 8 bits in size, and must be capable of taking on the value range of [0, 255] for unsigned, and [-127, 127] for signed. The difference between a char and the other integer types is that a char has a special meaning, corresponding with the American Standard Code for Information Interchange (ASCII). In the preceding example, the uppercase letter B is represented by the 8-bit value 0x42. It should be noted that although a char can be used to simply represent an 8-bit integer type, its default meaning is a character type; that's why it has a special meaning. For example, consider the following code: 

#include <iostream>

int main(void)
{
int i = 0x42;
char c = 0x42;

std::cout << i << '\n';
std::cout << c << '\n';
}

// > g++ scratchpad.cpp; ./a.out
// 66
// B

In the previous example, we represented the same integer type, 0x42, using both an int (to be explained later) and a char. These two values are, however, output to stdout in two different ways. The integer is output as an integer while, using the same APIs, the char is output as its ASCII representation. In addition, arrays of char types are considered to be an ASCII string type in both C and C++, which also has a special meaning. The following code shows this:

#include <iostream>

int main(void)
{
const char *str = "Hello World\n";
std::cout << str;
}

// > g++ scratchpad.cpp; ./a.out
// Hello World

From the preceding example, we understand the following. We define an ASCII string using a char pointer (an unbounded array type would also work in this case); std::cout understands how to handle this type by default, and a char array has a special meaning. Changing the array type to an int would not compile, as the compiler would not know how to convert the string to an array on integers, and std::cout would not know, by default, how to handle the array of integers, even though, on some platforms, an int and a char might actually be the same type. 

Like a bool and short int, the character type is not always the most efficient type to use when representing an 8-bit integer, and as alluded to in the previous code, on some platforms, it is possible for a char to actually be larger than 8 bits, a topic that will be discussed in further detail when we discuss integers. 

To further investigate the char type, as well as the other types being discussed in this section, let's leverage the std::numeric_limits{} class. This class provides a simple wrapper around limits.h, which provides us with a means to query how a type is implemented on a given platform in real time using a collection of static member functions. 

For example, consider the following code:

#include <iostream>

int main(void)
{
auto num_bytes_signed = sizeof(signed char);
auto min_signed = std::numeric_limits<signed char>().min();
auto max_signed = std::numeric_limits<signed char>().max();

auto num_bytes_unsigned = sizeof(unsigned char);
auto min_unsigned = std::numeric_limits<unsigned char>().min();
auto max_unsigned = std::numeric_limits<unsigned char>().max();

std::cout << "num bytes (signed): " << num_bytes_signed << '\n';
std::cout << "min value (signed): " << +min_signed << '\n';
std::cout << "max value (signed): " << +max_signed << '\n';

std::cout << '\n';

std::cout << "num bytes (unsigned): " << num_bytes_unsigned << '\n';
std::cout << "min value (unsigned): " << +min_unsigned << '\n';
std::cout << "max value (unsigned): " << +max_unsigned << '\n';
}

// > g++ scratchpad.cpp; ./a.out
// num bytes (signed): 1
// min value (signed): -128
// max value (signed): 127

// num bytes (unsigned): 1
// min value (unsigned): 0
// max value (unsigned): 255

In the preceding example, we leverage std::numeric_limits{} to tell us the min and max value for both a signed and unsigned char (it should be noted that all examples in this book were performed on a standard Intel 64-bit CPU, and it is assumed that these same examples can, in fact, be executed on different platforms for which the values being returned might be different). The std::numeric_limits{} class can provide real-time information about a type, including the following:

  • Signed or unsigned 
  • Conversion limits, such as rounding and the total number of digits needed to represent the type
  • Min and max information

As shown in the preceding example, a char on a 64-bit Intel CPU is 1 byte in size (that is, 8 bits), and takes on the values [0, 255] for an unsigned char and [-127, 127] for a signed char, as stated by the specification. Let's look at a wide char or wchar_t:

#include <iostream>

int main(void)
{
auto num_bytes_signed = sizeof(signed wchar_t);
auto min_signed = std::numeric_limits<signed wchar_t>().min();
auto max_signed = std::numeric_limits<signed wchar_t>().max();

auto num_bytes_unsigned = sizeof(unsigned wchar_t);
auto min_unsigned = std::numeric_limits<unsigned wchar_t>().min();
auto max_unsigned = std::numeric_limits<unsigned wchar_t>().max();

std::cout << "num bytes (signed): " << num_bytes_signed << '\n';
std::cout << "min value (signed): " << +min_signed << '\n';
std::cout << "max value (signed): " << +max_signed << '\n';

std::cout << '\n';

std::cout << "num bytes (unsigned): " << num_bytes_unsigned << '\n';
std::cout << "min value (unsigned): " << +min_unsigned << '\n';
std::cout << "max value (unsigned): " << +max_unsigned << '\n';
}

// > g++ scratchpad.cpp; ./a.out
// num bytes (signed): 4
// min value (signed): -2147483648
// max value (signed): 2147483647

// num bytes (unsigned): 4
// min value (unsigned): 0
// max value (unsigned): 4294967295

A wchar_t represents Unicode characters and its size depends on the operating system. On most Unix-based systems, a wchar_t is 4 bytes, and can represent a UTF-32 character type, as shown in the previous example, while on Windows, a wchar_t is 2 bytes in size, and can represent a UTF-16 character type. Executing the previous example on either of these operating systems will result in a different output.

This is extremely important, and this issue defines the fundamental theme of this entire chapter; the default types that C and C++ provide are different depending on the CPU architecture, the operating system, and in some cases, if the application is running in user space or in the kernel (for example, when a 32-bit application is executing on a 64-bit kernel). Never assume, while system programming, that when interfacing with a system call, that your application's definition of a specific type is the same as the type the API assumes. Quite often, this assumption will prove to be invalid. 

主站蜘蛛池模板: 怀集县| 武隆县| 轮台县| 湟中县| 汕头市| 大关县| 博客| 慈溪市| 岑巩县| 固原市| 迁西县| 宝坻区| 五台县| 六安市| 江都市| 南澳县| 昌邑市| 宁德市| 永康市| 额济纳旗| 宁都县| 彩票| 左云县| 扎囊县| 鹤壁市| 泰顺县| 泗水县| 平昌县| 廉江市| 双牌县| 平乡县| 兴隆县| 海晏县| 建瓯市| 焉耆| 盐亭县| 措美县| 湖南省| 汉中市| 余姚市| 陇南市|