c++ 将void* 偏移8个字节
时间: 2023-11-26 12:06:41 浏览: 29
可以使用指针类型转换的方式偏移 `void*` 指针。具体实现如下:
```cpp
void* ptr = ...; // 原始 void* 指针
char* charPtr = static_cast<char*>(ptr); // 转换成 char* 指针
charPtr += 8; // 偏移 8 个字节
void* offsetPtr = static_cast<void*>(charPtr); // 再转回 void* 指针
```
在这个例子中,我们将 `void*` 指针转换为 `char*` 指针,然后通过加上 8 的方式偏移指针,最后再转回 `void*` 指针。由于 `char` 的大小恰好是 1 字节,因此我们可以直接以字节为单位进行偏移。需要注意的是,这种偏移方式需要保证偏移后的内存区域是合法的,否则会出现未定义行为。
相关问题
用C++语言写一个将内存的16位像素数据保存为bmp文件.
以下是一个可能的实现,仅供参考:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned int DWORD;
// BMP文件头结构体
#pragma pack(push, 1)
typedef struct {
WORD bfType; // 文件类型,必须为0x4D42
DWORD bfSize; // 文件大小
WORD bfReserved1; // 保留字段
WORD bfReserved2; // 保留字段
DWORD bfOffBits; // bmp数据的偏移量
} BMPFILEHEADER;
#pragma pack(pop)
// BMP信息头结构体
#pragma pack(push, 1)
typedef struct {
DWORD biSize; // 信息头大小,必须为40
DWORD biWidth; // 图像宽度,单位像素
DWORD biHeight; // 图像高度,单位像素
WORD biPlanes; // 颜色平面数,必须为1
WORD biBitCount; // 每个像素的位数
DWORD biCompression; // 压缩类型
DWORD biSizeImage; // bmp数据大小
DWORD biXPelsPerMeter; // 水平分辨率,像素/米
DWORD biYPelsPerMeter; // 垂直分辨率,像素/米
DWORD biClrUsed; // 使用的颜色表中的颜色数
DWORD biClrImportant; // 重要的颜色数
} BMPINFOHEADER;
#pragma pack(pop)
// 将内存中的像素数据保存为bmp文件
void save_bmp(const char* filename, BYTE* pixels, int width, int height) {
// 计算bmp文件大小和bmp数据大小
int row_size = (width * 2 + 3) & ~3; // 每行的字节数必须是4的倍数
int data_size = row_size * height;
int file_size = sizeof(BMPFILEHEADER) + sizeof(BMPINFOHEADER) + data_size;
// 构造bmp文件头
BMPFILEHEADER file_header = {0};
file_header.bfType = 0x4D42;
file_header.bfSize = file_size;
file_header.bfOffBits = sizeof(BMPFILEHEADER) + sizeof(BMPINFOHEADER);
// 构造bmp信息头
BMPINFOHEADER info_header = {0};
info_header.biSize = sizeof(BMPINFOHEADER);
info_header.biWidth = width;
info_header.biHeight = height;
info_header.biPlanes = 1;
info_header.biBitCount = 16;
info_header.biCompression = 0;
info_header.biSizeImage = data_size;
info_header.biXPelsPerMeter = 0;
info_header.biYPelsPerMeter = 0;
info_header.biClrUsed = 0;
info_header.biClrImportant = 0;
// 打开文件并写入bmp文件头和bmp信息头
FILE* fp = fopen(filename, "wb");
if (fp == NULL) {
printf("Failed to open file %s\n", filename);
return;
}
fwrite(&file_header, sizeof(BMPFILEHEADER), 1, fp);
fwrite(&info_header, sizeof(BMPINFOHEADER), 1, fp);
// 写入像素数据
BYTE* row_buf = (BYTE*)malloc(row_size);
memset(row_buf, 0, row_size); // 每行填充0补齐
for (int y = height - 1; y >= 0; y--) {
// 将每一行的像素数据转换为16位RGB565格式并写入文件
BYTE* src = pixels + y * width * 2;
WORD* dst = (WORD*)row_buf;
for (int x = 0; x < width; x++) {
BYTE r = src[0];
BYTE g = src[1];
BYTE b = src[2];
*dst++ = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
src += 2;
}
fwrite(row_buf, row_size, 1, fp);
}
free(row_buf);
// 关闭文件
fclose(fp);
}
int main() {
// 示例代码,假设内存中有一个16位RGB565格式的像素数组
int width = 320;
int height = 240;
BYTE* pixels = (BYTE*)malloc(width * height * 2);
memset(pixels, 0, width * height * 2);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int i = y * width + x;
pixels[i * 2] = (x * 255) / width;
pixels[i * 2 + 1] = (y * 255) / height;
}
}
save_bmp("test.bmp", pixels, width, height);
free(pixels);
return 0;
}
fnv1a64 哈希算法 用c++实现
以下是使用C++实现FNV1a64哈希算法的示例代码:
```cpp
#include <iostream>
#include <cstring>
using namespace std;
const uint64_t FNV_OFFSET_BASIS = 14695981039346656037ull;
const uint64_t FNV_PRIME = 1099511628211ull;
uint64_t fnv1a64(const void* data, size_t size)
{
uint64_t hash = FNV_OFFSET_BASIS;
const uint8_t* ptr = static_cast<const uint8_t*>(data);
for (size_t i = 0; i < size; ++i)
{
hash ^= static_cast<uint64_t>(ptr[i]);
hash *= FNV_PRIME;
}
return hash;
}
int main()
{
const char* str = "Hello, world!";
uint64_t hash = fnv1a64(str, strlen(str));
cout << "Hash of \"" << str << "\" is: " << hash << endl;
return 0;
}
```
在这个示例中,`fnv1a64`函数接收一个指向数据的指针和数据的大小,并返回计算出的哈希值。首先,将哈希值初始化为偏移基础值`FNV_OFFSET_BASIS`。然后,对于数据中的每个字节,使用异或运算符将其与哈希值进行异或运算,然后将哈希值乘以FNV素数`FNV_PRIME`。最后,返回计算出的哈希值。
在`main`函数中,我们将一个字符串传递给`fnv1a64`函数,并输出计算出的哈希值。
请注意,此代码中使用了C++11标准中的`uint64_t`和`size_t`类型,因此您需要编译器支持C++11才能编译此代码。