zoukankan      html  css  js  c++  java
  • 尝试实现一个简单的C语言string类型

      用过`C++/Java/python/matlab/JS`等语言后,发现都能很轻松的使用string类型,而C只能这样:

    char str[] = "hello world";
    or 
    const char* str = "hello world";

      如果只是一个string的类型的话,可以简单的自定义一个:

    typedef const char* string;
    

      但这样的写法并不便利,且这种用法不能修改变量中的数据,于是想写一个类似C++中的string类,但写了一会儿,发现用C实现有点难...

      代码:

    #ifndef STRING_H_INCLUDED
    #define STRING_H_INCLUDED
    
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef const char* const_string;
    typedef char* not_const_string;
    
    typedef struct {
        const_string str;
    
        unsigned int size(){return (unsigned int)strlen(str);};
        void show(){printf("%s
    ", str);};
        not_const_string sort() {
            not_const_string not_con_str = (not_const_string)malloc(strlen(str));
            strcpy(not_con_str, str);
            for(int i = 1; not_con_str[i] != ''; i++) {
                char s = not_con_str[i];
                int j = i - 1;
                while(not_con_str[j] != NULL && not_con_str[j] > s) {
                    not_con_str[j + 1] =  not_con_str[j];
                    j--;
                }
                not_con_str[j + 1] = s;
            }
            return not_con_str;
        }
    }string;
    
    #endif // STRING_H_INCLUDED

      test:

    // 测试头文件 String.h
    #include "String.h"
    
    int main()
    {
        string str = {"baced"};  // 必须加{}
    
        str.show();
        printf("%d
    ",str.size());
        printf("%s
    ", str.sort());
    
        return 0;
    }

      运行结果:

    baced
    5
    abcde

      正常来说,用老版的编译器,比如用VC6.0,或用gcc编译会出现语法错误。我在codeblocks中虽然运行成功了,但这样写法是不能称为C语言的,不过是IDE用C++兼容了这样的写法,所以才这样写。

      我看了一些资料后尝试用回调函数来实现,即在结构体中保存函数指针。

      结果效果并不是很好,语法很麻烦:

    #ifndef STRING_H_INCLUDED
    #define STRING_H_INCLUDED
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef const char* const_string;
    typedef char* not_const_string;
    
    typedef struct string string;
    
    struct string {
        const_string str;
        void (*init) (string* );
        void (*show) (string* );
        unsigned int (*size) (string* );
        not_const_string (*sort) (const_string );
    };
    
    /* 定义函数 */
    void init(string*self);
    unsigned int size(string*self);
    void show(string*self);
    not_const_string sort(const_string str);
    
    void init(string*self) {
        self->init = init;
        self->show = show;
        self->size = size;
        self->sort = sort;
    }
    
    unsigned int size(string*self) {
        return (unsigned int)strlen(self->str);
    }
    
    void show(string*self) {
        printf("%s
    ", self->str);
    }
    
    not_const_string sort(const_string str) {
        not_const_string not_con_str = (not_const_string)malloc(strlen(str));
        strcpy(not_con_str, str);
        for(int i = 1; not_con_str[i] != ''; i++) {
            char s = not_con_str[i];
            int j = i - 1;
            while(not_con_str[j] != NULL && not_con_str[j] > s) {
                not_con_str[j + 1] =  not_con_str[j];
                j--;
            }
            not_con_str[j + 1] = s;
        }
        return not_con_str;
    }
    
    #endif // STRING_H_INCLUDED

      测试:

    #include "String.h"
    
    int main()
    {
        string str = {"baced"};  // 必须加{} --这里是C++中的结构体初始化写法 C语言好像不能这样写 但无妨 可以const_string str2 = "baced";然后再传给init函数
    
        init(&str);
        str.show(&str);
        printf("%d
    ",str.size(&str));
        printf("%s
    ", str.sort(str.str));
    
        return 0;
    }

      运行结果:

    baced
    5
    abcde
    

      可以看到用着挺麻烦的...不如其他语言的简单和直观,经常拿来用的话是不太可能的。

    # 2018-02-05

      实际上,回调函数在许多语言中都可看见(比如python/java/C++等),C语言的一些工程源码中也随处可见,比如windows API 中的WNDCLASS结构体的lpfnWndProc成员就是一个函数指针,还有CreateThread 创建线程函数的第三个参数也是函数指针(创建线程的几个函数中的参数都有函数指针)。

      CreateThread函数的函数指针的定义是这样的:

    typedef (DWORD)(*PTHREAD_START_ROUTINE)(LPVOID lpThreadParameter);
    

      其中DWORD是函数类型,其定义为:

    typedef unsigned long DWORD;
    

      *PTHREAD_START_ROUTINE 即是函数指针,LPVOID lpThreadParameter 则是传参。

      在processthreadsapi.h中可看见其函数原型:

    WINBASEAPI HANDLE WINAPI CreateThread (LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId);

      参考资料:

    https://stackoverflow.com/questions/17052443/c-function-inside-struct
    http://bbs.csdn.net/topics/390124447
    https://www.zhihu.com/question/31519846?sort=created
    

      

  • 相关阅读:
    现在程序员的工资是不是被高估了?
    没有基础怎么学Web前端?相关学习路线是什么?
    在大厂工作5年的大神,给前端初学者的四大建议
    我是小白0基础,现在我想学习前端开发,该如何系统的学习?
    Web前端工程师就业前景怎么样?整体薪资待遇好不好?
    没有基础怎么学Web前端?相关学习路线是什么?
    8年web前端开发经验者告诉你如何零基础学习web前端
    自学Web前端开发需具备哪些技能?(企业要求)?
    Redis cluster 有没有必要刷新 拓扑?
    maven option vs provided and dependencies vs dependencyManagement
  • 原文地址:https://www.cnblogs.com/darkchii/p/8344345.html
Copyright © 2011-2022 走看看