用过`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

  

尝试实现一个简单的C语言string类型的更多相关文章

  1. 利用OD破解一个简单的C语言程序

    最近在学习汇编(看的是王爽老师的<汇编语言(第三版)>),然后想尝试使用OD(Ollydbg)软件破解一个简单的C语言程序练练手. 环境: C语言编译环境:VC++6.0 系统:在Wind ...

  2. 一个简单的C语言程序(详解)

    C Primer Plus之一个简单的C语言程序(详解) #include <stdio.h> int main(void) //一个简单的 C程序 { int num; //定义一个名为 ...

  3. 初次尝试PHP——一个简单的对数据库操作的增删改查例子

    第一次学习PHP,很多人说PHP是最好的语言,学习了一点点,还不敢说这样的话,不过确实蛮好用的. 做了一个简单的对数据库的增删改查的操作,主要是将四种操作写成了独立的函数,之后直接调用函数.以下是代码 ...

  4. 利用windows.h头文件写一个简单的C语言倒计时

    今天写一个简单的倒计时函数 代码如下: #include<stdio.h> #include<windows.h> int main() { int i; printf(&qu ...

  5. 编写一个Car类,具有String类型的属性品牌,具有功能drive; 定义其子类Aodi和Benchi,具有属性:价格、型号;具有功能:变速; 定义主类E,在其main方法中分别创建Aodi和Benchi的对象并测试对象的特 性。

    package com.hanqi.test; public class Car { //构造一个汽车的属性 private String name; //创建getter和setter方法 publ ...

  6. 为Python编写一个简单的C语言扩展模块

    最近在看pytorh方面的东西,不得不承认现在这个东西比较火,有些小好奇,下载了代码发现其中计算部分基本都是C++写的,这真是要我对这个所谓Python语音编写的框架或者说是库感觉到一丢丢的小失落,细 ...

  7. 一个简单的C语言语法检查器的实现

    我自己的实现方法的核心过程:首先用一个非终结符代表所有要检查的程序代码,然后根据文法将这个整体的符号不断展开,以拼凑成按检查的程序的顺序排列的终结符序列,能成功说明语法正确,否则有错误. 关键词:分词 ...

  8. C++ Daily 《4》----一个简单的 int to string 的方法

    经常会在项目中用到 int to string, 之前一般用C语言的 sprintf, 发现C++ 中的 ostringstream 可以轻松完成这个任务. #include <iostream ...

  9. 一个简单的C语言题背后的故事

    最近看到了一个C语言问题,是要计算出这个函数的输出: #include <stdio.h> int Test(int x,int y, int z){ printf("x,y,z ...

随机推荐

  1. 在 input 上添加图标字体时无法添加的问题

    效果:一个搜索框.如图: 实施过程:一开始,将搜索框分为2部分,用2个 input ,一个 search ,一个 button ,然后给 type="button" 的input ...

  2. C++ explicit的作用

    explicit作用: 在C++中,explicit关键字用来修饰类的构造函数,被修饰的构造函数的类,不能发生相应的隐式类型转换,只能以显示的方式进行类型转换. explicit使用注意事项: * e ...

  3. nested exception is org.apache.ibatis.binding.BindingException: Parameter 'cons_id' not found. Available parameters are [arg2, arg1, arg0, param3, param1, param2]

    修改DAO层的类中的方法,如下所示:

  4. List(数组)里面常用的属性和方法

    常用属性: length 长度 reversed 翻转 isEmpty 是否为空 isNotEmpty 是否不为空常用方法: add 增加 addAll 拼接数组 增加多个数据 list.addAll ...

  5. mysql 远程连接不上,bind-address参数配置要求,以及怎么去使得mysql能够允许远程的客户端访问

    刚安装了MySQL服务器,使用远程管理工具总是连接不上,因为知道mysql的默认端口是3306,于是使用telnet连接这个端口,(从这里可以学到telnet是可以这样用的) telnet 192.1 ...

  6. workspace 打开的是我的电脑

    在system tree板块的空白处右键-->set root-->current workspace 即可恢复workspace.

  7. python开发基础作业01:模拟登陆系统

    随老男孩学习python mark 作业要求及提示:编写登录接口 ''' 练习程序:编写登录接口 1. 输入用户名和密码 2. 认证成功后显示欢迎信息 3. 输错三次后锁定 输入三次后退出,下次同样用 ...

  8. Android系统架构(图解)

    下图是 Android 操作系统的架构,架构包括 4 层,由上到下依次是应用程序层.应用程序框架层.核心类库和 Linux 内核.其中,核心类库中包含系统库及 Android 运行环境. 图1  An ...

  9. es 搜索功能简介

    DSL 语法介绍 语法 范围 /_search 集群上搜索所有的索引 /index1/_search index1 /index1,index2/_search index1和index2 /inde ...

  10. Kubernetes的pod控制器之DaemonSet

    DaemonSet 顶级参数介绍 [root@master manifests]# kubectl explain ds KIND: DaemonSet VERSION: extensions/v1b ...