在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

C語言中的高內聚低耦合講解

multisim ? 來源:CSDN博客 ? 作者:迂者-賀利堅 ? 2021-08-16 14:06 ? 次閱讀

編程時,我們講究的是高內聚低耦合,在協(xié)同開發(fā)、代碼移植、維護等環(huán)節(jié)都起到很重要的作用。

一、原理篇而低耦合,是指模塊之間盡可能的使其獨立存在,模塊之間不產(chǎn)生聯(lián)系不可能,但模塊與模塊之間的接口應該盡量少而簡單。這樣,高內聚從整個程序中每一個模塊的內部特征角度,低耦合從程序中各個模塊之間的關聯(lián)關系角度,對我們的設計提出了要求。

程序設計和軟件工程發(fā)展過程中產(chǎn)生的很多技術、設計原則,都可以從內聚和耦合的角度進行解讀。作為C語言程序設計的初學者,結合當前對于函數(shù)的理解可達到的程度,我們探討一下如何做到高內聚低耦合。

針對低耦合。耦合程度最低的是非直接耦合,指兩個函數(shù)之間的聯(lián)系完全是通過共同的調用函數(shù)的控制和調用來實現(xiàn)的,耦合度最弱,函數(shù)的獨立性最強。但一組函數(shù)之間沒有數(shù)據(jù)傳遞顯然不現(xiàn)實,次之追求數(shù)據(jù)耦合,調用函數(shù)和被調用函數(shù)之間只傳遞簡單的數(shù)據(jù)參數(shù),例如采用值傳遞方式的函數(shù)。

有些函數(shù)數(shù)在調用時,利用形式參數(shù)傳地址的方式,在函數(shù)體內通過指針可以修改其指向的作用域以外的存儲單元,這構成了更強的耦合,稱為特征耦合,在這里,使函數(shù)之間產(chǎn)生聯(lián)系的是地址這樣的特征標識。另外,有兩個函數(shù)可能會打開同一個文件進行操作,這也構成了特征耦合的一種形式。

更強的耦合是外部耦合,這里,一組模塊都訪問同一全局變量,而且不通過參數(shù)表傳遞該全局變量的信息,當發(fā)現(xiàn)程序執(zhí)行結果異常時,很難定位到是在哪個函數(shù)中出了差錯。不少初學者覺得參數(shù)傳遞麻煩,將要處理的數(shù)據(jù)盡可能地定義為全局變量,這樣,函數(shù)之間的接口簡單了,但形成的是耦合性很強的結構。

在C語言中,還可以通過靜態(tài)局部變量,在同一個程序的兩次調用之間共享數(shù)據(jù),這也可以視為是一種外部耦合,只不過靜態(tài)局部變量的作用域限于函數(shù)內部,其影響也只在函數(shù)內部,耦合程度比使全局變量也還是弱很多。由此,我們可以理解前述在使用全局變量、靜態(tài)局部變量時提出的“用在合適的時候,不濫用”的原則。

針對高內聚。內聚程度最高的是功能內聚,模塊內所有元素的各個組成部分全部都為完成同一個功能而存在,共同完成一個單一的功能,模塊已不可再分。這樣的函數(shù)功能非常清晰、明確,一般出現(xiàn)在程序結構圖的較低被調用的層次上。

次之的是順序內聚,一個函數(shù)中各個處理元素和同一個功能密切相關,通常前一個處理元素的輸出是后一個處理元素的輸入。對于這樣的函數(shù),如果不致于產(chǎn)生高耦合的話,可以分開兩個函數(shù)實現(xiàn)。

有的函數(shù),其中的不同處理功能僅僅是由于都訪問某一個公用數(shù)據(jù)而發(fā)生關聯(lián),這稱為通信內聚和信息內聚,內聚程度進一步下降。內聚程度再低的情況就不再一一列舉,最差的偶然內聚中,一個函數(shù)內的各處理元素之間沒有任何聯(lián)系,只是偶然地被湊到一起。

可以想像這樣的模塊東一榔頭西一錘子,類似一個毫無凝聚力的團伙,對應的是低質量。總之,在解決問題劃分函數(shù)時,要遵循“一個函數(shù),一個功能”的原則,盡可能使模塊達到功能內聚。

