您的位置:首页 > 其它

第48课 函数设计原则(完)

2016-04-05 23:22 281 查看
1. 函数设计原则

(1)函数从意义上应该是一个独立的功能模块

(2)函数名要在一定程度上反映函数的功能

(3)函数参数名要能够体现参数的意义

(4)尽量避免在函数中使用全局变量

void sc(char *s1, char* s1);×

void str_copy(char* dest, char* src); √

(5)当函数参数不应该在函数体内部被修改时,应加上const声明

(6)如果参数是指针,且仅作输入参数,则应加上const声明

  void str_copy(char* dest, const char* src);

(7)不能省略返回值的类型。如果没有返回值,应声明为void。

(8)对参数进行有效性检查,特别是指针参数的检查尤为重要

(9)不要返回指向“栈内存”的指针,因为栈内存在函数体结束时被自动释放

(10)函数体的规模要小,尽量控制在80行代码之内

(11)相同的输入对应相同的输出,避免函数带有“记忆”功能

(12)避免函数有过多的参数,参数个数尽量控制在4个以内

(13)有时候函数不需要返回值,但为了增加灵活性,如支持链式表达,可以附加返回值

char s[64];

int len = strlen(strcpy(s, "Hello")); //当中的strcpy返回缓冲区s的地址。

(14)函数名返回值类型在语义上不可冲突

char c = getchar(); //getchar的返回值实际上是int类型,而不是char。与函数名不符。

2. 课程总结

(1)C语言的学习需要勤思考、勤动手才能得到提高

(2)难点部分为指针(指针的本质、指针的运算、指针和数组)

(3)学习过程可以采用各个击破的方法,在一个特定的时间段只重点学习和练习某个主题

【实例分析】优秀代码赏析eclipseUtil.c

/*******************************************************************************
* 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 */
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: