c++怎样申请一个已知字节的空间,然后按位操作把字节的每位都存储满,然后再存入一个二进制文件中

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++怎样申请一个已知字节的空间,然后按位操作把字节的每位都存储满,然后再存入一个二进制文件中相关的知识,希望对你有一定的参考价值。

ps:我在做哈弗曼编码译码器,在压缩这里卡住了,求高手指教。
(分不是问题,只要解决了我有多少分都给!!!)

申请固定的一段字节空间,使用BYTE这个类型,
比如new BYTE[10],申请了10个。
然后将内容按位与,左移,
左移的时候是不是就空出了空间?!再进行与操作,再左移。直到你不想塞东西了。

然后存入文件的时候,就以二进制写进去,把你申请的BYTE类型写进去。
还有一点值得提一下,按位与的时候,是可以用BYTE与INT这样操作的,也就是说不同类型之间的操作,你要把握好,不要造成数据丢失。毕竟他们的类型不一样,长度也不一样,所以规定好你自己的类型。
参考技术A #include <iostream>
#include <fstream>
using namespace std;
1,申请N字节空间。 char *data = new char[N];
2,位操作。同C语言
3,保存为二进制文件
ofstream out("file.dat",ios::out | ios::binary);
out.write(data,N);
out.close();
4,清理. delete data;追问

那个就是位操作那里很迷茫 能具体点吗?

追答

每个char是一个字节,如5的二进制为0b 00000101。怎么把最高位变成1呢?
例如char c = 5; c = c | 128 .因为128是0b 10000000。这样c=0b10000101。
把其他位变成1。如左边第三位 。char d=128; d = d>>3; >>是位的右移操作。然后c=c|d;。
1变成0就是&。道理和0变成1很相似。

追问

我想存入的全是1,0,1,0的数字,能直接存吗,还是也是要这样的操作,要转换类型吗,这与位段的操作有关吗,这段非常迷茫啊,谢谢了

追答

我明白了。你是打算每一位用一个字节保存,然后写入这些位。是不是?
如果是,可以这样存。
读取
ifstream in("file.dat",ios::in | ios::binary);
in.read(data,N);

追问

就是通过位操作把每一字节的八个位都填满,填的内容是1和0的数字,不知道怎么填进去,要不要转换类型,然后把字节们都填满了后把这段空间的内容都存入二进制文件,

追答

很简单。比如char c;c=5;那么c的八个位就是 00000101。

追问

那是不是得把那些0101010100什么的先转换成十进制的数字再存入呢,这样做貌似更麻烦了,能不能一位一位的存入呢,

追答

一位一位的存,一位一位的读,岂不是相当麻烦?何必这样呢?
按字节存,按字节读。要获取某位,直接 位与 或者 位或 操作。这样不是更好。

追问

关键是我做的这个哈弗曼编码译码器,先把一段字母统计频率,建树,编码,得把那些字母换成已编的码,存入文件,但是直接那样存的话txt的所占空间就更大了,是放大了不是压缩了,所以得用位操作,把编码了的内容按位一位一位的存入,再存入一个二进制文件,这样占的空间就比较小一点了,关键最后得比较存字母的文件和编了码后的文件的大小,我不知道还有什么别的办法了,只知道能这样,但是具体的不知道怎么操作啊,也没找到例题

参考技术B 主要靠几个宏实现位操作,位是从0开始算的,即一个字节包括位0~7
#define SETBIT(num,bit) ((num) | (0x1<< (bit) ) )
#define CLRBIT(num,bit) ((num) & ~(0x1<< (bit) ) )
#define READBIT(num,bit) ((num) & (0x1<< (bit) ) )
int main()

int i,bit=0,count=100;
char *datas=new char[(count+7)/8],*p;
p=datas;
*p=0;
for (i=0;i<count;i++)

*p=SETBIT(*p,bit); //或者*p=CLRBIT(*p,bit);
if (bit>=7)

bit=0;
p++;
*p=0;

else
bit++;

return 0;
追问

额 不好意思 能解释一下吗 看不懂啊

追答

| 是二进制的或,& 是二进制的与, ~是二进制的取反,>是二进制左移,右移,0x1>1是十六进制的5,即二进制的101右移一位,变成二进制的10

追问

