工作知识点总结1

1.QByteArray类
提供一个字节数组,QByteArray可用于存储原始字节(包括“\ 0” )和传统的8位 “\ 0” 端接字符串 . 使用QByteArray比使用const char *更方便.

除了QByteArray之外,Qt还提供了QString类来存储字符串数据。对于大多数用途,QString是您要使用的类。它存储16位Unicode字符,使您可以轻松地在应用程序中存储非ASCII /非拉丁字符。此外,QSt API在Qt API中始终使用。
QByteArray适合的两个主要情况是当您需要存储原始二进制数据,并且当内存保护至关重要时(例如,使用嵌入式Linux的Qt)

初始化QByteArray的一种方法是const char *将其传递给其构造函数。例如,以下代码创建一个大小为5的字节数组,
其中包含数据“Hello”:

    QByteArray ba("Hello");

虽然size()为5,但是字节数组在最后还会保留一个额外的’\ 0’字符,
以便如果使用一个函数来请求指向底层数据的指针(例如调用data()),那么指出的数据保证被’\ 0’终止。

若是想把QString转为QByteArray:
eg:

    QString str_value = m_broadCstvolEdit->text();
    QByteArray ba = str_value.toLocal8Bit();

char *QByteArray::data():

char *data = ba.data(); 返回指向存储在字节数组中的数据的指针。

2.C++ 里面的“\\.\” 意思

由于”\”是C/C+中转义符, “\\.\”就相当于\.\

在Windows中 \.\ 前缀用于标识设备,其中的”.”表示本地计算机。

比如\.\PhysicalDrive0表示本机的物理驱动器0(一般是主硬盘),
\.\COM1表示本机的1号串行口
\computer01\PhysicalDrive1表示网络中计算机computer01的物理驱动器1,等等。

你可以用CreateFile函数打开\.\PhysicalDrive0
然后用ReadFile, WriteFile来直接读写本机硬盘扇区
用DeviceIoControl来获取硬盘的信息(扇区数,磁头数,柱面数)等。

亦可用CreateFile打开卷,如\.\C:即是C盘。

3.C++ 什么是句柄?为什么会有句柄?HANDLE
从广义上,能够从一个数值拎起一大堆数据的东西都可以叫做句柄。句柄的英文是”Handle”,本义就是”柄”,只是在计算机科学中,被特别地翻译成”句柄”,其实还是个”柄”。从一个小东西拎起一大堆东西,这难道不像是个”柄”吗?

然后,指针其实也是一种”句柄”,只是由于指针同时拥有更特殊的含义——实实在在地对应内存里地一个地址——所以,通常不把指针说成是”句柄”。但指针也有着能从一个32位的值引用到一大堆数据的作用,这不是句柄又是什么?

Windows系统中有许多内核对象(这里的对象不完全等价于”面向对象程序设计”一词中的”对象”,虽然实质上还真差不多),比如打开的文件,创建的线程,程序的窗口,等等。这些重要的对象肯定不是4个字节或者8个字节足以完全描述的,他们拥有大量的属性。为了保存这样一个”对象”的状态,往往需要上百甚至上千字节的内存空间,那么怎么在程序间或程序内部的子过程(函数)之间传递这些数据呢?拖着这成百上千的字节拷贝来拷贝去吗?显然会浪费效率。那么怎么办?当然传递这些对象的首地址是一个办法,但这至少有两个缺点:

暴露了内核对象本身,使得程序(而不是操作系统内核)也可以任意地修改对象地内部状态(首地址都知道了,还有什么不能改的?),这显然是操作系统内核所不允许的;
操作系统有定期整理内存的责任,如果一些内存整理过一次后,对象被搬走了怎么办?
所以,Windows操作系统就采用进一步的间接:在进程的地址空间中设一张表,表里头专门保存一些编号和由这个编号对应一个地址,而由那个地址去引用实际的对象,这个编号跟那个地址在数值上没有任何规律性的联系,纯粹是个映射而已。

在Windows系统中,这个编号就叫做”句柄”。

