Windows 程序设计3:宽窄字节的区别及重要性

文章目录

  • 前言
  • 一、宽窄字节简介
  • 二、操作系统及VS编译器对宽窄字节的编码支持
    • 1. 操作系统
    • 2. 编译器
  • 三、宽窄字符串的优缺点
  • 四、宽窄字节数据类型
  • 总结


前言

Windows 程序设计3:宽窄字节的区别及重要性。


一、宽窄字节简介

在C++中,常用的字符串指针就是char* ,字符串变量为string,内部也是对char* 的封装,但是并不了解这些跟宽窄字节有什么关系。

实际上,最早的系统都是窄字节的,也就是我们最常用的char,因为都是英文的一共就26个字母,再加上其他的一些符号标点,char就足够用了。无符号的char最多可以表示255个字符,已经足够。

后来随着操作系统的国际化,系统出现了很多语言版本。原来的char表示一个英文字符的方式已经无法表达一个中文汉字了。汉字有好几万个,单纯的char取值范围已经不够了。此时有人想到,一个char表示不下那就用两个char来表示一个汉字。因此,数字、字母等仍用窄字节,也就是一个char来表示;一个汉字或全角字符等使用两个char来表示。

虽然这样可以基本解决问题,即在中文系统上能正常显示中文、在其他语言系统上也能够正常显示,但是如果想把一个在中文系统上写的软件拿到日文或韩文等其他语言的系统上就会出现乱码,汉字是无法正常显示的。同理,其他语言的软件拿到中文系统上也会出现乱码。

那么为了解决这样国际化的问题,微软在Windows系统中引入了宽字节的功能,即Unicode。Unicode中规定任意一个字符都占用两个字节,即两个char。无论是字符还是字母、数字、汉字都占用两个字节。用两个char难免造成不方便,因此微软定义了一个新的类型:wchar_t,其原型实际上就是unsigner short,占用两个字节。

二、操作系统及VS编译器对宽窄字节的编码支持

1. 操作系统

Windows提供了两种类型的API函数,如MessageBox函数,实际上MessageBox函数只是一个宏,其对应了两个版本的函数:MessageBoxA和MessageBoxW,在VS编译器中使用时系统会根据是否定义了_UNICODE宏来进行判断当前工程使用宽字节的Unicode编码还是窄字节编码,以此来决定使用哪个版本的函数。如果没有定义,则使用窄字节的MessageBoxA;如果定义了就使用宽字节的MessageBoxW。
右键MessageBox,点击转到定义
在这里插入图片描述
可以看到该宏的具体定义
在这里插入图片描述
可以利用Depends工具查看动态链接库中的函数,见https://blog.csdn.net/qq_59940419/article/details/144721964?spm=1001.2014.3001.5502,MessageBox在User32.dll中,打开如下路径:C:\Windows\System32,找到User32.dll将其拖入到Depends工具中,可以找到两个函数。
在这里插入图片描述
其他的很多函数也都是这样进行区分宽窄字节的。大家可以自己看一看。

说明:Windows 2000以后的系统都是使用Unicode从头进行开发的,如果调用任何一个Windows API函数并传递一个ANSI即窄字节的字符串,那么系统会首先将字符串转换为Unicode,然后将Unicode即宽字节的字符串传递给操作系统。如果希望函数返回ANSI字符串,系统就会先将Unicode字符串转换为ANSI字符串,然后将结果返回给应用程序。进行这些字符串的转换需要占用系统的时间和内存,通过从头开始使用Unicode来开发应用程序,可以使得应用程序运行得更加高效。因此开发时建议使用宽字节。

2. 编译器

VC++6.0默认为窄字节编码。vs2005, vs2008, vs2010, vs2012, vs2013, vs2015, vs2017等等都是默认Unicode编码。也可以在工程中设置编码方式。
右键项目,点击属性
在这里插入图片描述
可以在字符集处调整编码方式
在这里插入图片描述
注意:从vs2013开始,如果要将工程默认的Unicode编码转为窄字节编码,需要安装多字节补丁。

三、宽窄字符串的优缺点

即便Unicode宽字节相对来说更好,但是其也有缺点。

一般来说,设计界面和跟字符串操作相关的,推荐使用宽字节。其他地方还是可以使用窄字节的,因为宽字节的占用空间是窄字节的二倍。这样的话在本机还好,如果涉及字符串的网络传输,那么传输量会偏大。所以也不是说什么时候都要使用Unicode宽字节。

