主頁 > 後端開發 > 使用C語言實作簡單的通用的鏈表

使用C語言實作簡單的通用的鏈表

2023-06-08 08:08:27 後端開發

在資料結構中,我們已經學習到了簡單的靜態鏈表以及單鏈表和雙鏈表,它們各有優缺點,但是有個共同的問題是他們呢無法存盤不同的資料,下面提供了一種方法,可以將不同節點的資料鏈接起來,

下面的代碼都是基礎的C語言代碼,涉及到的知識點基本覆寫到C語言學習的所有知識面,尤其是使用了宏,減少了重復的代碼,

無論是C語言大佬還是C語言萌新,都可以食用此鏈表,理解起來可能很復雜,以下是原始碼,建議好好理解,

Main.c

#include "stdafx.h"
#include"Teacher.h"
#include "Student.h"
#include"MainCmd.h"

int main()
{
    CALL_PROC(Main, MainCmd)

    return 0;
}

Stdafx.h

#pragma once
#include<iostream>
using namespace std;

Teacher.h

#pragma once
#include"List.h"
#include"CmdMap.h"

DECLEAR_PROC(Teacher)

struct TEACHER
{
    LINKER linker;

    char szName[20];
    char szAddr[20];
    int nAge;
};

extern LINKER* g_pTeacher;

LINKER* CreateTeacher();
void InputTeacher(LINKER* pLink);
void OutputTeacher(const LINKER* pLink);
LINKER* FindTeacher(LINKER* pHead);

void CreateTeacherList();
void AddTeacher();
void DeleteTeacher();
void FindTeacherNode();
void InsertTeacher();
void ShowTeacherList();
void ClearTeacherList();

Teacher.cpp

#include"Teacher.h"
#include"Student.h"
#include"stdafx.h"
#include"CmdFun.h"

FUN_TABLE g_TeacherTable = { CreateTeacher,&InputTeacher,&OutputTeacher,&FindTeacher };

LINKER* CreateTeacher()
{
    char szName[12] = "";
    cout << "請輸入創建的結點型別:(Student Or Teacher)";
    cin >> szName;
    if (!strcmp(szName, "Student"))
    {
        STUDENT* pNew = new STUDENT;
        if (NULL != pNew)
        {
            pNew->linker.pFunTab = &g_StudentTable;
            pNew->linker.pNext = NULL;
            pNew->linker.pPrev = NULL;
        }
        return (LINKER*)pNew;
    }
    if (!strcmp(szName, "Teacher"))
    {
        TEACHER* pNew = new TEACHER;
        if (NULL != pNew)
        {
            pNew->linker.pFunTab = &g_TeacherTable;
            pNew->linker.pNext = NULL;
            pNew->linker.pPrev = NULL;
        }
        return (LINKER*)pNew;
    }

    return NULL;
}

void InputTeacher(LINKER* pLink)
{
    TEACHER* pTemp = (TEACHER*)pLink;
    cout << "請輸入姓名:";
    cin >> pTemp->szName;
    cout << "請輸入住址:";
    cin >> pTemp->szAddr;
    cout << "請輸入年齡:";
    cin >> pTemp->nAge;

}

void OutputTeacher(const LINKER* pLink)
{
    TEACHER* pTemp = (TEACHER*)pLink;
    cout << "***********************" << endl;
    cout << "姓名:" << pTemp->szName << endl;
    cout << "住址:" << pTemp->szAddr << endl;
    cout << "年齡:" << pTemp->nAge << endl;
}

LINKER* FindTeacher(LINKER* pHead)
{
    TEACHER* pTemp = (TEACHER*)pHead;

    cout << "請輸入要查找的姓名:";
    char szBuf[20];
    cin >> szBuf;

    while (NULL != pTemp->linker.pNext)
    {
        if (0 == strcmp(szBuf, pTemp->szName))
        {
            return (LINKER*)pTemp;
        }
        pTemp = (TEACHER*)pTemp->linker.pNext;
    }

    return NULL;
}