Handle在Windows中的含义很广泛,以下关于谈到的Handle除非特别说明,将仅限于进程、线程的上下文中。

1、先来谈谈Handle

Handle本身是一个32位的无符号整数,它用来代表一个内核对象。它并不指向实际的内核对象,用户模式下的程序永远不可能获得一个内核对象的实际地址(一般情况下)。那么Handle的意义何在?它实际上是作为一个索引在一个表中查找对应的内核对象的实际地址。那么这个表在哪里呢?每个进程都有这样的一个表,叫句柄表。该表的第一项就是进程自己的句柄,这也是为什么你调用GetCurrentProcess()总是返回0x7FFFFFFF原因。

简单地说,Handle就是一种用来”间接”代表一个内核对象的整数值。你可以在程序中使用handle来代表你想要操作的内核对象。这里的内核对象包括:事件(Event)、线程、进程、Mutex等等。我们最常见的就是文件句柄(file handle)。

另外要注意的是,Handle仅在其所属的进程中才有意义。将一个进程拥有的handle传给另一个进程没有任何意义,如果非要这么做,则需要使用DuplicateHandle(),在多个进程间传递Handle是另外一个话题了,与这里要讨论的无关。

2、进程ID

首先,进程ID是一个32位无符号整数,每个进程都有这样的一个ID,并且该ID在系统范围内是唯一的。系统使用该ID来唯一确定一个进程。

深入些说,系统可能使用进程ID来计算代表该进程的内核对象的基地址(及EPROCESS结构的基地址),具体的计算公式你可以去问微软的OS开发人员。

3、HINSTANCE

HINSTANCE也是一个32无符号整数,它表示程序加载到内存中的基地址。

4.extern “C”和__declspec(dllexport)以及__declspec(dllimport)

extern “C“的主要作用就是为了能够正确实现C++代码调用其他C语言代码。加上extern “C”后,会指示编译器这部分代码按C语言的进行编译,而不是C++的。由于C++支持函数重载,因此编译器编译函数的过程中会将函数的参数类型也加到编译后的代码中,而不仅仅是函数名;而C语言并不支持函数重载,因此编译C语言代码的函数时不会带上函数的参数类型,一般之包括函数名。

这个功能十分有用处,因为在C++出现以前,很多代码都是C语言写的,而且很底层的库也是C语言写的,为了更好的支持原来的C代码和已经写好的C语言库,需要在C++中尽可能的支持C,而extern “C”就是其中的一个策略。

这个功能主要用在下面的情况:

1、C++代码调用C语言代码

2、在C++的头文件中使用

3、在多个人协同开发时,可能有的人比较擅长C语言,而有的人擅长C++,这样的情况下也会有用到

__declspec(dllexport) __declspec(dllimport)一般也是使用宏的形式:

#ifdef ONEDLL_EXPORTS
#define ONEDLL_API __declspec(dllexport)
#else
#define ONEDLL_API __declspec(dllimport)
#endif

这样在DLL代码本身就是__declspec(dllexport) ,在使用DLL的程序中就变成了__declspec(dllimport),这两标志分别用来指明当前的函数将被导出,和当前函数是被导入的。

5.串口之ReadFile、WriteFile函数详解

BOOL ReadFile(
  HANDLE hFile, //文件的句柄
  LPVOID lpBuffer, //用于保存读入数据的一个缓冲区
  DWORD nNumberOfBytesToRead, //要读入的字符数
  LPDWORD lpNumberOfBytesRead, //指向实际读取字节数的指针
  LPOVERLAPPED lpOverlapped //如文件打开时指定了FILE_FLAG_OVERLAPPED,那么必须,用这个参数引用一个特殊的结构。该结构定义了一次异步读取操作。否则,应将这个参数设为NULL
  );
功能说明
  从文件指针指向的位置开始将数据读出到一个文件中, 且支持同步和异步操作,
  如果文件打开方式没有指明FILE_FLAG_OVERLAPPED的话,当程序调用成功时,它将实际读出文件的字节数保存到lpNumberOfBytesRead指明的地址空间中。
  如果文件要交互使用的话,当函数调用完毕时要记得调整文件指针。
  从文件中读出数据。与lread函数相比,这个函数要明显灵活的多。该函数能够操作通信设备、管道、套接字以及邮槽。