在一个工程中,有的地方使用宽字节,有的地方使用窄字节(如一些代码逻辑和网络传输使用窄字节,界面设计使用宽字节),这就需要进行宽窄字节的转换。微软提供相应的API函数,直接使用即可。

四、宽窄字节数据类型

大家熟知的char, char* 都是窄字节的。常见的一些数据类型如下:
窄字节:
char, char* , const char*
CHAR, (PCHAR, PSTR, LPSTR), LPCSTR

Unicode宽字节:
wchar_t, wchar_t* , const wchar_t*
WCHAR, (PWCHAR, PWSTR, LPWSTR), LPCWSTR

_T通用类型:
TCHAR, (TCHAR* , PTCHAR, PTSTR, LPTSTR), LPCTSTR

其中,P代表指针的思想,STR表示字符串的意思,L是长指针的意思(在Win32平台下可以忽略),C表示const常量的意思,W表示wide宽字节的意思,T可以理解为通用类型的意思。

可以根据工程中是否定义_UNICODE宏,来判断当前工程的编码是宽字节还是窄字节,然后再定义成不同的类型。比如TCHAR类型,如果工程中定义了_UNICODE宏,那么就表明工程是宽字节编码的,其最终就被定义为wchar_t类型,如果工程中没有定义_UNICODE宏,就表明工程是窄字节编码的,其最终被定义为char类型。通用类型的优势在于,在修改了工程的编码格式之后不需要修改代码,因此更加建议使用通用类型。


总结

Windows 程序设计3:宽窄字节的区别及重要性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/65799.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

进阶——十六届蓝桥杯嵌入式熟练度练习(LED的全开,全闭,点亮指定灯,交替闪烁,PWM控制LED呼吸灯)