CMD_MAP_BEGIN(Teacher)
CMD(Create, 創建, CreateTeacherList)
CMD(Add, 添加, AddTeacher)
CMD(Delete, 洗掉, DeleteTeacher)
CMD(Find, 查找, FindTeacherNode)
CMD(Insert, 插入, InsertTeacher)
CMD(Show, 創建, ShowTeacherList)
CMD(Clear, 清空, ClearTeacherList)
CMD(Back, 回傳, NULL)
CMD_MAP_END()


LINKER* g_pTeacher = NULL;

CmdFun(Teacher)

Student.h

#pragma once
#include"List.h"
#include"CmdMap.h"

DECLEAR_PROC(Student)

struct STUDENT
{
    LINKER linker;

    char szID[20];
    char chSex;
    int nGrade;
};

struct STAFF
{
    LINKER linker;

    char szID[20];
    char chSex;
    int nGrade;
};

LINKER* CreateStudent();
void InputStudent(LINKER* pLink);
void OutputStudent(const LINKER* pLink);
LINKER* FindStudent(LINKER* pHead);

void CreateStudentList();
void AddStudent();
void DeleteStudent();
void FindStudentNode();
void InsertStudent();
void ShowStudentList();
void ClearStudentList();

Student.cpp

#include"Student.h"
#include"Teacher.h"
#include"stdafx.h"
#include"CmdFun.h"

FUN_TABLE g_StudentTable = { &CreateStudent,&InputStudent,&OutputStudent,&FindStudent };

LINKER* CreateStudent()
{
    char szName[12] = "";
    cout << "請輸入創建的結點型別:(Student Or Teacher)";
    cin >> szName;
    if (!strcmp(szName, "Student"))
    {
        STUDENT* pNew = new STUDENT;
        if (NULL != pNew)
        {
            pNew->linker.pFunTab = &g_StudentTable;
            pNew->linker.pNext = NULL;
            pNew->linker.pPrev = NULL;
        }
        return (LINKER*)pNew;
    }
    if (!strcmp(szName, "Teacher"))
    {
        TEACHER* pNew = new TEACHER;
        if (NULL != pNew)
        {
            pNew->linker.pFunTab = &g_TeacherTable;
            pNew->linker.pNext = NULL;
            pNew->linker.pPrev = NULL;
        }
        return (LINKER*)pNew;
    }

    return NULL;
}

void InputStudent(LINKER* pLink)
{
    STUDENT* pTemp = (STUDENT*)pLink;
    cout << "請輸入ID:";
    cin >> pTemp->szID;
    cout << "請輸入性別:";
    cin >> pTemp->chSex;
    cout << "請輸入分數:";
    cin >> pTemp->nGrade;

}

void OutputStudent(const LINKER* pLink)
{
    STUDENT* pTemp = (STUDENT*)pLink;
    cout << "***********************" << endl;
    cout << "ID:" << pTemp->szID << endl;
    cout << "性別:" << pTemp->chSex << endl;
    cout << "分數:" << pTemp->nGrade << endl;
}

LINKER* FindStudent(LINKER* pHead)
{
    if (NULL == pHead)
    {
        return NULL;
    }

    STUDENT* pTemp = (STUDENT*)pHead;

    cout << "請輸入要查找的ID:";
    char szBuf[20];
    cin >> szBuf;

    while (NULL != pTemp)
    {
        if (0 == strcmp(szBuf, pTemp->szID))
        {
            return (LINKER*)pTemp;
        }
        pTemp = (STUDENT*)pTemp->linker.pNext;
    }

    return NULL;
}

