矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
查看: 2226|回复: 15

C/C++变量初始化

[复制链接]
     
发表于 2024-12-16 15:26:54 | 显示全部楼层 |阅读模式
C/C++这种比较原始的语言,没有垃圾回收,没有动态类型
没有自动初始化特性,但往往编程中偷懒或者不小心会忘记初始化
比如在嵌入式开发中从来都不初始化好像也没太大问题
所以拿本地环境两种编译器看看什么情况有问题什么情况没问题
Image 1050.jpg
Image 1051.jpg
Image 1052.jpg
Image 1053.jpg
Image 1054.jpg
     
 楼主| 发表于 2024-12-16 15:29:13 | 显示全部楼层
本帖最后由 JuncoJet 于 2024-12-16 15:41 编辑

所有的全局变量,包括static修饰的,都会自动初始化
所有的局部变量都不会自动初始化,包括成员变量
——Windows,VC++、gcc(MinGW)
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2024-12-16 15:46:44 | 显示全部楼层
微信截图_20241216154504.png
Linux下有所不同,除局部变量外都能自动初始化
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2024-12-16 15:57:36 | 显示全部楼层
本帖最后由 JuncoJet 于 2024-12-16 16:06 编辑

成员变量手动初始化,有部分代码会导致初始化无效
必须使用构造函数或者static来初始化

哦,我的VC2005不支持这语法,编译出错了,新的C++是支持的,应该是没问题的
Image 1055.jpg
Image 1056.jpg
Image 1057.jpg
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2024-12-16 15:59:45 | 显示全部楼层
代码如下,欢迎自行编译测试
  1. #include <stdio.h>
  2. #include <conio.h>
  3. int i;
  4. float f;
  5. class T{
  6. public:
  7.         static int i;
  8.         float f;
  9. };
  10. int T::i=0;
  11. int main(int argc, char *argv[]){
  12.         int li;
  13.         float lf;
  14.         static int si;
  15.         static float sf;
  16.         printf("%d %f\n",i,f);
  17.         printf("%d %f\n",li,lf);
  18.         printf("%d %f\n",si,sf);
  19.         T t;
  20.         T *tt=new T;
  21.         printf("%d %f\n",t.i,t.f);
  22.         printf("%d %f\n",tt->i,tt->f);
  23.         getch();
  24. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2024-12-16 16:07:18 | 显示全部楼层
静态变量和全局变量都能初始化成默认值。
类(struct, class)成员能自动初始化成默认值,否则是编译器的BUG。
临时变量放栈上那就没办法了,只能是个垃圾值。
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2024-12-16 16:12:25 | 显示全部楼层
本帖最后由 JuncoJet 于 2024-12-16 16:19 编辑
chipset009 发表于 2024-12-16 16:07
静态变量和全局变量都能初始化成默认值。
类(struct, class)成员能自动初始化成默认值,否则是编译器的BUG ...


Image 1058.jpg
好像Windows下都不会初始化
哦 想起来了加括号才能自动初始化,不加括号的不会
T *tt=new T(); C++博大精深
回复 支持 反对

使用道具 举报

发表于 2024-12-16 16:19:33 | 显示全部楼层
#include <cstdio>
#include <string>

struct A
{
  int a;
  float b;
};

struct B
{
  A a;
  char c;
  std::string str;
};

int main()
{
  B tb;  // const B tb; will fail to build by g++ 13.3
  printf("%d, %f, %c, %llu\n", tb.a.a, tb.a.b, tb.c, tb.str.size());
  const B* pb = new (std::nothrow) B;
  if(nullptr != pb)
  {
    printf("%d, %f, %c, %llu\n", pb->a.a, pb->a.b, pb->c, pb->str.size());
    delete pb;
  }
}

编译器偷懒了,B tb;由于放栈上,编译器(g++)对成员就当了临时变量处理的,不给初始化。如果加const会编译失败,提示没有初始化。如果放堆上,像  const B* pb = new (std::nothrow) B;这种,就把成员给初始化成默认值。
回复 支持 反对

使用道具 举报

     
发表于 2024-12-16 17:19:57 | 显示全部楼层
JuncoJet 发表于 2024-12-16 16:12
好像Windows下都不会初始化
哦 想起来了加括号才能自动初始化,不加括号的不会
T *tt=new T();  ...

T的构造函数没给,为缺省值,缺省构造函数就是按照输入参数给每个成员赋值,如果你不给括号,new的时候相当于没有给构造函数参数,所以构造函数不会赋值,如果给了括号,相当于传给构造函数参数0,于是成员都赋值为0了
回复 支持 反对

使用道具 举报

     
发表于 2024-12-16 17:24:47 | 显示全部楼层
没有自动初始化特性,但往往编程中偷懒或者不小心会忘记初始化

++++++++++++++++++++++++++++++++++++++++

学校正经教出来的学生都会习惯性初始化,然后被其它编译器的 IDE 艹,你丫的画蛇添足干嘛
未标题-1in3.png
回复 支持 反对

使用道具 举报

     
发表于 2024-12-16 18:55:50 | 显示全部楼层
我觉得这才是C/C++精髓之处,给了程序员足够的自由发挥的空间,你凭啥认为默认值就不是垃圾值?
回复 支持 反对

使用道具 举报

     
发表于 2024-12-16 19:39:55 | 显示全部楼层
关于局部变量初始化这个话题,有个视频 UP 主叫 “码农高天” 的一期视频很不错,不仅讲了要不要初始化、而且讲了很多相关联的知识,油管子和 B 站都有,值得一看。

视频的标题是 “我与微软的代码规范之争——局部变量竟然不让初始化?”
回复 支持 反对

使用道具 举报

     
发表于 2024-12-17 09:06:37 | 显示全部楼层
局部变量需不需要初始化,我觉得还得看情况,不能一刀切。假如一个函数在程序中会被频繁调用,里面申请一块很大的内存,里面是什么值都不会影响程序运行结果,但编译器固定给你先写一轮0进去,结果性能有很大影响,这种情况还希望编译器默认初始化吗?
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2024-12-17 09:31:54 | 显示全部楼层
本帖最后由 JuncoJet 于 2024-12-17 09:35 编辑
spader 发表于 2024-12-17 09:06
局部变量需不需要初始化,我觉得还得看情况,不能一刀切。假如一个函数在程序中会被频繁调用,里面申请一块 ...


局部变量依赖栈的大小,不会给到很大的内存,初始化就一次性的操作
自动初始化不会消耗很大的时间
new malloc 的情况我觉得可以另当别论,使用memset初始化标准配置
但是吧既然标准配置了,何必不自动完成初始化
new不存在初始化问题 加括号就能自动完成初始化,所以上面列举特指malloc

malloc基本上搭配写入操作 read文件 recv网络数据,所以确实不初始化也能用,只要有写入大小
回复 支持 反对

使用道具 举报

发表于 2024-12-17 12:26:45 | 显示全部楼层
spader 发表于 2024-12-17 09:06
局部变量需不需要初始化,我觉得还得看情况,不能一刀切。假如一个函数在程序中会被频繁调用,里面申请一块 ...

初始化就是构造,有构造就得有析构,很大一笔开销,却毛用没有,编译器本来就知道类型,没有必要去做无用功。
于是后来的C++标准里逐渐添加规定了一堆奇葩类型,pod, trivial, standard_layout, scalar...
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2025-4-29 19:58

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表