要做到高內聚低耦合,重點是要在寫代碼之前花些時間做好設計。在下面的例子中,將討論結合具體的問題,如何將以上的因素考慮進去。

二、示例篇本例受裘宗燕老師《從問題到程序——程序設計與C語言引論啟發(fā)》。

任務輸出200以內的完全平方數(shù)(一個數(shù)如果是另一個整數(shù)的完全平方,那么我們就稱這個數(shù)為完全平方數(shù),也叫做平方數(shù)),要求每隔5個數(shù)據(jù)要輸出一個換行。

解決方案及點評對于這個簡單任務,我們在一個main函數(shù)中完成了任務。程序如方案1:

//方案1:內聚性較高的單模塊實現(xiàn)方案

#include 《stdio.h》

int main()

{

int m, num=0;

for (m = 1; m * m 《= 200; m++)

{

printf(“%d ”, m * m);

num++;

if (num%5==0)

printf(“

”);

}

return 0;

}

由于任務本身簡單,將之在一個main函數(shù)中實現(xiàn)后,這個函數(shù)的內聚程度接近功能內聚,已經(jīng)相當高了,就任務本身,不需再進行分解。為使讀者能深入理解模塊質量方面的技術,我們將試圖將內聚程序再提高一些,然后考察耦合程度不同的各種解決方案。

要提高上面解決方案中函數(shù)(僅main一個函數(shù))的內聚程度,我們考察程度的功能“找出完全平方數(shù)并輸出”——“找出完全平方數(shù)”和“輸出”這本身就是兩個功能,再細分輸出時還有“要求5個數(shù)據(jù)在一行”的要求,這些功能的實現(xiàn)細節(jié)都在一個函數(shù)當中,可見是有余地再提高內聚程度的。

在實現(xiàn)的應用中,幾乎所有的處理都可以分解為“輸入-計算-輸出”的模式,優(yōu)秀的解決方案往往至少要將這三個模塊都獨立出來,對于“計算”模塊而言,其內部不再包括輸入輸出,專門接受輸入的數(shù)據(jù),計算完成后返回結果即可。當然,對于復雜的問題,在各個環(huán)節(jié)上可能還需要再做分解。

下面,我們探討將“找出完全平方數(shù)輸出”和“每5個數(shù)據(jù)后換行”分開實現(xiàn)的方案。這樣的分解有助于提高內聚性,與此同時,分解后的兩個模塊間的耦合程度,成為我們要關注的焦點。

現(xiàn)在將“找出完全平方數(shù)并輸出”的功能仍放在main函數(shù)中(獨立成為單獨的函數(shù)也可以,但不必要了),而“每5個數(shù)據(jù)后換行”的功能,設計一個名稱為format的函數(shù),它每調用一次就輸出一個空格作為兩個完全平方數(shù)間的分隔,而每調用到第5次時,輸出的是一個換行。

這兩個模塊之間,需要有一個“現(xiàn)在是第幾次調用”的信息需要傳遞,不可能用耦合程度最松散的非直接耦合。我們考慮數(shù)據(jù)耦合,用簡單形式參數(shù)傳值,得到方案2。

//方案2:一個耦合度低,但不能完成功能要求的解決方案

#include 《stdio.h》

void format(int);

int main()

{

int m, num=0;

for (m = 1; m * m 《= 200; m++)

{

printf(“%d”, m * m);

format(num);

}

return 0;

}

void format(int n)

{

n++;

if (n%5==0)

printf(“

”);

else

printf(“ ”);

return;

}

在這個程序結構中,format與main函數(shù)的耦合程度為數(shù)據(jù)耦合。在main中定義了局部變量num,在一次都未輸出時,置初值為0是合理的。在調用format時,將num傳遞來的表示第幾次輸出(第幾個完全平方數(shù))的形式參數(shù)n,n自增1,然后再控制輸出空格或換行。

然而分析和運行程序發(fā)現(xiàn),“每隔5個數(shù)據(jù)輸出一個換行”的功能并未實現(xiàn)。因為形式參數(shù)n在函數(shù)format內的改變對應的實在參數(shù)num占不同的內存空間,n++修改的結果,對num無任何的影響,導致了在下一次調用時,丟失了“輸出的是第幾個”的重要信息。