CMD_MAP_BEGIN(Student)
CMD(Create, 創建, CreateStudentList)
CMD(Add, 添加, AddStudent)
CMD(Delete, 洗掉, DeleteStudent)
CMD(Find, 查找, FindStudentNode)
CMD(Insert, 插入, InsertStudent)
CMD(Show, 創建, ShowStudentList)
CMD(Clear, 清空, ClearStudentList)
CMD(Back, 回傳, NULL)
CMD_MAP_END()

LINKER* g_pStudent = NULL;

//CmdFun(Student)

void CreateStudentList() { switch (CreatList(&g_pStudent, CreateStudent)) { case ELIST_MEMORY_FAIL: cout << "動態記憶體分配失敗" << endl; break; case ELIST_OK: cout << "創建鏈表成功" << endl; break; case ELIST_PARAM: cout << "傳參不合理" << endl; break; case ELIST_CREATE_FAIL: cout << "鏈表已存在,創建鏈表失敗" << endl; break; default: break; } } void AddStudent() { switch (Add(g_pStudent)) { case ELIST_MEMORY_FAIL: cout << "動態記憶體分配失敗" << endl; break; case ELIST_OK: cout << "增加結點成功" << endl; break; case ELIST_NOTEXIST: cout << "鏈表不存在" << endl; break; default: break; } } void DeleteStudent() { LINKER* pNode = FindStudent(g_pStudent); switch (DeleteNode(&g_pStudent, pNode)) { case ELIST_OK: cout << "洗掉結點成功" << endl; break; case ELIST_PARAM: cout << "沒有找到要洗掉的結點" << endl; break; case ELIST_NOTEXIST: cout << "鏈表不存在" << endl; break; default: break; } } void FindStudentNode() { LINKER* pNode = FindStudent(g_pStudent); if (NULL != pNode) { cout << "查找成功,該結點資訊如下:" << endl; OutputStudent(pNode); } else { cout << "查找失敗" << endl; } } void InsertStudent() { LINKER* pNode = FindStudent(g_pStudent); if (NULL == pNode) { cout << "沒有找到要插入的位置" << endl; } int mode; cout << "輸入1表示前插輸入0表示后插:"; cin >> mode; switch (Insert(&g_pStudent, pNode, (MODE)mode)) { case ELIST_MEMORY_FAIL: cout << "動態記憶體分配失敗" << endl; break; case ELIST_OK: cout << "插入成功" << endl; break; case ELIST_NOTFIND: cout << "沒有找到要插入的位置,插入失敗" << endl; break; case ELIST_PARAM: cout << "傳入的引數有誤" << endl; break; case ELIST_NOTEXIST: cout << "鏈表不存在,插入失敗!" << endl; break; default: break; } } void ShowStudentList() { switch (ShowList(g_pStudent)) { case ELIST_PARAM: cout << "鏈表不存在" << endl; break; case ELIST_OK: cout << "鏈表已全部顯示" << endl; break; default: break; } } void ClearStudentList() { switch (ClearList(&g_pStudent)) { case ELIST_PARAM: cout << "鏈表不存在" << endl; break; case ELIST_NOTEXIST: cout << "鏈表清空鏈表失敗" << endl; break; case ELIST_OK: cout << "清空鏈表成功" << endl; break; default: break; } }

MainCmd.h

#pragma once
#include"CmdMap.h"

DECLEAR_PROC(Main);

MainCmd.cpp

#include"stdafx.h"
#include"MainCmd.h"
#include"Student.h"
#include"Teacher.h"

void Teacher();
void Student();

CMD_MAP_BEGIN(Main)
CMD(Teacher, 老師, &Teacher)
CMD(Student, 學生, &Student)
CMD(Exit, 退出, NULL)
CMD_MAP_END()

void Teacher()
{
    system("cls");
    CALL_PROC(Teacher, Teacher);
    system("cls");
}

void Student()
{
    system("cls");
    CALL_PROC(Student, Student);
    system("cls");
}

List.h

#pragma once