参数说明
  HANDLE hFile, 需要写入数据的文件指针,这个指针指向的文件必须是GENERIC_READaccess 访问属性的文件。
  LPOVERLAPPED lpOverlapped OVERLAPPED结构体指针,如果文件是以FILE_FLAG_OVERLAPPED方式打开的话,那么这个指针就不能为NULL。
返回值
  调用成功,返回非0
  调用不成功,返回为0
  会设置GetLastError。如启动的是一次异步读操作,则函数会返回零值,并将ERROR_IO_PENDING设置成GetLastError的结果。如结果不是零值,但读入的字节数小于nNumberOfBytesToRead参数指定的值,表明早已抵达了文件的结尾。


WriteFile
The WriteFile function writes data to a file and is designed for both synchronous and asynchronous operation. The function starts writing data to the file at the position indicated by the file pointer. After the write operation has been completed, the file pointer is adjusted by the number of bytes actually written, except when the file is opened with FILE_FLAG_OVERLAPPED. If the file handle was created for overlapped input and output (I/O), the application must adjust the position of the file pointer after the write operation is finished.

This function is designed for both synchronous and asynchronous operation. TheWriteFileEx function is designed solely for asynchronous operation. It lets an application perform other processing during a file write operation.

BOOL WriteFile(
HANDLE hFile, // handle to file
LPCVOID lpBuffer, // data buffer
DWORD nNumberOfBytesToWrite, // number of bytes to write
LPDWORD lpNumberOfBytesWritten, // number of bytes written
LPOVERLAPPED lpOverlapped // overlapped buffer
);
Parameters
hFile
[in] Handle to the file to be written to. The file handle must have been created with GENERIC_WRITE access to the file.
Windows NT/2000/XP: For asynchronous write operations, hFile can be any handle opened with the FILE_FLAG_OVERLAPPED flag by theCreateFile function, or a socket handle returned by thesocket or accept function.

Windows 95/98/Me: For asynchronous write operations, hFile can be a communications resource opened with the FILE_FLAG_OVERLAPPED flag byCreateFile, or a socket handle returned by socket oraccept. You cannot perform asynchronous write operations on mailslots, named pipes, or disk files.

lpBuffer
[in] Pointer to the buffer containing the data to be written to the file.
nNumberOfBytesToWrite
[in] Specifies the number of bytes to write to the file.
A value of zero specifies a null write operation. The behavior of a null write operation depends on the underlying file system. To truncate or extend a file, use theSetEndOfFile function.

Named pipe write operations across a network are limited to 65,535 bytes.

lpNumberOfBytesWritten
[out] Pointer to the variable that receives the number of bytes written. WriteFile sets this value to zero before doing any work or error checking.
Windows NT/2000/XP: If lpOverlapped is NULL, lpNumberOfBytesWritten cannot be NULL. IflpOverlapped is not NULL, lpNumberOfBytesWritten can be NULL. If this is an overlapped write operation, you can get the number of bytes written by callingGetOverlappedResult. If hFile is associated with an I/O completion port, you can get the number of bytes written by callingGetQueuedCompletionStatus.

If I/O completion ports are used and you are using a callback routine to free the memory allocated to theOVERLAPPED structure pointed to by the lpOverlapped parameter, specify NULL as the value of this parameter to avoid a memory corruption problem during the deallocation. This memory corruption problem will cause an invalid number of bytes to be returned in this parameter.

Windows 95/98/Me: This parameter cannot be NULL.

lpOverlapped
[in] Pointer to an OVERLAPPED structure. This structure is required ifhFile was opened with FILE_FLAG_OVERLAPPED.

6.C++中如何将int型变量转换成char类型

int b=65;
char c;
c=b;
cout<<c<<endl;

因为 char 类型本身就是一个特殊的整型,字符‘A’对应的ascii码是65,所以可以直接把char转化为int型。

7.c++中c_str用法