一個補救的方法,是由format將變化后的n值作為返回值,再傳回給main函數(shù),得到如下方案3的程序:

//方案3:利用了返回值使耦合度增大,但功能得以實現(xiàn)的方案

#include 《stdio.h》

int format(int);

int main()

{

int m, num=0;

for (m = 1; m * m 《= 200; m++)

{

printf(“%d”, m * m);

num = format(num);

}

return 0;

}

int format(int n)

{

n++;

if (n%5==0)

printf(“

”);

else

printf(“ ”);

return n;

}

維持原函數(shù)返回值為void,而將參數(shù)改為傳地址,得到下面的方案4。這個方案的耦合度更高一些,但功能還是能夠實現(xiàn)的。

//方案4:傳地址實現(xiàn)功能的方案,耦合度更大

#include 《stdio.h》

void format(int*);

int main()

{

int m, num=0;

for (m = 1; m * m 《= 200; m++)

{

printf(“%d”, m * m);

format(&num);

}

return 0;

}

void format(int *p)

{

(*p)++;

if ((*p)%5==0)

printf(“

”);

else

printf(“ ”);

return;

}

一定有人想到了用全局變量的解決方案。這樣,可以將num定義為全局變量,num的生存周期不再依賴于函數(shù)調用,其值也能在函數(shù)的調用之間保持不變(只要其間沒有另外給它賦值),從而可以完成傳遞信息的任務。這時,format因為無需參數(shù)傳遞,可以設計為無參函數(shù),得到如下方案5的程序:

//方案5:耦合度最高的全局變量方案

#include 《stdio.h》

void format();

int num=0;

int main()

{

int m ;

for (m = 1; m * m 《= 200; m++)

{

printf(“%d”, m * m);

format();

}

return 0;

}

void format()

{

num++;

if (num%5==0)

printf(“

”);

else

printf(“ ”);

return;

}

這是解決這個問題的耦合程度最高的一個方案。將num定義為外部變量,意味著如果還有其他函數(shù),num是可以被任何函數(shù)修改的,當發(fā) format 計數(shù)錯誤時,尋找錯誤困難,而修改后又可能會帶來其他地方的錯誤。在這么一個短小的程序中,這種方案可能尚可接受,當程度的規(guī)模稍變大,可能帶來的問題必須高度重視。因此,在實際應用中,強調全局變量要慎用(不是不用)。

考慮到num是在format中應用的私用數(shù)據(jù)——只有format才關心這到底是第幾個數(shù)據(jù),main本來都不用關心的。這樣,可以考慮將num定義為format中的局部靜態(tài)變量,得到方案6的程序:

//方案6:用靜態(tài)局部變量,耦合度偏高但封裝性最好的方案

#include 《stdio.h》

void format();

int main()

{

int m ;

for (m = 1; m * m 《= 200; m++)

{

printf(“%d”, m * m);

format();

}

return 0;

}

void format()

{

static int num=0;

num++;

if (num%5==0)

printf(“

”);

else

printf(“ ”);

return;

}

在這里,靜態(tài)局部變量num的作用域是局部的,定義在函數(shù)體里,封裝性在所有方案里是最好的,從而能保證信息的隱蔽性,避免其他函數(shù)無意的越權訪問;不過,num的生存期是全局的,可以跨越函數(shù)的不同次調用,在兩次調用間傳遞信息,耦合程度(自己和自己的耦合)要高一些,但使main函數(shù)和format函數(shù)的耦合達到了最理想的程度,既保證了功能的正確,又保證了局部數(shù)據(jù)的安全性,表現(xiàn)出靜態(tài)局部變量的優(yōu)勢。綜上所述,在解決一個問題時,存在著諸多的方案。方案1可以接受,但希望提高內聚性而做出改進;方案2用簡單的參數(shù)傳值方式實現(xiàn)耦合程度低,但很可惜不能完成功能;在其他方案中,對于這個問題,選擇的優(yōu)先順序是:

?

方案6、方案3 》 方案4 》 方案5