#define ELIST_OK 1
#define ELIST_CREATE_FAIL -1
#define ELIST_MEMORY_FAIL -2
#define ELIST_NOTEXIST -3
#define ELIST_PARAM -4
#define ELIST_NOTFIND -5

struct LINKER;
struct FUN_TABLE
{
    LINKER* (*pfnCreateNode)();
    void (*pfnInput)(LINKER* pNode);
    void (*pfnOutput)(const LINKER* pNode);
    LINKER* (*pfnFind)(LINKER* pHead);
};

extern FUN_TABLE g_TeacherTable;
extern FUN_TABLE g_StudentTable;


struct LINKER
{
    FUN_TABLE* pFunTab;

    LINKER* pNext;
    LINKER* pPrev;
};

enum MODE { before = 1, after = 0 };

int CreatList(LINKER** ppHead, LINKER* (*pfnCreateNode)());
int Add(LINKER* pHead);
int DeleteNode(LINKER** ppHead, LINKER* pNode);
LINKER* FindNode(LINKER* pHead);
int Insert(LINKER** ppHead, LINKER* pNode, MODE mode);
int ShowList(LINKER* pHead);
int ClearList(LINKER** ppHead);

List.cpp

#include "List.h"
#include"stdafx.h"

int CreatList(LINKER** ppHead, LINKER* (*pfnCreateNode)())
{
    if (NULL == ppHead)
    {
        return ELIST_PARAM;
    }
    if (NULL != *ppHead)
    {
        return ELIST_CREATE_FAIL;
    }

    LINKER* pNew = pfnCreateNode();
    if (NULL == pNew)
    {
        return ELIST_MEMORY_FAIL;
    }

    pNew->pFunTab->pfnInput(pNew);
    *ppHead = pNew;

    return ELIST_OK;
}

int Add(LINKER* pHead)
{
    if (NULL == pHead)
    {
        return ELIST_NOTEXIST;
    }
    while (NULL != pHead->pNext)
    {
        pHead = pHead->pNext;
    }

    LINKER* pNew = pHead->pFunTab->pfnCreateNode();
    if (NULL == pNew)
    {
        return ELIST_MEMORY_FAIL;
    }

    pNew->pFunTab->pfnInput(pNew);
    pHead->pNext = pNew;
    pNew->pPrev = pHead;

    return ELIST_OK;
}

int DeleteNode(LINKER** ppHead, LINKER* pNode)
{
    if (NULL == ppHead || NULL == pNode)
    {
        return ELIST_PARAM;
    }
    if (NULL == *ppHead)
    {
        return ELIST_NOTEXIST;
    }

    if (NULL == pNode->pPrev)
    {
        *ppHead = pNode->pNext;
    }
    else
    {
        pNode->pPrev->pNext = pNode->pNext;
    }
    if (NULL != pNode->pNext)
    {
        pNode->pNext->pPrev = pNode->pPrev;
    }

    delete pNode;
    pNode = NULL;

    return ELIST_OK;
}

LINKER* FindNode(LINKER* pHead)
{
    if (NULL == pHead)
    {
        return NULL;
    }

    return pHead->pFunTab->pfnFind(pHead);

}

int Insert(LINKER** ppHead, LINKER* pNode, MODE mode)
{
    if (NULL == ppHead)
    {
        return ELIST_PARAM;
    }
    if (NULL == *ppHead)
    {
        return ELIST_NOTEXIST;
    }
    if (NULL == pNode)
    {
        return ELIST_NOTFIND;
    }

    LINKER* pNew = (*ppHead)->pFunTab->pfnCreateNode();
    if (NULL == pNew)
    {
        return ELIST_MEMORY_FAIL;
    }
    pNew->pFunTab->pfnInput(pNew);

    if (1 == mode)
    {
        if (NULL == pNode->pPrev)
        {
            *ppHead = pNew;
        }
        else
        {
            pNode->pPrev->pNext = pNew;
        }
        pNew->pPrev = pNode->pPrev;
        pNew->pNext = pNode;
        pNode->pPrev = pNew;
    }
    else if (0 == mode)
    {
        if (NULL != pNode->pNext)
        {
            pNode->pNext->pPrev = pNew;
        }
        pNew->pNext = pNode->pNext;
        pNew->pPrev = pNode;
        pNode->pNext = pNew;
    }
    else
    {
        return ELIST_PARAM;
    }

    return ELIST_OK;
}

