C 语言和C++语言的 struct对比

本文深入探讨了C++语言与C语言中struct的对比,包括成员初始化、类型区别、typedef结构、变量声明等方面。通过具体代码示例展示了两者之间的差异,并强调了C++作为C语言的扩展,提供了更丰富的类特性。

C 语言和C++语言的 struct对比

                                                                                                          author: stonehat

1. C++语言将struct当成类来处理的,所以C++的struct可以包含C++类的所有东西,例如构造函数,析构函数,友元等,C++的struct和C++类唯一不同就是

    struct成员默认的是public, C++默认private。而C语言struct不是类,不可以有函数,也不能使用类的特征例如public等关键字 ,也不可以有static关键字。

2. C++ struct里面成员初始化的形式和类是相同的,不可以直接初始化,就是不可以定义成员的时候同时初始化。C语言 struct中间的某个类型(例如int)也不可以直接初始化。

   就是说下面int a = 0;在C++和C语言里面都是不能通过的。

   

struct HE
{
int a = 0;
}
//C++和C编译是不能通过的。

3.  初始化方式,C++ struct的初始化,C++不仅拥有C语言的初始化方式。如下:

 

struct HE
{
int a;

};
int main(){
HE d={3}; // 因为 HE在C++是类名,可以省略struct。C语言里面要加上struct 才行。
return 0;
}

也可以使用类的初始化方式

struct HE
{
int a;

};
int main(){
HE d;
d.a = 3;
return 0;
}



4. 类型不同,下面代码:

 

struct HE
{
int a;

};

在C里面实际上数据类型为 (struct HE),所以定义一个结构HE变量都要 带上struct. 

struct HE a;   //C语言 变量方式

而在C++里面实际上数据类型为HE(主要是因为结构体被当成类对待了),所以定义变量不需要 struct.

HE a; //C++语言 变量

5. typedef struct 在C++和C语言中都是一样的功能,定义别名。 但是要注意下面的代码的区别

//代码一

#include <stdio.h>
#include <stdlib.h>
typedef struct HE
{
int a;

} *PHE,DHE,EHE; //这是定义了一个struct HE*类型别名和两个普通别名,main函数只考虑指针型别名。
int main(){
PHE a = (PHE)malloc(sizeof(struct HE)); //这是C语言的写法
//PHE a = new HE(); 这是C++语言的写法
return 0;
}
//代码二
#include <stdio.h>
#include <stdlib.h>
struct HE
{
int a;

} *PHE,DHE,EHE; //这里定义了一个指针型变量和两个普通变量

上面两个代码省略 struct的名字 HE都是可以的。

总结:C++语言因为是和C语言兼容的,所以C语言的语法在C++编译器里不会出错,但是程序员最好知道什么是C语言,什么是C++语言。



转载于:https://www.cnblogs.com/stonehat/archive/2011/10/07/2200629.html

