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('