点亮灯的函数 void led_show(unsigned char upled) { HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOC,upled<<8,GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RE…

力扣 最大子数组和

动态规划&#xff0c;前缀和&#xff0c;维护状态更新。 题目 从题可以看出&#xff0c;找的是最大和的连续子数组&#xff0c;即一个数组中的其中一个连续部分。从前往后遍历&#xff0c;每遍历到一个数可以尝试做叠加&#xff0c;注意是尝试&#xff0c;因为有可能会遇到一个…

Homestyler 和 Tripo AI 如何利用人工智能驱动的 3D 建模改变定制室内设计

让设计梦想照进现实 在Homestyler,我们致力于为每一个梦想设计师提供灵感的源泉,而非挫折。无论是初学者打造第一套公寓,或是专业设计师展示作品集,我们的直观工具都能让您轻松以惊人的3D形式呈现空间。 挑战:实现定制设计的新纪元 我们知道,将个人物品如传家宝椅子、…

如何当前正在运行的 Elasticsearch 集群信息

要查看当前正在运行的 Elasticsearch 集群信息&#xff0c;可以通过以下几种方法&#xff1a; 1. 使用 _cluster/health API _cluster/health API 返回集群的健康状态、节点数量、分片状态等信息。可以用 curl 命令直接访问&#xff1a; curl -X GET "http://localhost…

算法练习4——一个六位数

这道题特别妙 大家仔细做一做 我这里采用的是动态规划来解这道题 结合题目要求找出数与数之间的规律 抽象出状态转移方程 题目描述 有一个六位数&#xff0c;其个位数字 7 &#xff0c;现将个位数字移至首位&#xff08;十万位&#xff09;&#xff0c;而其余各位数字顺序不…

client-go 的 QPS 和 Burst 限速

1. 什么是 QPS 和 Burst &#xff1f; 在 kubernetes client-go 中&#xff0c;QPS 和 Burst 是用于控制客户端与 Kubernetes API 交互速率的两个关键参数&#xff1a; QPS (Queries Per Second) 定义&#xff1a;表示每秒允许发送的请求数量&#xff0c;即限速器的平滑速率…

B-tree 数据结构详解

1. 引言 1.1 什么是 B-tree&#xff1f; B-tree&#xff08;Balanced Tree&#xff0c;平衡树&#xff09;是一种自平衡的多路搜索树数据结构&#xff0c;其核心特性包括&#xff1a; 多路性&#xff1a; 每个节点可以包含多个关键字和子节点&#xff0c;而非仅二分。平衡性…

Python 正则表达式完全指南

# Python 正则表达式完全指南 正则表达式&#xff08;Regular Expression&#xff09;是Python中进行文本处理的强大工具。本指南将详细介绍Python中正则表达式的使用方法和实践技巧。 ## 1. 基础知识 ### 1.1 导入正则表达式模块 python import re ### 1.2 创建正则表达式 在…

Vue的scoped原理是什么

CSS常见模块化方案 BEM&#xff08;Block Element Modifier&#xff09;: BEM是一种流行的命名约定&#xff0c;它通过特定的命名规则来组织CSS类名&#xff0c;使得样式具有模块化、可重用性和可读性。BEM的命名规则是&#xff1a;block__element--modifier。 block&#xf…

【LC】3270. 求出数字答案

题目描述&#xff1a; 给你三个 正 整数 num1 &#xff0c;num2 和 num3 。 数字 num1 &#xff0c;num2 和 num3 的数字答案 key 是一个四位数&#xff0c;定义如下&#xff1a; 一开始&#xff0c;如果有数字 少于 四位数&#xff0c;给它补 前导 0 。答案 key 的第 i 个数…

太原理工大学软件设计与体系结构 --javaEE

这个是简答题的内容 选择题的一些老师会给你们题库&#xff0c;一些注意的点我会做出文档在这个网址 项目目录预览 - TYUT复习资料:复习资料 - GitCode 希望大家可以给我一些打赏 什么是Spring的IOC和DI IOC 是一种设计思想&#xff0c;它将对象的创建和对象之间的依赖关系…

深度学习知识点:LSTM

文章目录 1.应用现状2.发展历史3.基本结构4.LSTM和RNN的差异 1.应用现状 长短期记忆神经网络&#xff08;LSTM&#xff09;是一种特殊的循环神经网络(RNN)。原始的RNN在训练中&#xff0c;随着训练时间的加长以及网络层数的增多&#xff0c;很容易出现梯度爆炸或者梯度消失的问…

mmdet

一&#xff0c;configs/_base_ 1.default_runtime.py 2.schedule_1x.py 二&#xff0c;mmdet 1.datasets/coco.py/CocoDataset METAINFO {classes:(milk, red, spring, fanta, sprite, pepsi, king, ice, cola, scream ),# palette is a list of color tuples, which is us…

ElasticSearch 认识和安装ES

文章目录 一、为什么学ElasticSearch?1.ElasticSearch 简介2.ElasticSearch 与传统数据库的对比3.ElasticSearch 应用场景4.ElasticSearch 技术特点5.ElasticSearch 市场表现6.ElasticSearch 的发展 二、认识和安装ES1.认识 Elasticsearch&#xff08;简称 ES&#xff09;2.El…

node.js中实现token的生成与验证

Token&#xff08;令牌&#xff09;是一种用于在客户端和服务器之间安全传输信息的加密字符串。在Web开发中&#xff0c;Token常用于身份验证和授权&#xff0c;确保用户能够安全地访问受保护的资源。 作用与意义 身份验证&#xff1a;Token可以用来验证用户的身份&#xff0…

第34天:安全开发-JavaEE应用反射机制攻击链类对象成员变量方法构造方法

时间轴&#xff1a; Java反射相关类图解&#xff1a; 反射&#xff1a; 1、什么是 Java 反射 参考&#xff1a; https://xz.aliyun.com/t/9117 Java 提供了一套反射 API &#xff0c;该 API 由 Class 类与 java.lang.reflect 类库组成。 该类库包含了 Field 、 Me…

Django后端相应类设计

通用的ApiResponse类&#xff1a;用于生成统一的 API 响应格式。每个响应都包含以下字段&#xff08;每个接口最终的返回数据格式&#xff09;&#xff1a; status_code&#xff1a;HTTP 状态码&#xff08;如 200、400、500 等&#xff09;message&#xff1a;响应的描述信息…

汽车基础软件AutoSAR自学攻略(三)-AutoSAR CP分层架构(2)

汽车基础软件AutoSAR自学攻略(三)-AutoSAR CP分层架构(2) 下面我们继续来介绍AutoSAR CP分层架构&#xff0c;下面的文字和图来自AutoSAR官网目前最新的标准R24-11的分层架构手册。该手册详细讲解了AutoSAR分层架构的设计&#xff0c;下面让我们来一起学习一下。 Introductio…

css面试常考布局(圣杯布局、双飞翼布局、三栏布局、两栏布局、三角形)

两栏布局 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> </head> &…

模糊查询在sqlserver、dm8、mysql的编写示例

模糊查询要求&#xff1a;字段值以 25D 开头&#xff0c;并以 4 位数字结尾 sqlserver&#xff1a; select * from table_name where column_name like 25D[0-9][0-9][0-9][0-9] 说明&#xff1a; 25D&#xff1a;表示字符串以 25D 开头。 [0-9][0-9][0-9][0-9]&#xf…