<think>嗯,用户问的是C++struct astruct *a的区别。首先,我需要确认自己对这两个表达式的理解是否正确。struct a通常是指结构体类型的实例,而struct *a应该是指向结构体的指针。不过可能用户在这里的写法有些简略,需要明确语法是否正确。 首先,struct a的声明方式是否正确呢?在C++中,声明结构体变量通常不需要重复使用struct关键字,比如如果已经定义了结构体a,那么直接写a obj;就可以了。但如果是C语言的话,可能需要struct a obj;。不过用户提到的是C++,所以可能这里的struct a是指一个结构体实例。但可能用户想表达的是声明结构体变量时,比如struct A a;struct A *a;的区别? 或者,用户可能是在问结构体变量结构体指针变量之间的区别。比如,struct A a; 定义了一个A类型的结构体变量,而struct A *a; 定义了一个指向A结构体的指针变量。这种情况下,两者的区别在于内存分配访问方式。 需要进一步考虑用户的可能意图。用户可能混淆了结构体实例指针的声明方式。在C++中,声明结构体变量时,可以省略struct关键字,直接使用结构体名。比如,假设有struct A {};,那么声明变量可以是A a;,而指针则是A *a;。这时候,a是对象实例,*a是指针,指向该类型的对象。 所以,正确的区别应该是实例指针的区别。实例直接存储结构体的数据,而指针存储的是内存地址,需要通过解引用或箭头操作符来访问成员。比如a.membera->member的区别。 另外,需要提到内存分配的问题。结构体实例在声明时可能已经在栈上分配了内存(如果是局部变量),而指针则需要手动分配内存(比如使用new)或者指向已有的实例。如果指针未初始化就使用,会导致未定义行为。 可能用户的问题中还涉及到结构体的定义声明的不同。比如,struct a {};是定义一个结构体类型,而struct *a可能是指针的声明,但这在语法上可能不正确,除非a已经被定义为一个结构体类型。例如,正确的指针声明应该是struct A *a;,其中A是已经定义的结构体类型。 总结下来,用户的问题可能需要拆解为两点:结构体实例与结构体指针的区别,以及正确的语法形式。需要指出在C++中声明结构体变量指针的正确方式,并比较它们在内存、访问方式用法上的不同。 同时,要注意用户可能存在的误解,比如struct *a的写法是否正确,是否需要先定义结构体类型。可能用户实际是想比较结构体变量指向结构体的指针变量,比如A a;A *a;之间的区别,这时候需要解释两者的不同之处,包括内存分配、访问方式、传递参数时的差异等。 另外,可能需要提到在函数参数传递时,使用指针可以避免拷贝大的结构体,提高效率。或者使用引用(C++特性)作为替代方案。同时,指针可以为空,而实例必须有实际的对象存在。 最后,需要确保回答准确,避免误导用户。例如,struct astruct *a这样的写法可能只有在特定上下文中有效,需要明确结构体是否已经定义,或者是否存在语法错误。例如,如果用户的意思是struct A a;struct A *a;,那么这里的A是结构体名,而a是变量名。这种情况下,前者是实例,后者是指针,正确区分即可。</think>在C++中,`struct a``struct *a`的区别主要体现在**变量类型****内存操作方式**上。以下是详细对比: --- ### 一、语法本质区别 1. **`struct a`** - 表示一个结构体类型的**实例**(具体对象) - 直接存储结构体的完整数据 - 示例: ```cpp struct Student { // 先定义结构体类型 int id; string name; }; Student a; // 声明一个结构体实例a ``` 2. **`struct *a`** - 表示指向结构体类型的**指针** - 仅存储内存地址(需指向已存在的结构体实例) - 示例: ```cpp Student *a_ptr; // 声明一个指向Student结构体的指针 ``` --- ### 二、内存分配对比 | 特性 | `struct a` (实例) | `struct *a` (指针) | |--------------------|------------------------------|-------------------------------| | 内存占用 | 直接占用结构体大小的内存 | 固定为指针大小(如4/8字节) | | 内存位置 | 通常分配在栈上(局部变量时) | 指针本身在栈,指向内容在堆或栈 | | 初始化要求 | 自动初始化(除非手动指定) | 必须显式指向有效内存地址 | | 典型内存操作 | `Student a;` | `Student *a_ptr = new Student;` | --- ### 三、访问成员的差异 1. **实例访问**(`.`运算符) ```cpp a.id = 1001; // 直接访问成员 a.name = "Alice"; ``` 2. **指针访问**(`->`运算符 或 先解引用) ```cpp a_ptr->id = 1002; // 通过指针访问成员 (*a_ptr).name = "Bob"; // 等价写法 ``` --- ### 四、典型使用场景 | 场景 | `struct a` (实例) | `struct *a` (指针) | |--------------------|--------------------------------------------|---------------------------------------------| | 函数参数传递 | 会产生拷贝(适合小型结构体) | 传递地址(适合大型结构体,避免拷贝开销) | | 动态内存管理 | 不能直接用于动态内存分配 | 必须通过`new`/`delete`管理堆内存 | | 数据结构 | 直接作为数据节点 | 用于链表、树等需要动态链接的结构 | | 空值可能性 | 实例必然存在(除非未初始化) | 指针可为`nullptr`(需判空) | --- ### 五、关键注意事项 1. **指针必须初始化**: ```cpp // 错误用法(野指针) Student *a_ptr; a_ptr->id = 1003; // 未初始化,导致未定义行为 // 正确用法 Student s; Student *a_ptr = &s; // 指向栈对象 Student *a_heap = new Student; // 指向堆对象 ``` 2. **深浅拷贝问题**: ```cpp Student a = {1004, "Charlie"}; Student b = a; // 浅拷贝(若含指针成员需谨慎) Student *c = &a; // 共享同一份数据 ``` 3. **现代C++替代方案**: ```cpp // 优先使用智能指针 #include <memory> std::unique_ptr<Student> smart_ptr = std::make_unique<Student>(); ``` --- ### 六、完整代码示例 ```cpp #include <iostream> #include <string> using namespace std; struct Student { int id; string name; }; int main() { // 实例用法 Student s1; s1.id = 1001; s1.name = "Alice"; // 指针用法 Student *s2 = new Student; s2->id = 1002; (*s2).name = "Bob"; // 输出结果 cout << "s1: " << s1.id << " " << s1.name << endl; cout << "s2: " << s2->id << " " << s2->name << endl; delete s2; // 必须手动释放堆内存 return 0; } ``` --- **总结**:`struct a`是直接操作数据实体,而`struct *a`是通过指针间接操作数据。选择依据: - 需要直接控制数据生命周期 → 用实例 - 需要动态内存管理或避免拷贝 → 用指针(或更现代的智能指针/引用)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值