C結(jié)構(gòu)體、C++結(jié)構(gòu)體 和 C++類的定義和區(qū)別

C語言中的結(jié)構(gòu)體

一 : C語言中的結(jié)構(gòu)體

(1) C語言中的結(jié)構(gòu)體不能為空,否則會(huì)報(bào)錯(cuò)

要求一個(gè)結(jié)構(gòu)或聯(lián)合至少有一個(gè)成員

(2) C語言中的結(jié)構(gòu)體只涉及到數(shù)據(jù)結(jié)構(gòu),而不涉及到算法.

也就是說在C中數(shù)據(jù)結(jié)構(gòu)和算法是分離的。換句話說就是C語言中的結(jié)構(gòu)體只能定義成員變量,但是不能定義成員函數(shù)。然而在C++中既可以定義成員變量又可以定義成員函數(shù), C++中的結(jié)構(gòu)體和類體現(xiàn)了數(shù)據(jù)結(jié)構(gòu)和算法的結(jié)合。
不過雖然C語言的結(jié)構(gòu)體中不能定義成員函數(shù),但是卻可以定義函數(shù)指針,不過函數(shù)指針本質(zhì)上不是函數(shù)而是指針,所以總的來說C語言中的結(jié)構(gòu)體只是一個(gè)復(fù)雜數(shù)據(jù)類型 ,只能定義成員變量,不能定義成員函數(shù),不能用于面向?qū)ο缶幊獭砜匆粋€(gè)函數(shù)指針的例子:

int FuncAdd(int a, int b)  //求和
{  
    return a + b;  
}  

struct  CTest1  
{  
    int(*Add)(int, int); //函數(shù)指針  
};  
  
int main()  
{  
    struct CTest1 test;  
    int AddResult = 0;  
    test.Add = My_FuncAdd;  
    AddResult = test.Add(8, 6);  
    printf("%d", AddResult);  
}

二 : C++語言中的結(jié)構(gòu)體

(1)第一種語法表示

struct 結(jié)構(gòu)體名稱{
???數(shù)據(jù)類型 member1;
???數(shù)據(jù)類型 member2;
};
這種方式在聲明結(jié)構(gòu)體變量時(shí)為:struct 結(jié)構(gòu)體名稱 結(jié)構(gòu)體變量名

#include<stdio.h>
struct Student{
    int sNo;
    char name[10];
};
int main(){
    struct Student stu;
    scanf("%d",&stu.sNo);
    scanf("%s",stu.name);
    printf("%d\n",stu.sNo);
}
(2)第二種語法表示

typedef struct 結(jié)構(gòu)體名稱{
???數(shù)據(jù)類型 member1;
???數(shù)據(jù)類型 member2;
}結(jié)構(gòu)體名稱別名;
這種方式在聲明結(jié)構(gòu)體變量時(shí)有兩種方式。

第一種:struct 結(jié)構(gòu)體名稱 構(gòu)體變量名
第二種:結(jié)構(gòu)體名稱別名 結(jié)構(gòu)體變量名

原因:這里使用了typedef關(guān)鍵字,此關(guān)鍵字的作用就是聲明數(shù)據(jù)類型的別名,方便用戶編程,所以這里用了之后,結(jié)構(gòu)體名稱別名就相當(dāng)于struct 結(jié)構(gòu)體名稱。在聲明結(jié)構(gòu)體變量時(shí),就無需寫struct了。

#include<stdio.h>
typedef struct Student{
    int sNo;
    char name[10];
}Stu;
int main(){
    struct Student stu;  //方式一
    Stu stu1;            //方式二
    scanf("%d",&stu.sNo);
    scanf("%s",stu.name);
    printf("%d\n",stu.sNo);
    scanf("%d",&stu1.sNo);
    scanf("%s",stu1.name);
    printf("%d\n",stu1.sNo);
}
(3)第三種方式

struct 結(jié)構(gòu)體名稱{
???數(shù)據(jù)類型 member1;
???數(shù)據(jù)類型 member2;
}結(jié)構(gòu)體變量名;

相當(dāng)于:

struct 結(jié)構(gòu)體名稱{
???數(shù)據(jù)類型 member1;
???數(shù)據(jù)類型 member2;
};
struct 結(jié)構(gòu)體名稱 結(jié)構(gòu)體變量名;

這種方式既定義了結(jié)構(gòu)體名稱,同時(shí)聲明了一個(gè)結(jié)構(gòu)體變量名。在其它地方也可以通過struct 結(jié)構(gòu)體來再次聲明其它變量,而第四種方法則不可以。

#include<stdio.h>
struct Student{
    int sNo;
    char name[10];
}stu;      //此處stu 是變量名
int main(){
    scanf("%d",&stu.sNo);
    scanf("%s",stu.name);
    printf("%d\n",stu.sNo);
}
(4)第四種方式

