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


    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(''))
        {
            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('');
            }
            _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] = '';
            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] = '';
            }
        }
    
        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 */
  • 相关阅读:
    discuz $_G变量
    php & 引用
    discuz模板引擎
    nginx正则表达式
    linux系统安装 dig和nslookup命令
    linux中的各种$号 位置参数变量
    memcache图形管理工具
    mysql 注入问题
    pycharm 连接mysql失败
    Bootstrap 常用网站
  • 原文地址:https://www.cnblogs.com/5iedu/p/5357412.html
Copyright © 2020-2023  润新知