int ClearList(LINKER** ppHead)
{
    if (NULL == ppHead)
    {
        return ELIST_PARAM;
    }
    if (NULL == *ppHead)
    {
        return ELIST_NOTEXIST;
    }

    LINKER* pTemp = *ppHead;
    while (NULL != pTemp)
    {
        *ppHead = pTemp->pNext;
        delete pTemp;
        pTemp = *ppHead;
    }

    return ELIST_OK;
}

int ShowList(LINKER* pHead)
{
    if (NULL == pHead)
    {
        return ELIST_PARAM;
    }
    while (NULL != pHead)
    {
        pHead->pFunTab->pfnOutput(pHead);
        pHead = pHead->pNext;
    }
    cout << endl;

    return ELIST_OK;
}

CmdFun.h

#pragma once
#pragma once
#include"stdafx.h"
#include"List.h"

#define CmdFun(name)\
void Create##name##List()\
{\
    switch (CreatList(&g_p##name, Create##name))\
    {\
    case ELIST_MEMORY_FAIL:\
        cout << "動態記憶體分配失敗" << endl;\
        break;\
    case ELIST_OK:\
        cout << "創建鏈表成功" << endl;\
        break;\
    case ELIST_PARAM:\
        cout << "傳參不合理" << endl;\
        break;\
    case ELIST_CREATE_FAIL:\
        cout << "鏈表已存在,創建鏈表失敗" << endl;\
        break;\
    default:\
        break;\
    }\
}\
void Add##name()\
{\
    switch (Add(g_p##name))\
    {\
    case ELIST_MEMORY_FAIL:\
        cout << "動態記憶體分配失敗" << endl;\
        break;\
    case ELIST_OK:\
        cout << "增加結點成功" << endl;\
        break;\
    case ELIST_NOTEXIST:\
        cout << "鏈表不存在" << endl;\
        break;\
    default:\
        break;\
    }\
}\
\
void Delete##name()\
{\
    LINKER* pNode = Find##name(g_p##name);\
\
    switch (DeleteNode(&g_p##name, pNode))\
    {\
    case ELIST_OK:\
        cout << "洗掉結點成功" << endl;\
        break;\
    case ELIST_PARAM:\
        cout << "沒有找到要洗掉的結點" << endl;\
        break;\
    case ELIST_NOTEXIST:\
        cout << "鏈表不存在" << endl;\
        break;\
    default:\
        break;\
    }\
}\
\
void Find##name##Node()\
{\
    LINKER* pNode = Find##name(g_p##name);\
    if (NULL != pNode)\
    {\
        cout << "查找成功,該結點資訊如下:" << endl;\
        Output##name(pNode);\
    }\
    else\
    {\
        cout << "查找失敗" << endl;\
    }\
}\
\
void Insert##name()\
{\
    LINKER* pNode = Find##name(g_p##name);\
    if (NULL == pNode)\
    {\
        cout << "沒有找到要插入的位置" << endl;\
    }\
\
    int mode;\
    cout << "輸入1表示前插輸入0表示后插:";\
    cin >> mode;\
\
    switch (Insert(&g_p##name, pNode, (MODE)mode))\
    {\
    case ELIST_MEMORY_FAIL:\
        cout << "動態記憶體分配失敗" << endl;\
        break;\
    case ELIST_OK:\
        cout << "插入成功" << endl;\
        break;\
    case ELIST_NOTFIND:\
        cout << "沒有找到要插入的位置,插入失敗" << endl;\
        break;\
    case ELIST_PARAM:\
        cout << "傳入的引數有誤" << endl;\
        break;\
    case ELIST_NOTEXIST:\
        cout << "鏈表不存在,插入失敗!" << endl;\
        break;\
    default:\
        break;\
    }\
}\
\
void Show##name##List()\
{\
    switch (ShowList(g_p##name))\
    {\
    case ELIST_PARAM:\
        cout << "鏈表不存在" << endl;\
        break;\
    case ELIST_OK:\
        cout << "鏈表已全部顯示" << endl;\
        break;\
    default:\
        break;\
    }\
}\
\
void Clear##name##List()\
{\
    switch (ClearList(&g_p##name))\
    {\
    case ELIST_PARAM:\
        cout << "鏈表不存在" << endl;\
        break;\
    case ELIST_NOTEXIST:\
        cout << "鏈表清空鏈表失敗" << endl;\
        break;\
    case ELIST_OK:\
        cout << "清空鏈表成功" << endl;\
        break;\
    default:\
        break;\
    }\
}

CmdMap.h

#pragma once
#include"stdafx.h"
struct CMD_MAP
{
    const char* pStrName;
    const char* pStrInfo;
    void (*pfn)();
};

#define CMD_MAP_BEGIN(name)\
void name##Proc(const char *pStrApp)\
{\
    CMD_MAP *pCmdMap = NULL;\
    char szCmd[256] = "";\
    while(true)\
    {\
        pCmdMap = GET_CMD_MAP(name);\
        cout << pStrApp << ">";\
        cin >> szCmd;\
\
        while(NULL != pCmdMap->pStrName)\
        {\
            if(0 == strcmp(pCmdMap->pStrName,szCmd))\
            {\
                if(NULL != pCmdMap->pfn)\
                {\
                    pCmdMap->pfn();\
                }\
                break;\
            }\
            pCmdMap++;\
        }\
        if (NULL == pCmdMap->pStrName)\
        {\
            cout << "您輸入的命令有誤!" << endl;\
        }\
        else\
        {\
            if(NULL == pCmdMap->pfn)\
            {\
                break;\
            }\
        }\
    }\
}\
CMD_MAP g_##name[] = {

#define CMD(name,info,fn)\
    {#name,#info,fn},

#define CMD_MAP_END()\
    {NULL,NULL,NULL}};

#define GET_CMD_MAP(name) g_##name

#define DECLEAR_PROC(name)\
void name##Proc(const char *pStrApp);\
extern CMD_MAP g_##name[];

#define CALL_PROC(name,app_name) name##Proc(#app_name);

運行結果:

  創建通用型鏈表 增加節點: 

   顯示增加的節點:

   

  

  

 

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/554543.html

標籤:其他

上一篇:Spring IOC @Configuration注解分析

下一篇:返回列表

標籤雲
其他(160524) Python(38215) JavaScript(25478) Java(18209) C(15237) 區塊鏈(8270) C#(7972) AI(7469) 爪哇(7425) MySQL(7235) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5873) 数组(5741) R(5409) Linux(5347) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4585) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2434) ASP.NET(2403) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) .NET技术(1983) 功能(1967) HtmlCss(1952) Web開發(1951) C++(1933) python-3.x(1918) 弹簧靴(1913) xml(1889) PostgreSQL(1879) .NETCore(1863) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • 使用C語言實作簡單的通用的鏈表

    在資料結構中,我們已經學習到了簡單的靜態鏈表以及單鏈表和雙鏈表,它們各有優缺點,但是有個共同的問題是他們呢無法存盤不同的資料。下面提供了一種方法,可以將不同節點的資料鏈接起來。 下面的代碼都是基礎的C語言代碼,涉及到的知識點基本覆寫到C語言學習的所有知識面,尤其是使用了宏,減少了重復的代碼。 無論是 ......

    uj5u.com 2023-06-08 08:08:27 more
  • Spring IOC @Configuration注解分析

    # 引入 在使用SpringBoot開發時,最常用的注解有@Component、@Service、@Controller、@Configuration等。當類使用這些注解標記時,類會被Spring IOC容器管理,包括創建,填充屬性和實體化。 但是Spring容器如何發現并將這些類放到容器進行管理呢 ......

    uj5u.com 2023-06-08 08:08:20 more
  • 【Python&RS】遙感影像的像素坐標轉地理坐標(仿射變換)

    ? GDAL(Geospatial Data Abstraction Library)是一個在X/MIT許可協議下的開源柵格空間資料轉換庫。它利用抽象資料模型來表達所支持的各種檔案格式。它還有一系列命令列工具來進行資料轉換和處理。 Python的GDAL庫作為柵格資料的處理轉換庫,其支持幾百種柵格數 ......

    uj5u.com 2023-06-08 08:08:15 more
  • 逍遙自在學C語言 | 宏定義技巧讓你的C代碼快人一步

    ## 前言 在C語言中,宏定義是一種預處理指令,用于在代碼中定義和使用常量、函式或代碼片段的替代。 宏定義使用`#define`關鍵字來定義,并在代碼中進行替換。宏定義具有以下優點: 1. **簡化代碼**:宏定義可以將一些常用的、重復出現的代碼片段簡化為一個宏名稱,提高代碼的可讀性和簡潔性。 2. ......

    uj5u.com 2023-06-08 08:08:04 more
  • IO流 p10 列印流

    # 列印流 PrintStream 和 PrintWriter ![](https://img2023.cnblogs.com/blog/3008601/202306/3008601-20230604103522664-997405676.png) ![](https://img2023.cnblo ......

    uj5u.com 2023-06-08 08:02:46 more
  • Python&Excel辦公自動化

    操作作業簿 01 新建一個excel作業簿 #2023-4-17 import xlwings as xw # 啟動 excel,但不新建作業簿 app是什么,app是excel程式本身 app = xw.App(visible=True,add_book=True) #新建一個作業簿 workbo ......

    uj5u.com 2023-06-08 07:57:40 more
  • Python 串列推導式:簡潔、高效的資料操作藝術

    # Python 串列推導式:簡潔、高效的資料操作藝術 Python 的串列推導式,這個看似簡單的語法糖,實則內含無限威力。在 Python 代碼撰寫中,串列推導式的靈活性和簡潔性讓它成為了不可或缺的一部分。在這篇文章中,我們將更全面、更深入地探討串列推導式,從基礎的概念認識,到各類進階的用法和操作 ......

    uj5u.com 2023-06-08 07:57:35 more
  • 鏈家廣州二手房資料 2023

    還記得在2019年的夏天曾經用 R 爬過一份廣州在 lianjia.com 放盤資料 ([博客1](https://www.cnblogs.com/yukiwu/p/10975337.html),[博客2](https://www.cnblogs.com/yukiwu/p/11271515.html ......

    uj5u.com 2023-06-08 07:57:29 more
  • jvm中類和物件定義存盤基礎知識

    在Java虛擬機中,類和物件是程式的基本組成單元。類定義了一組物件的共性特征和行為,是Java程式中最基本的代碼單元。而物件則是具體的實體,有自己獨特的狀態和行為。在JVM中,類和物件都需要進行存盤,因此了解類和物件的存盤基礎知識對于Java程式員來說是非常重要的。 ......

    uj5u.com 2023-06-08 07:57:25 more
  • 【python基礎】回圈陳述句-while回圈

    # 1.初識while回圈 回圈陳述句主要的作用是在多次處理具有相同邏輯的代碼時使用。while回圈是Python提供的回圈陳述句之一。 while回圈的語法格式之一: ![image](https://img2023.cnblogs.com/blog/3179433/202306/3179433-20 ......

    uj5u.com 2023-06-08 07:57:14 more