sizeof().cpp - 一目了然

本文通过示例代码详细介绍了C++中sizeof运算符的使用方法,包括基本数据类型、结构体、类及STL容器等不同情况下的表现。特别关注了内存对齐和动态分配对结果的影响。

//sizeof().cpp
//关于sizeof对基本数据类型、结构体、类、STL容器的用法均以C++代码和注释给出

//在VC 6.0上编译通过,可复制文章直接运行,希望有帮助^_^

#include <iostream>
#include <vector>
#include <string>
using namespace std;

 

struct S1 { //sizeof(S1)==8
 short a; //2
 short b; //2
 int c; //4
};

 

struct S2 { //sizeof(S2)==12
 short a; //2+2( 字节对齐为2(方便计算机进行存取操作)
               //从而凑足结构体中的最宽元素(此处为int——4个字节),参见下例S3 )
 int b; //4
 short c; //2+2
};


struct S3 { //sizeof(S2)==24
 short a; //2
 int b; //4+2
 double c; //8
 short d; //2+6
};

 

class C { //sizeof(C)==2
 short a;
};

 

int main()
{
 cout<<sizeof(S1)<<endl;
 cout<<sizeof(S2)<<endl;
 cout<<sizeof(S3)<<endl;
 cout<<endl;
 
 S1* s;
 cout<<sizeof(s)<<endl; //指针变量总是返回4
 cout<<endl;

 

 double* a=new double[8]; //堆上分配内存
 cout<<sizeof(a)<<endl; //sizeof(ptr)==4
 cout<<sizeof(*a)<<endl; //sizeof(double)==8
 cout<<endl;

 

 char* ss;
 cout<<sizeof(ss)<<endl; //sizeof(ptr)==4
 cout<<sizeof(*ss)<<endl; //sizeof(char)==1
 cout<<endl;


 //我们可以得出结论,内存分配对结构体(或类)和普通变量(如int)是不公平对待的
 //当然运气好的时候结果会一致,比如:
 C c;
 short cc;
 cout<<sizeof(c)<<" "<<sizeof(cc)<<endl; //sizeof(C)==sizeof(short)==2
 cout<<endl;
 
 //sizeof()在编译时起作用(栈内),而不是运行时
 //而vector的元素是动态分配的(堆上分配内存),因此sizeof(vector<int>)总是返回16
 //16便是vector类的非静态数据成员所占用的空间,如下:
 //_A allocator; iterator _First,_Last,_End;
 vector<int> v(999);
 cout<<sizeof(v)<<" "<<sizeof(vector<int>)<<endl;
 cout<<sizeof(string)<<endl; //同样地,sizeof(string)==16

 cout<<endl;


 return 0;

}

 