?建議讀者回顧前面的內容,想一想這樣排序的理由。在上述探討各個方案的過程中,我們應該體會到在程序設計能力提高的過程中,不斷地學習新的技術,懂得新的評判標準,這也就是一個不斷拓寬眼蜀的過程。在稍后的練習中,不妨多想一些方案,也能夠從專業(yè)的角度評判方案的優(yōu)劣,最終做到的,就是出手就是最佳方案的專業(yè)水平。

責任編輯:haq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • C語言
    +關注

    關注

    180

    文章

    7630

    瀏覽量

    140709
  • 編程
    +關注

    關注

    88

    文章

    3686

    瀏覽量

    94958

原文標題:用C語言實例描述程序中的內聚和耦合

文章出處:【微信號:A1411464185,微信公眾號:multisim】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦
    熱點推薦

    深入理解C語言C語言循環(huán)控制

    改變程序的執(zhí)行流程,使代碼更加靈活和可控。本文將詳細介紹這些語句的作用及其應用場景,并通過示例代碼進行說明。Part.1break語句C語言中break語句有兩種
    的頭像 發(fā)表于 04-29 18:49 ?948次閱讀
    深入理解<b class='flag-5'>C</b><b class='flag-5'>語言</b>:<b class='flag-5'>C</b><b class='flag-5'>語言</b>循環(huán)控制

    技術干貨驛站 ▏深入理解C語言:嵌套循環(huán)與循環(huán)控制的底層原理

    大家好!在上一節(jié)中,我們學習了C語言中的基本循環(huán)語句,如for、while和do...while循環(huán)。今天,我們將進一步探討嵌套循環(huán)和循環(huán)控制,這些技巧可以幫助我們實現(xiàn)更復雜的邏輯操作。無論是處理
    的頭像 發(fā)表于 02-21 18:26 ?564次閱讀
    技術干貨驛站  ▏深入理解<b class='flag-5'>C</b><b class='flag-5'>語言</b>:嵌套循環(huán)與循環(huán)控制的底層原理

    EE-62:在C語言中訪問短字內存

    電子發(fā)燒友網(wǎng)站提供《EE-62:在C語言中訪問短字內存.pdf》資料免費下載
    發(fā)表于 01-07 14:02 ?0次下載
    EE-62:在<b class='flag-5'>C</b><b class='flag-5'>語言中</b>訪問短字內存

    EE-128:C語言中的DSP:從C調用匯編類成員函數(shù)

    電子發(fā)燒友網(wǎng)站提供《EE-128:C語言中的DSP:從C調用匯編類成員函數(shù).pdf》資料免費下載
    發(fā)表于 01-07 13:48 ?0次下載
    EE-128:<b class='flag-5'>C</b><b class='flag-5'>語言中</b>的DSP:從<b class='flag-5'>C</b>調用匯編類成員函數(shù)

    深入理解C語言:循環(huán)語句的應用與優(yōu)化技巧

    能讓你的代碼更加簡潔明了,還能顯著提升程序執(zhí)行效率。本文將詳細介紹C語言中的三種常見循環(huán)結構——while循環(huán)、for循環(huán)和do...while循環(huán),帶你深入理解它
    的頭像 發(fā)表于 12-07 01:11 ?558次閱讀
    深入理解<b class='flag-5'>C</b><b class='flag-5'>語言</b>:循環(huán)語句的應用與優(yōu)化技巧

    C語言中申請的堆內存能不能自動釋放

    C語言中申請的堆內存能不能自動釋放?每次都要手動 free 太麻煩,也容易忘記。 學過 C++ 的同學,應該首先能想到智能指針。 但是這是C語言
    的頭像 發(fā)表于 11-27 09:33 ?483次閱讀

    C語言中的頭文件能不能重復包含

    C語言中的頭文件能不能重復包含? 比如代碼寫成這樣,stdio.h 連續(xù)包含了兩次。 #include #include int main(){ printf("helloworld
    的頭像 發(fā)表于 11-26 17:19 ?533次閱讀

    Java 枚舉與策略模式、函數(shù)式接口的結合:實現(xiàn)耦合的設計

    中,通常會使用枚舉來定義業(yè)務上的一組常量,那除了簡單地定義常量之外,我們如何利用枚舉來實現(xiàn)耦合的設計呢?下面介紹下枚舉和策略模式、
    的頭像 發(fā)表于 11-21 14:06 ?584次閱讀

    C語言程序設計教程第4版第8講:指針

    C語言指針講解
    發(fā)表于 11-20 14:10 ?5次下載

    技術干貨驛站 ▏深入理解C語言:掌握C語言條件判斷,從if到switch的應用

    在編程中,條件判斷語句是控制程序流程的核心元素之一。它們使得程序能夠根據(jù)不同的輸入和狀態(tài),做出相應的決策。特別是在C語言中,條件判斷語句的使用極為廣泛,涵蓋了從簡單的if語句到更復雜的switch
    的頭像 發(fā)表于 11-09 01:10 ?817次閱讀
    技術干貨驛站 ▏深入理解<b class='flag-5'>C</b><b class='flag-5'>語言</b>:掌握<b class='flag-5'>C</b><b class='flag-5'>語言</b>條件判斷,從if到switch的應用

    C語言中的socket編程基礎

    Socket編程簡介 Socket是一種通信機制,允許程序之間進行通信。在C語言中,socket編程是網(wǎng)絡編程的基礎。通過使用socket,程序可以發(fā)送和接收數(shù)據(jù),實現(xiàn)不同計算機之間的通信
    的頭像 發(fā)表于 11-01 16:51 ?1107次閱讀

    C語言與Java語言的對比

    C語言和Java語言都是當前編程領域中的重要成員,它們各自具有獨特的優(yōu)勢和特點,適用于不同的應用場景。以下將從語法特性、內存管理、跨平臺性、性能、應用領域等多個方面對C
    的頭像 發(fā)表于 10-29 17:31 ?979次閱讀

    C語言中最常見的宏定義寫法

    如果讓你用C語言寫個宏定義,我相信大部分同學順手就能寫出define。
    的頭像 發(fā)表于 10-28 11:12 ?776次閱讀

    c語言中從左到右結合怎么看

    C語言中,操作符的結合性(Associativity)是指當操作符在表達式中連續(xù)出現(xiàn)時,它們如何與操作數(shù)結合的順序。對于大多數(shù)二元操作符(即需要兩個操作數(shù)的操作符),C語言遵循兩種基
    的頭像 發(fā)表于 08-20 11:42 ?1540次閱讀

    技術干貨驛站 ▏深入理解C語言:基本數(shù)據(jù)類型和變量

    C語言中,數(shù)據(jù)類型和變量是編程的基礎,也是理解更復雜概念的關鍵。數(shù)據(jù)類型決定了變量的內存分配、存儲范圍和操作方式,而變量則是存儲數(shù)據(jù)的容器。本篇文章將從基本數(shù)據(jù)類型和變量兩個方面,帶你深入了解C
    的頭像 發(fā)表于 07-26 17:53 ?2654次閱讀
    技術干貨驛站 ▏深入理解<b class='flag-5'>C</b><b class='flag-5'>語言</b>:基本數(shù)據(jù)類型和變量
    主站蜘蛛池模板: 色网站在线视频 | 天堂网www在线资源 天堂网www在线资源链接 | 黄色午夜| 四虎影院海外永久 | 无人区理论片手机看片 | 精品卡一卡二 卡四卡视频 精品噜噜噜噜久久久久久久久 | 亚洲专区一 | 狠狠躁 | 欧美日本三级 | 激情亚洲婷婷 | 亚洲伊人久久在 | 亚洲天天综合网 | 给我一个可以看片的www日本 | 天天爱添天天爱添天天爱添 | 日韩毛片高清免费 | 日韩在线免费看网站 | 网站啪啪| 四虎欧美在线观看免费 | 免费在线观看一级毛片 | 欧美女同网站 | 性猛交毛片 | 国产资源网站 | 色多多在线观看播放 | 日本黄色录像视频 | 91大神精品视频 | 免费观看三级毛片 | 久久精品久久久久 | 天堂网资源www | 综合精品 | 天天摸天天做天天爽 | 亚洲插插插 | 色宅男看片午夜大片免费看 | 亚洲四虎影院 | 夜色爽| 亚州一级毛片在线 | 欧美操穴| 色老头一区二区三区在线观看 | 亚洲不卡在线播放 | 91色在线视频 | 亚洲va久久久噜噜噜久久男同 | 中文一级黄色片 |