这个宏定义是什么意思呢,还有数据是从哪里传入的呢,不好意思啊,我是菜鸟一个,还是不太明白这段代码呢,谢谢你了

追答

你调试一下这段代码,就是按F10,然后看datas和p里面值的变化,把值复制到windows的计算器,调成科学型的,然后看对应的二进制值,可能你会明白

本回答被提问者采纳

C++成员函数的存储方式

成员函数的存储方式

       学习C语言的变量定义时,我们就知道,定义一个变量,就需要在内存中申请空间,存放变量的数据。例如:

double a;

       此时,定义一个double类型的变量。double类型占据8个字节的内存空间,那么,在内存中,就划分出8个字节的空间,存放变量a的数据。

       所以,用类去定义对象时,系统会为每一个对象分配存储空间。如果类包括了数据和函数,要分别为数据和函数的代码分配存储空间。按理说,如果用同一个类定义了10个对象,那么,就需要分别为10个对象的数据和函数代码分配存储单元。

       进一步分析,可以看到:一般情况下,不同对象的数据存储单元中存放的数据值是不相同的,而不同对象的函数的代码是相同的,无论调用哪一个对象的函数的代码,其实调用的都是同样内容的代码。既然这样,在内存中开辟10段空间来分别存放10个相同内容的函数代码段,显然是浪费空间资源,是没有必要的。

那么,C++语言的发明者自然会想到:能否只用一段空间来存放这个共同的函数代码段,在调用各对象的函数时,都去调用这个公用的函数代码,如下图所示:

       显然,这样做会大大节约存储空间。C++编译系统正是这样做的,因此,每个对象所占用的存储空间只是该对象的数据部分所占用的存储空间,而不包括函数代码所占用的存储空间,如果声明了一个类:

       程序运行结果如下:

       可以看到,输出变量stud的容量是32个字节。这就证明了一个对象所占用的空间大小只取决于该对象中成员变量所占的空间,而与成员函数无关。所以,student类定义了student()、print()函数,并不占据stud对象的存储空间。

函数代码是存储在对象空间之外的。如果对同一个student类定义了10个对象,这些对象的成员函数对应的是同一个函数代码段,而不是10个不同的函数代码段。需要注意的是:虽然调用不同对象的成员函数时都是执行同一段函数代码,但是,执行结果一般是不相同的。程序测试例子如下:

    程序运行结果如下:

 

       可以看到,使用student类定义了stud1, stud2对象。可以看到,stud1, stud2对象分别调用同一个print()函数,但是,输出的信息是不一样的。其中,stud1.print()输出的是stud1对象的信息,stud2.print()输出的是stud2对象的信息。

所以,对象stud1的成员函数访问的是本对象stud1中的成员。那么,就发生了一个问题:不同的对象使用的是同一个函数代码段,它怎么能够分别对不同对象中的数据进行操作呢?

原来C++为此专门设立了一个名为this的指针,用来指向不同的对象。当调用对象stud1的成员函数时,this指针就指向stud1,成员函数访问的是stud1的成员。当调用对象stud2的成员函数时,this指针就指向stud2,此时,成员函数访问的就是stud2的成员,关于this指针,在后续章节会做更详细讨论。

注意:this指针是C++的灵魂,使用C语言来进行面向对象编程的时候,就是模拟了C++的this指针对象,才让C语言的struct结构体有了灵魂。在通过函数指针调用自己的成员函数时,通过this对象可以操作自己的数据和函数。实现对象化的编程,就是面向对象编程的基础。

韦凯峰 Linux C/C++ 程序设计教程,Linux 系统编程,Openwrt 系统开发,微信:13926572996,QQ:1523520001,博客:www.mylinux.vip

以上是关于c++怎样申请一个已知字节的空间,然后按位操作把字节的每位都存储满,然后再存入一个二进制文件中的主要内容,如果未能解决你的问题,请参考以下文章

已知线性表最多可能有20个元素,存储每个元素需要8字节,存储每个指针需要4字节。当元素个数为( )时使用单链表比使用数组存储此线性表更加节约空间。

应用按位与操作,分离字节

c++堆与栈的简单认识

单链表(不带头结点)按位序插入

C++ new申请内存,提示 内存不足

C++成员函数的存储方式