const char *c_str();
c_str()函数返回一个指向正规C字符串的指针, 内容与本string串相同.
这是为了与c语言兼容,在c语言中没有string类型,故必须通过string类对象的成员函数c_str()把string 对象转换成c中的字符串样式。
注意:一定要使用strcpy()函数 等来操作方法c_str()返回的指针
比如:最好不要这样:
char* c;
string s=”1234”;
c = s.c_str(); //c最后指向的内容是垃圾,因为s对象被析构,其内容被处理
应该这样用:
char c[20];
string s=”1234”;
strcpy(c,s.c_str());
这样才不会出错,c_str()返回的是一个临时指针,不能对其进行操作
再举个例子
c_str() 以 char* 形式传回 string 内含字符串
如果一个函数要求char*参数,可以使用c_str()方法:
string s = “Hello World!”;
printf(“%s”, s.c_str()); //输出 “Hello World!”

8.C语言中atoi()和itoa()用法详解

atoi():将字符串转换为整型值。
itoa():将整型值转换为字符串。

9.C语言中有string吗

一直以来对这个问题都不是很清楚:只是知道C语言里有<string.h>这个头文件,所以就想当然的认为C语言里有string这个 类型,可以通过下面这种形式来声明string的变量 string aString; 后来编程时发现通不过编译,又查资料才知道原来C语言里压根就没有string这个类型,所以字符串都是通过char数组来存储的, 而<string.h>这个头文件里声明的函数原型也全是针对char数组的种种操作。直到C++中才出现了string这个类(注意是类, 不是类型)。这是网上我找到的比较满意的答复:

” C语言中有string类型变量吗”
这里的 string 有 二 义性。

(1) 如果 string 是普通词汇,“C语言中有字符类型变量吗”, 答,有。 字符类型 用 char 声明。
char str[]=”This is a string”;

(2) 如果 string 是专用词汇,“C语言中有string类型变量吗”,答,没有。string 是 类,是 class, 不是 类型,不是 type.
类 的 声明 用 构造函数初始化,或 new 声明。
类 – C++, 不是 C

10.把const char*赋值给unsigned char

    string str_tmp = "0120";
    unsigned char tmp[64];
    memset(tmp, 0, sizeof(tmp));
    // 取str_tmp中前两个字符赋值给tmp[0].这里atoi是把字符串转为整形,
    // 整形是可以赋值给char型的
    tmp[0] = atoi(str_tmp.substr(0,2).c_str());

11.C++中substr的用法

substr表示字符串的截取,substr有2种用法:
假设:string s = “0123456789”;

string sub1 = s.substr(5); //只有一个数字5表示从下标为5开始一直到结尾:sub1 = “56789”

string sub2 = s.substr(5, 3); //从下标为5开始截取长度为3位:sub2 = “567”

12.字符串数组和字符串的区别

1).明确一下:
你说的Char是c++的内置类型char么
你说的String是标准库中定义的类么
如果是的话,它两的区别有:
char数组仅仅是存储字符串用的,c库中有一系列操作字符串的函数
String是类,它包含一个可变长度的char数组,封装了常用的字符串操作函数
它们之间可以转化。

2).


#include <stdio.h>
#include <string.h>

int main()
{
    char c1[] ="helloworld";
    char *c2 = "helloworld";

    printf("sizeof(s1) :  %d %d\n", sizeof(c1), sizeof(c2));
    printf("strlen(s2) :  %d %d\n", strlen(c1), strlen(c2));

    return 0;
}

这段程序运行的结果是:
sizeof(s1): 11 4
strlen(s2): 10 10

“helloword”一共10个字符,所以strlen的值都为10;

差别体现在sizeof的值。用字符串数组定义的”helloword”占11个字节,是因为”helloword”加上结尾的”\0”一共十一个char型字符,每个char型字符占1个字节;

而用字符串指针变量定义时,sizeof的值仅为4个字节,这是因为s2是一个指针,在32位系统中,地址占4个字节。

发布了21 篇原创文章 · 获赞 21 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/SeekN/article/details/81566530