if (property == toInt(VehicleProperty::HUD_TRANSFER_WARP_MATRIX_DATA)) { // prop = getPropValue(toInt(VehicleProperty::HUD_WARPING_MATRIX), data, count * 8, VehiclePropertyStatus::AVAILABLE); uint8_t *p = (uint8_t*)data; for (int i = 0; i < count; i++) { reverse(p, p + 8); p = p + 8; } onPropChanged(toInt(VehicleProperty::HUD_WARPING_MATRIX), data, count * sizeof(int64_t)); return; } if (context.getReportWay() == REPORT_DIFFERENCE && !context.getForceReportFlag()) { ret = context.setData(data, count); if (ret != DATA_SET_OK) { return; } } else { ret = context.setData(data, count); } if (toInt(VehicleProperty::MCU_IG_DATA) == property && ret == DATA_SET_OK) { for (auto manager : mManagerVec) { manager->onVehiclePowerStatus(*((int32_t*)data)); } } if (toInt(VehicleProperty::MCU_SYNC_INFO) == property && ret == DATA_SET_OK) { for (auto manager : mManagerVec) { manager->onCfcInfoChanged(data, count); } } // only dispatch the property has subscribe. if (context.getSubscribe() && ret != DATA_SET_NO_PERMISSION) { VehiclePropValuePtr prop = getPropValue(property, data, count, VehiclePropertyStatus::AVAILABLE); t1 = systemTime(CLOCK_MONOTONIC); //we report to up layer DATA_SET_OK or DATA_SET_EQUAL, but we logProp only DATA_SET_OK. if (!useSharedMemory) { doHalEvent(std::move(prop)); } else { int buffer[toInt(VehicleConstant::SHARED_MEMORY_META_DATA_SIZE) / sizeof(int)]; buffer[0] = 0; buffer[1] = count; buffer[2] = crc32(0, reinterpret_cast<const uint8_t *>(data), count); VehiclePropValuePtr prop = getPropValue(property, buffer, sizeof(buffer), VehiclePropertyStatus::AVAILABLE); doHalShmEvent(std::move(prop), data, count); } t2 = systemTime(CLOCK_MONOTONIC); if (t2 - t1 > ms2ns(100)) { SLOGW("callback cost too many time! prop = %X, diff = %ld", property, t2 - t1); } } else { t2 = systemTime(CLOCK_MONOTONIC); } level = context.getLogLevel(); if (context.getForceReportFlag()) { context.setForceReportFlag(false); forceprint = true; SLOGI("force log! (%d:%d:%s)", level, ret, context.propName); } if ((level == LOGCTRL_SHOW && ret == DATA_SET_OK) || forceprint) { logProp("rp", property, data, count, context.propName, dcount, context.getSubscribe(), t1, true); } else if (level == LOGCTRL_DOWNFREQ) { dcount = context.getDropCount(); if (context.isLogExpire(t2) || forceprint) { logProp("rp", property, data, count, context.propName, dcount, context.getSubscribe(), t1, true); context.setDropCount(0); } else { context.setDropCount(dcount + 1); } }
最新发布
08-08
在 C++代码中添加注释是提升代码可读性和维护性的重要手段。合理使用注释可以帮助其他开发者快速理解代码逻辑、意图以及实现方式。以下是一些具体的注释编写方法和实践建议: - 对于变量声明,可以在行尾添加简短说明,用于解释变量的作用或使用场景。例如: ```cpp int retryCount = 0; // 记录重试次数,用于控制请求失败后的重试逻辑 bool isInitialized = false; // 标识初始化状态,用于防止重复初始化 ``` 这种方式可以使变量用途一目了然,同时保持代码简洁[^1]。 - 对于复杂逻辑或关键判断,建议在代码上方添加多行注释,详细说明逻辑结构或算法原理。例如: ```cpp /* * 根据当前系统状态和用户权限,判断是否允许执行特定操作。 * 如果权限不足或状态异常,将记录日志并返回错误码。 */ if (!checkPermission() || systemState != SystemState::NORMAL) { logError("Permission denied or system not in normal state"); return ERROR_CODE_PERMISSION_DENIED; } ``` 多行注释适合用于解释较长的逻辑段落,有助于提升代码整体可读性[^3]。 - 对于类或函数接口,推荐使用统一格式的文档注释,说明其功能、参数、返回值等信息。例如: ```cpp /** * @brief 构造函数,初始化网络连接配置 * @param host 服务器地址 * @param port 通信端口 * @param timeout 连接超时时间(单位:毫秒) */ NetworkManager(const std::string& host, int port, int timeout); ``` 这种注释风格不仅便于阅读,还能被文档生成工具(如 Doxygen)解析,自动生成 API 文档[^3]。 - 在涉及多继承、虚函数重载等复杂结构时,应在代码中添加清晰的注释以说明意图。例如: ```cpp class Derived : public Base1, public Base2 { public: // Implement Base1::onEvent to handle user input events void onEvent(EventType type) override; // Override Base2::calculate to provide custom logic int calculate(int value) const override; }; ``` 通过注释明确函数的重载目的,有助于团队协作和代码维护[^4]。 - 对于宏定义或条件编译区域,也应添加注释说明其作用和使用场景: ```cpp #ifdef ENABLE_DEBUG_LOG // 启用调试日志输出,仅在开发阶段使用 void logDebug(const std::string& message) { std::cout << "[DEBUG] " << message << std::endl; } #endif ``` 这类注释能帮助开发者快速理解编译选项的影响范围[^4]。 综上所述,注释的编写应根据代码的复杂程度和上下文环境灵活选择形式,并确保注释内容与代码逻辑一致、简洁明了。避免冗余注释和过时注释,以提升代码的可维护性和协作效率。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值