struct {
???數(shù)據(jù)類型 member1;
???數(shù)據(jù)類型 member2;
}結(jié)構(gòu)體變量名;

此方式是匿名結(jié)構(gòu)體,在定義時(shí)同時(shí)聲明2個(gè)結(jié)構(gòu)體變量,但不能在其它地方聲明,因?yàn)槲覀儫o法得知該結(jié)構(gòu)體的標(biāo)識(shí)符,所以就無法通過標(biāo)識(shí)符來聲明變量。

#include<stdio.h>
struct {
    int sNo;
    char name[10];
}stu,stu1;     //匿名結(jié)構(gòu)體,同時(shí)定義了2個(gè)結(jié)構(gòu)體變量
int main(){
    scanf("%d",&stu.sNo);
    scanf("%s",stu.name);
    printf("%d\n",stu.sNo);
    scanf("%d",&stu1.sNo);
    scanf("%s",stu1.name);
    printf("%d\n",stu1.sNo);
}

三 : C++ 中結(jié)構(gòu)體的繼承關(guān)系

對(duì)于成員訪問權(quán)限以及繼承方式,struct中是public。而class中默認(rèn)的是private,class還可以用于表示模板類型,struct則不行。

namespace std{
struct living_habit{ //生活習(xí)慣結(jié)構(gòu)體
...
};

struct animal :public living_habit {//動(dòng)物繼承生活習(xí)慣結(jié)構(gòu)體
...
 };

struct bird :public animal{ //鳥繼承動(dòng)物
...
};

}

另外namespace std{} : 稱namespace(命名空間),在聲明一個(gè)命名空間時(shí),花括號(hào)內(nèi)不僅可以包括變量,而且還可以包括以下類型:
·變量(可以帶有初始化);
·常量;
·數(shù)(可以是定義或聲明);
·結(jié)構(gòu)體;
·類;
·模板;

四 : C++類的定義和實(shí)現(xiàn)

(1):定義(默認(rèn)的是private):
class 類名  
{  
    public:  
        //公共的行為或?qū)傩? 

    private:  
        //公共的行為或?qū)傩? 
}; 
(2):實(shí)現(xiàn)

兩種方式:一種類內(nèi) 實(shí)現(xiàn)(setPoint),另外一種是在類內(nèi)對(duì)成員函數(shù)進(jìn)行聲明 ,類外實(shí)現(xiàn)(setPoint2)

    #include <iostream>  
    using namespace std;  
    class Point  
    {  
        public:  
            void setPoint(int x, int y) //類內(nèi) 實(shí)現(xiàn)setPoint函數(shù)  
            {  
                xPos = x;  
                yPos = y;  
            }  
      
          void setPoint2(int x, int y); //在類內(nèi)對(duì)成員函數(shù)進(jìn)行聲明  ,類外實(shí)現(xiàn)

            void printPoint()       //實(shí)現(xiàn)printPoint函數(shù)  
            {  
                cout<< "x = " << xPos << endl;  
                cout<< "y = " << yPos << endl;  
            }  
      
        private:  
            int xPos;  
            int yPos;  
    };  
      
   void Point2::setPoint(int x, int y) //通過作用域操作符 '::' 實(shí)現(xiàn)setPoint函數(shù)  
     {  
       xPos = x;  
       yPos = y;  
    }  

    int main()  
    {  
        Point M;        //用定義好的類創(chuàng)建一個(gè)對(duì)象 點(diǎn)M  
        M.setPoint(10, 20); //設(shè)置 M點(diǎn) 的x,y值  
       //M.setPoint2(10, 20); //設(shè)置 M點(diǎn) 的x,y值  

        M.printPoint();     //輸出 M點(diǎn) 的信息  
      
        return 0;  
    }  

概念:class和struct的語法基本相同,從聲明到使用,都很相似,但是struct的約束要比class多,理論上,struct能做到的class都能做到,但class能做到的stuct卻不一定做的到。
類型:struct是值類型,class是引用類型,因此它們具有所有值類型和引用類型之間的差異。
效率:由于堆棧的執(zhí)行效率要比堆的執(zhí)行效率高,但是堆棧資源卻很有限,不適合處理邏輯復(fù)雜的大對(duì)象,因此struct常用來處理作為基類型對(duì)待的小對(duì)象,而class來處理某個(gè)商業(yè)邏輯。
關(guān)系:struct不僅能繼承也能被繼承 ,而且可以實(shí)現(xiàn)接口,不過Class可以完全擴(kuò)展。內(nèi)部結(jié)構(gòu)有區(qū)別,struct只能添加帶參的構(gòu)造函數(shù),不能使用abstract和protected等修飾符,不能初始化實(shí)例字段。

注(本文作為隨筆方便自己以后查看,轉(zhuǎn)載請(qǐng)附以下參考鏈接):
http://blog.csdn.net/dawn_after_dark/article/details/73555562
http://blog.csdn.net/Loving_Forever_/article/details/51483828

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容