嘗試實現一個簡單的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\n", 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] != '\0'; 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\n",str.size());
    printf("%s\n", 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\n", 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] != '\0'; 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\n",str.size(&str));
    printf("%s\n", 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

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM