返璞归真vc++之字符类型

2023-10-24 03:59
文章标签 c++ 类型 字符 返璞归真

本文主要是介绍返璞归真vc++之字符类型,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  在今天,大量使用java与.net的程序员已经很少去真实了解字符的底层表达,但是使用VC++编程,对字符的处理却非常慎重,刚学习vc++肯定会为其中的字符类型给晕头转向,今天本人学习第一节,从字符开始

  特别说明:本文章所有开发环境选用vs2012开发

  在计算机系统中所有的数据与程序指令都是二进制的形式存在的,CPU处理器给特定序列的二进制序列包含有特殊的意义,及我们常说的计算机指令,计算机指令目前流行的X86指令集,以及目前流行android平台下arm指令集,同时所有的数据也是以二进制的形式表达在计算机中,主要表达在计算机体系中的内存,寄存器,以及CPU缓存。所以计算机认识到的字符也就是一串二进制格式的数据,计算机的首要任务就是给这些二进制进行字符的映射,但是在不同的指令集与CPU下,对这些二进制进行翻译的过程中又产生了高位与低位只说,这个只是CPU级别的二进制读取顺序,如何给这些特定的二进制翻译成我们熟悉的人类语言,于是就产生了我们经常所说的字符串编码,常用的有ASCII编码,以及Unicode,

  asccii编码,及单个字节编码,1个字节8个位,也就是说,在计算机内存中,8个连续的位能代码一个字符,那么如何映射成字符呢,那么就是通过我们的assicc表来实现,如下

八进制十六进制十进制字符八进制十六进制十进制字符
00000nul1004064@
01011soh1014165A
02022stx1024266B
03033etx1034367C
04044eot1044468D
05055enq1054569E
06066ack1064670F
07077bel1074771G
10088bs1104872H
11099ht1114973I
120a10nl1124a74J
130b11vt1134b75K
140c12ff1144c76L
150d13cr1154d77M
160e14so1164e78N
170f15si1174f79O
201016dle1205080P
211117dc11215181Q
221218dc21225282R
231319dc31235383S
241420dc41245484T
251521nak1255585U
261622syn1265686V
271723etb1275787W
301824can1305888X
311925em1315989Y
321a26sub1325a90Z
331b27esc1335b91[
341c28fs1345c92\
351d29gs1355d93]
361e30re1365e94^
371f31us1375f95_
402032sp1406096'
412133!1416197a
422234"1426298b
432335#1436399c
442436$14464100d
452537%14565101e
462638&14666102f
472739`14767103g
502840(15068104h
512941)15169105i
522a42*1526a106j
532b43+1536b107k
542c44,1546c108l
552d45-1556d109m
562e46.1566e110n
572f47/1576f111o
603048016070112p
613149116171113q
623250216272114r
633351316373115s
643452416474116t
653553516575117u
663654616676118v
673755716777119w
703856817078120x
713957917179121y
723a58:1727a122z
733b59;1737b123{
743c60<1747c124|
753d61=1757d125}
763e62>1767e126~
773f63?1777f127del

其中,每一个二进制序列对应这一个英文与数字字符,例如常说的十进制数65的二进制表达是1000001,对应的十六进制为0x41;

我们都知道c语言中,字符是用char类型表示,同时默认的编码格式为asccii编码,也就是说当0x41这个十六进制数在转换成整形值是65,在进行asccii字符转换时,如上表所示,即我们常说的大写字母A,

下面我们做一个实验,即可证明以上观点是否正确

#include "stdafx.h"int _tmain(int argc, _TCHAR* argv[])
{//数值数据int i=0x41;//内存数据按整形值翻译打印出来printf("this is int%d\n",i);//内存数据按照asccii翻译打印出来printf("this is char%c\n",i);//打印出内存数据的十六进制格式printf("this is binary 0x%x\n",i);return 0;
}

打印结果如下

由此可见,数据的表达都是二进制,只是人为的定义了一些一些含义,你认为是字符的时候,就转换成字符,你认为是数字的时候就变成了数字,你认为是指令的时候,就编程了是指令,只是指令已经被CPU确定了含义。

那么同理得出Unicode也是类似的结构,只是有点不同

1、Unicode为双字节编码,也就是说一个字符需要两个字节的容量才能保存

所以需要特别注意的地方到了,那么以上这些函数printf能处理Unicode字符串吗?

答案显然是不能的,我们依然写一个程序去验证我们的结果

 

#include "stdafx.h"
#include <Windows.h>int _tmain(int argc, _TCHAR* argv[])
{WCHAR unicodeChar='';printf("this is unicode Char%c\n",unicodeChar);return 0;
}

 

 打印的结论:

可以看到,最终被一个问号代替了,也就是说,printf函数并没有把他解析出来,它依然按照asccii标准去解析,所以变成了问号,那么疑问出来了

WCHAR到底是一个什么类型呢,怎么在c++标准中并不存在这样一个类型呢?

答案马上揭晓,我们找到了下面的宏定义

#ifndef _MAC //非苹果硬件平台
typedef wchar_t WCHAR;  //实际值是wchar_t  // wc,   16-bit UNICODE character
#else
// some Macintosh compilers don't define wchar_t in a convenient location, or define it as a char
typedef unsigned short WCHAR; //苹果硬件平台实际上是unsigned short
// wc, 16-bit UNICODE character #endif

 

 也就是如上所述:

所以在我们常用的电脑下,都是wchar_t类型,那么这又是一个什么类型呢?

百度百科给出的定义如下,http://baike.baidu.com/link?url=s9f5p8uJEuzVarbu0ilC2XTNRSEQHmxMM0pAHJE5w-Iysq2KFAmRXQUqSuYbbIF-AwmC0e_-Rtsy9NUKP6QVYK

char是8位字符类型,最多只能包含256种字符,许多外文字符集所含的字符数目超过256个,char型无法表示。
wchar_t数据类型一般为16位或32位,但不同的C或C++库有不同的规定,如GNU Libc规定wchar_t为32位[1],总之,wchar_t所能表示的字符数远超char型。
标准C++中的wprintf()函数以及iostream类库中的类和对象能提供wchar_t宽字符类型的相关操作。
所以是一个宽字符,也就是比char类型大,支持多种语言,比如东南亚国家的语言等,所以我认为在后续的编程中,应该尽可能的使用宽字符类型,同时对于宽字符类型,c++标准也提供了wprintf一系列类来操作
今天就是以上学习的内容啦,大概就这么多了,通过理解原理,然后去看vc++对这些类型的宏包装,其中不同类型的相互转换应该也是有所理解的。

转载于:https://www.cnblogs.com/lichaoxyz/p/3636906.html

这篇关于返璞归真vc++之字符类型的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/272551

相关文章

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

IDEA如何将String类型转json格式

《IDEA如何将String类型转json格式》在Java中,字符串字面量中的转义字符会被自动转换,但通过网络获取的字符串可能不会自动转换,为了解决IDEA无法识别JSON字符串的问题,可以在本地对字... 目录问题描述问题原因解决方案总结问题描述最近做项目需要使用Ai生成json,可生成String类型

Go语言使用Buffer实现高性能处理字节和字符

《Go语言使用Buffer实现高性能处理字节和字符》在Go中,bytes.Buffer是一个非常高效的类型,用于处理字节数据的读写操作,本文将详细介绍一下如何使用Buffer实现高性能处理字节和... 目录1. bytes.Buffer 的基本用法1.1. 创建和初始化 Buffer1.2. 使用 Writ

C++中实现调试日志输出

《C++中实现调试日志输出》在C++编程中,调试日志对于定位问题和优化代码至关重要,本文将介绍几种常用的调试日志输出方法,并教你如何在日志中添加时间戳,希望对大家有所帮助... 目录1. 使用 #ifdef _DEBUG 宏2. 加入时间戳:精确到毫秒3.Windows 和 MFC 中的调试日志方法MFC

深入理解C++ 空类大小

《深入理解C++空类大小》本文主要介绍了C++空类大小,规定空类大小为1字节,主要是为了保证对象的唯一性和可区分性,满足数组元素地址连续的要求,下面就来了解一下... 目录1. 保证对象的唯一性和可区分性2. 满足数组元素地址连续的要求3. 与C++的对象模型和内存管理机制相适配查看类对象内存在C++中,规

Mysql 中的多表连接和连接类型详解

《Mysql中的多表连接和连接类型详解》这篇文章详细介绍了MySQL中的多表连接及其各种类型,包括内连接、左连接、右连接、全外连接、自连接和交叉连接,通过这些连接方式,可以将分散在不同表中的相关数据... 目录什么是多表连接?1. 内连接(INNER JOIN)2. 左连接(LEFT JOIN 或 LEFT

Redis的Hash类型及相关命令小结

《Redis的Hash类型及相关命令小结》edisHash是一种数据结构,用于存储字段和值的映射关系,本文就来介绍一下Redis的Hash类型及相关命令小结,具有一定的参考价值,感兴趣的可以了解一下... 目录HSETHGETHEXISTSHDELHKEYSHVALSHGETALLHMGETHLENHSET

在 VSCode 中配置 C++ 开发环境的详细教程

《在VSCode中配置C++开发环境的详细教程》本文详细介绍了如何在VisualStudioCode(VSCode)中配置C++开发环境,包括安装必要的工具、配置编译器、设置调试环境等步骤,通... 目录如何在 VSCode 中配置 C++ 开发环境:详细教程1. 什么是 VSCode?2. 安装 VSCo

Python中异常类型ValueError使用方法与场景

《Python中异常类型ValueError使用方法与场景》:本文主要介绍Python中的ValueError异常类型,它在处理不合适的值时抛出,并提供如何有效使用ValueError的建议,文中... 目录前言什么是 ValueError?什么时候会用到 ValueError?场景 1: 转换数据类型场景

C# dynamic类型使用详解

《C#dynamic类型使用详解》C#中的dynamic类型允许在运行时确定对象的类型和成员,跳过编译时类型检查,适用于处理未知类型的对象或与动态语言互操作,dynamic支持动态成员解析、添加和删... 目录简介dynamic 的定义dynamic 的使用动态类型赋值访问成员动态方法调用dynamic 的