網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
C語(yǔ)言容易被忽視的函數(shù)設(shè)計(jì)原則基礎(chǔ)_C 語(yǔ)言
作者:清風(fēng)自在?流水潺潺 ? 更新時(shí)間: 2022-06-21 編程語(yǔ)言一、函數(shù)設(shè)計(jì)原則
- 函數(shù)從意義上應(yīng)該是一個(gè)獨(dú)立的功能模塊
- 函數(shù)名要在一定程度上反映函數(shù)的功能
- 函數(shù)參數(shù)名要能夠體現(xiàn)參數(shù)的意義
- 盡量避免在函數(shù)中使用全局變量
- 當(dāng)函數(shù)參數(shù)不應(yīng)該在函數(shù)體內(nèi)部被修改時(shí),應(yīng)加上 const 聲明
- 如果參數(shù)是指針,且僅作輸入?yún)?shù),則應(yīng)加上 const 聲明,如下:
- 不能省略返回值的類型
- 如果函數(shù)沒(méi)有返回值,那么應(yīng)聲明為 void
- 類型對(duì)參數(shù)進(jìn)行有效性檢查
- 對(duì)于指針參數(shù)的檢查尤為重要
- 不要返回指向“棧內(nèi)存”的指針
- 棧內(nèi)存在函數(shù)體結(jié)束時(shí)被自動(dòng)釋放
- 函數(shù)體的規(guī)模要小,盡量控制在 80 行代碼之內(nèi)
- 相同的輸入對(duì)應(yīng)相同的輸出,避免函數(shù)帶有“記憶”功能
- 避免函數(shù)有過(guò)多的參數(shù),參數(shù)個(gè)數(shù)盡量控制在 4 個(gè)以內(nèi)
- 有時(shí)候函數(shù)不需要返回值,但為了增加靈活性,如支持鏈?zhǔn)奖磉_(dá),可以附加返回值
- 函數(shù)名與返回值類型在語(yǔ)義上不可沖突
下面來(lái)欣賞一份優(yōu)秀的代碼:
/*******************************************************************************
* Copyright (c) 2000, 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Kevin Cornell (Rational Software Corporation)
*******************************************************************************/
/* Eclipse Launcher Utility Methods */
#include "eclipseOS.h"
#include "eclipseCommon.h"
#include "eclipseUtil.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
#ifdef _WIN32
#include <direct.h>
#else
#include <unistd.h>
#include <strings.h>
#endif
#define MAX_LINE_LENGTH 256
/* Is the given VM J9 */
int isJ9VM( _TCHAR* vm )
{
_TCHAR * ch = NULL, *ch2 = NULL;
int res = 0;
if (vm == NULL)
return 0;
ch = lastDirSeparator( vm );
if (isVMLibrary(vm)) {
/* a library, call it j9 if the parent dir is j9vm */
if(ch == NULL)
return 0;
ch[0] = 0;
ch2 = lastDirSeparator(vm);
if(ch2 != NULL) {
res = (_tcsicmp(ch2 + 1, _T_ECLIPSE("j9vm")) == 0);
}
ch[0] = dirSeparator;
return res;
} else {
if (ch == NULL)
ch = vm;
else
ch++;
return (_tcsicmp( ch, _T_ECLIPSE("j9") ) == 0);
}
}
int checkProvidedVMType( _TCHAR* vm )
{
_TCHAR* ch = NULL;
struct _stat stats;
if (vm == NULL) return VM_NOTHING;
if (_tstat(vm, &stats) == 0 && (stats.st_mode & S_IFDIR) != 0) {
/* directory */
return VM_DIRECTORY;
}
ch = _tcsrchr( vm, _T_ECLIPSE('.') );
if(ch == NULL)
return VM_OTHER;
#ifdef _WIN32
if (_tcsicmp(ch, _T_ECLIPSE(".dll")) == 0)
#else
if ((_tcsicmp(ch, _T_ECLIPSE(".so")) == 0) || (_tcsicmp(ch, _T_ECLIPSE(".jnilib")) == 0) || (_tcsicmp(ch, _T_ECLIPSE(".dylib")) == 0))
#endif
{
return VM_LIBRARY;
}
if (_tcsicmp(ch, _T_ECLIPSE(".ee")) == 0)
return VM_EE_PROPS;
return VM_OTHER;
}
/*
* pathList is a pathSeparator separated list of paths, run each through
* checkPath and recombine the results.
* New memory is always allocated for the result
*/
_TCHAR * checkPathList( _TCHAR* pathList, _TCHAR* programDir, int reverseOrder) {
_TCHAR * c1, *c2;
_TCHAR * checked, *result;
size_t checkedLength = 0, resultLength = 0;
size_t bufferLength = _tcslen(pathList);
result = malloc(bufferLength * sizeof(_TCHAR));
c1 = pathList;
while (c1 != NULL && *c1 != _T_ECLIPSE('\0'))
{
c2 = _tcschr(c1, pathSeparator);
if (c2 != NULL)
*c2 = 0;
checked = checkPath(c1, programDir, reverseOrder);
checkedLength = _tcslen(checked);
if (resultLength + checkedLength + 1> bufferLength) {
bufferLength += checkedLength + 1;
result = realloc(result, bufferLength * sizeof(_TCHAR));
}
if(resultLength > 0) {
result[resultLength++] = pathSeparator;
result[resultLength] = _T_ECLIPSE('\0');
}
_tcscpy(result + resultLength, checked);
resultLength += checkedLength;
if(checked != c1)
free(checked);
if(c2 != NULL)
*(c2++) = pathSeparator;
c1 = c2;
}
return result;
}
_TCHAR * concatStrings(_TCHAR**strs) {
return concatPaths(strs, 0);
}
_TCHAR * concatPaths(_TCHAR** strs, _TCHAR separator) {
_TCHAR separatorString[] = { separator, 0 };
_TCHAR * result;
int i = -1;
size_t length = 0;
/* first count how large a buffer we need */
while (strs[++i] != NULL) {
length += _tcslen(strs[i]) + (separator != 0 ? 1 : 0);
}
result = malloc((length + 1) * sizeof(_TCHAR));
result[0] = 0;
i = -1;
while (strs[++i] != NULL) {
result = _tcscat(result, strs[i]);
if (separator != 0)
result = _tcscat(result, separatorString);
}
return result;
}
/*
* buffer contains a pathSeparator separated list of paths, check
* that it contains all the paths given. Each path is expected to be
* terminated with a pathSeparator character.
*/
int containsPaths(_TCHAR * str, _TCHAR** paths) {
_TCHAR * buffer;
_TCHAR * c;
int i;
/* terminate the string with a pathSeparator */
buffer = malloc((_tcslen(str) + 2) * sizeof(_TCHAR));
_stprintf(buffer, _T_ECLIPSE("%s%c"), str, pathSeparator);
for (i = 0; paths[i] != NULL; i++) {
c = _tcsstr(buffer, paths[i]);
if ( c == NULL || !(c == buffer || *(c - 1) == pathSeparator))
{
/* entry not found */
free(buffer);
return 0;
}
}
free(buffer);
return 1;
}
int isVMLibrary( _TCHAR* vm )
{
_TCHAR *ch = NULL;
if (vm == NULL) return 0;
ch = _tcsrchr( vm, '.' );
if(ch == NULL)
return 0;
#ifdef _WIN32
return (_tcsicmp(ch, _T_ECLIPSE(".dll")) == 0);
#else
return (_tcsicmp(ch, _T_ECLIPSE(".so")) == 0) || (_tcsicmp(ch, _T_ECLIPSE(".jnilib")) == 0) || (_tcsicmp(ch, _T_ECLIPSE(".dylib")) == 0);
#endif
}
#ifdef AIX
#include <sys/types.h>
#include <time.h>
/* Return the JVM version in the format x.x.x
*/
char* getVMVersion( char *vmPath )
{
char cmd[MAX_LINE_LENGTH];
char lineString[MAX_LINE_LENGTH];
char* firstChar;
char fileName[MAX_LINE_LENGTH];
time_t curTime;
FILE* fp;
int numChars = 0;
char* version = NULL;
/* Define a unique filename for the java output. */
(void) time(&curTime);
(void) sprintf(fileName, "/tmp/tmp%ld.txt", curTime);
/* Write java -version output to a temp file */
(void) sprintf(cmd,"%s -version 2> %s", vmPath, fileName);
(void) system(cmd);
fp = fopen(fileName, "r");
if (fp != NULL)
{
/* Read java -version output from a temp file */
if (fgets(lineString, MAX_LINE_LENGTH, fp) == NULL)
lineString[0] = '\0';
fclose(fp);
unlink(fileName);
/* Extract version number */
firstChar = (char *) (strchr(lineString, '"') + 1);
if (firstChar != NULL)
numChars = (int) (strrchr(lineString, '"') - firstChar);
/* Allocate a buffer and copy the version string into it. */
if (numChars > 0)
{
version = malloc( numChars + 1 );
strncpy(version, firstChar, numChars);
version[numChars] = '\0';
}
}
return version;
}
/* Compare JVM Versions of the form "x.x.x..."
*
* Returns -1 if ver1 < ver2
* Returns 0 if ver1 = ver2
* Returns 1 if ver1 > ver2
*/
int versionCmp(char *ver1, char *ver2)
{
char* dot1;
char* dot2;
int num1;
int num2;
dot1 = strchr(ver1, '.');
dot2 = strchr(ver2, '.');
num1 = atoi(ver1);
num2 = atoi(ver2);
if (num1 > num2)
return 1;
if (num1 < num2)
return -1;
if (dot1 && !dot2) /* x.y > x */
return 1;
if (!dot1 && dot2) /* x < x.y */
return -1;
if (!dot1 && !dot2) /* x == x */
return 0;
return versionCmp((char*)(dot1 + 1), (char*)(dot2 + 1) );
}
#endif /* AIX */
二、總結(jié)
- C 語(yǔ)言的學(xué)習(xí)需要勤思考勤動(dòng)手才能得到
- 提高難點(diǎn)部分為指針的學(xué)習(xí)
- 指針的本質(zhì),指針的運(yùn)算,指針和數(shù)組
- 學(xué)習(xí)過(guò)程可以采用各個(gè)擊破的方法
- 在一個(gè)特定的時(shí)間段只重點(diǎn)學(xué)習(xí)和練習(xí)某個(gè)主題
- 在熟練掌握C語(yǔ)言的各個(gè)特性后再進(jìn)行項(xiàng)目練習(xí)
至此,C 語(yǔ)言進(jìn)階剖析學(xué)完,完結(jié)撒花。
但是,以后路還很遠(yuǎn),還需要多加總結(jié),才能真正掌握 C 語(yǔ)言。
原文鏈接:https://blog.csdn.net/weixin_43129713/article/details/124165352
相關(guān)推薦
- 2022-09-16 淺析python中5個(gè)帶key的內(nèi)置函數(shù)_python
- 2023-12-10 Nacos單機(jī)啟動(dòng)的兩種方式
- 2023-11-15 Linux系統(tǒng)SSH客戶端斷開(kāi)后保持進(jìn)程繼續(xù)運(yùn)行配置方法;Python等腳本在終端后臺(tái)運(yùn)行的方法
- 2022-08-20 Python?實(shí)現(xiàn)一個(gè)全連接的神經(jīng)網(wǎng)絡(luò)_python
- 2022-04-05 Python中hash加密簡(jiǎn)介及使用方法_python
- 2022-03-21 golang?調(diào)用c語(yǔ)言動(dòng)態(tài)庫(kù)方式實(shí)現(xiàn)_Golang
- 2022-09-29 React實(shí)現(xiàn)下拉框的key,value的值同時(shí)傳送_React
- 2022-06-12 C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)中堆排序的分析總結(jié)_C 語(yǔ)言
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支