2022-04-11 关于C结构体与C++类的一些想法

最近看了个答题,很好玩,对C结构体和C++类的理解有些帮助。

原题:C语言 结构体的赋值测试

题主的要求是在C语言结构体的赋值中使用如下方法,但是不能通过,问原因,更改方案。

#include <stdio.h>
#include <stdlib.h>
#define  NUM  50
struct film
{
    char name[NUM];  //电影的名称 
    int  score;   //电影的评分    
};
typedef film FILM; 
 
int main(void)
{
    FILM  movie;
    movie = {"GoldedFather",10};
    printf("the name is %s and the score is %d .\n",movie.name,movie.score);
    return 0;
}

熟悉C语言的,一眼就能看出问题,这不是一个C的正常typedef,而是C++的,因为没有加struct,同时题主要用初始化的方法,但不在初始化的时候进行结构体赋值。

换句话说,如何用值列表在非初始化环境赋值给结构体。

当然,正常情况下,编译器是不允许这样做的。所以常规的解法是:

    FILM  movie = {"GoldedFather",10};

老老实实的按照C语言的规定,进行初始化赋值。

或者老老实实的进行成员赋值:


strcpy(movie.name,"GoldedFather");

movie.score=10;
 

更为根本的解决方法,也有人提出,用C++进行编译,没错,同样一段代码,用C编译叫结构体非初始化赋值,是非法的,但用C++就是类的值列表赋值,是合法的。

这个就是大家经常诟病的向下兼容,C++为了向下兼容C,让类的声明不仅可以用class,还可以用struct,于是在未标明究竟是C还是C++的时候,你无法判断同样一段代码是否合法。

从某种意义上,C++的只有public数据成员组成的struct类和C的struct结构体是一样的,成员的调用,成员赋值,成员使用都是一样的。区别只在定义和赋值时,C++似乎可以用更多的合法方法。

那么除了上述老老实实的方法,就没什么可行但不太建议的方法呢,有:

#include <stdio.h>
#include <stdlib.h>

typedef struct film
{
    int a;
    char b[10];
} FILM;

int main()
{
    FILM movie;
    movie = (FILM){1, "sdfa"};
}

其中的奥秘,估计老手一看便知,并且经常用来折磨代码维护人员,C的类型强制转换。

通过强制转换,C把一个值列表强制转为FILM结构体变量,那么一个结构体变量是可以赋值给另一个结构体变量的,这是合法的。

C语言太灵活了,灵活到近乎无法无天,强制转换这种语法,可以将任何类型转换为另一种任何类型,但是他把所有的责任都抛给了程序员。

一个灵活的C语言程序员的代码,在另一个人看,就是天书,当一个C++er在代码中混入C,或者相反,但没有注释,这将是一场灾难。

C不是面向对象的语言,在语言上讲,很大原因就是结构体无法完成类的一些效果,比如成员函数,比如私有成员,也就无法彻底的封装,使得库的使用者,永远可以用出乎意料的方式使用库构建者所构建的“类”。

最后总结,C语言和C++,不是一种语言,虽然兼容,但使用要格外小心,否则你真的无法知道你的程序究竟运行的是什么东西。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不停感叹的老林_<C 语言编程核心突破>

不打赏的人, 看完也学不会.

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值