尝试实现一个简单的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

  

原文地址:https://www.cnblogs.com/darkchii/p/8344345.html