`
imaginecup
  • 浏览: 85416 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

list.h库文件的分析与运用

阅读更多

 lish.h定义双向循环链表的的相关操作。具体的源码分析网上有很多,而且你自己通过阅读注释也可以看懂每个函数的具体功能。接下来就是list.h文件的运用:

由于list.h属于内核模块中的库文件(usr\src\linux-headers-version\include\linux\

而默认加载的是usr\include\下的库文件,不包含list.h

因此需要自己写一个库文件其中包含list.h中的函数

mylist.h

 

 

#ifndef _LINUX_LIST_H
#define _LINUX_LIST_H

#include <linux/stddef.h>


/*
 * Simple doubly linked list implementation.
 *
 * Some of the internal functions ("__xxx") are useful when
 * manipulating whole lists rather than single entries, as
 * sometimes we already know the next/prev entries and we can
 * generate better code by using them directly rather than
 * using the generic single-entry routines.
 */

struct list_head {
 struct list_head *next, *prev;
};

#define LIST_HEAD_INIT(name) { &(name), &(name) }

#define LIST_HEAD(name) \
 struct list_head name = LIST_HEAD_INIT(name)

static inline void INIT_LIST_HEAD(struct list_head *list)
{
 list->next = list;
 list->prev = list;
}

/*
 * Insert a new entry between two known consecutive entries.
 *
 * This is only for internal list manipulation where we know
 * the prev/next entries already!
 */
#ifndef CONFIG_DEBUG_LIST
static inline void __list_add(struct list_head *new,
         struct list_head *prev,
         struct list_head *next)
{
 next->prev = new;
 new->next = next;
 new->prev = prev;
 prev->next = new;
}
#else
extern void __list_add(struct list_head *new,
         struct list_head *prev,
         struct list_head *next);
#endif

/**
 * list_add - add a new entry
 * @new: new entry to be added
 * @head: list head to add it after
 *
 * Insert a new entry after the specified head.
 * This is good for implementing stacks.
 */
static inline void list_add(struct list_head *new, struct list_head *head)
{
 __list_add(new, head, head->next);
}


/**
 * list_add_tail - add a new entry
 * @new: new entry to be added
 * @head: list head to add it before
 *
 * Insert a new entry before the specified head.
 * This is useful for implementing queues.
 */
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
 __list_add(new, head->prev, head);
}

/*
 * Delete a list entry by making the prev/next entries
 * point to each other.
 *
 * This is only for internal list manipulation where we know
 * the prev/next entries already!
 */
static inline void __list_del(struct list_head * prev, struct list_head * next)
{
 next->prev = prev;
 prev->next = next;
}

/**
 * list_del - deletes entry from list.
 * @entry: the element to delete from the list.
 * Note: list_empty() on entry does not return true after this, the entry is
 * in an undefined state.
 */
#ifndef CONFIG_DEBUG_LIST
static inline void list_del(struct list_head *entry)
{
 __list_del(entry->prev, entry->next);
 INIT_LIST_HEAD(entry);
}
#else
extern void list_del(struct list_head *entry);
#endif

/**
 * list_replace - replace old entry by new one
 * @old : the element to be replaced
 * @new : the new element to insert
 *
 * If @old was empty, it will be overwritten.
 */
static inline void list_replace(struct list_head *old,
    struct list_head *new)
{
 new->next = old->next;
 new->next->prev = new;
 new->prev = old->prev;
 new->prev->next = new;
}

static inline void list_replace_init(struct list_head *old,
     struct list_head *new)
{
 list_replace(old, new);
 INIT_LIST_HEAD(old);
}

/**
 * list_del_init - deletes entry from list and reinitialize it.
 * @entry: the element to delete from the list.
 */
static inline void list_del_init(struct list_head *entry)
{
 __list_del(entry->prev, entry->next);
 INIT_LIST_HEAD(entry);
}

/**
 * list_move - delete from one list and add as another's head
 * @list: the entry to move
 * @head: the head that will precede our entry
 */
static inline void list_move(struct list_head *list, struct list_head *head)
{
 __list_del(list->prev, list->next);
 list_add(list, head);
}

/**
 * list_move_tail - delete from one list and add as another's tail
 * @list: the entry to move
 * @head: the head that will follow our entry
 */
static inline void list_move_tail(struct list_head *list,
      struct list_head *head)
{
 __list_del(list->prev, list->next);
 list_add_tail(list, head);
}

/**
 * list_is_last - tests whether @list is the last entry in list @head
 * @list: the entry to test
 * @head: the head of the list
 */
static inline int list_is_last(const struct list_head *list,
    const struct list_head *head)
{
 return list->next == head;
}

/**
 * list_empty - tests whether a list is empty
 * @head: the list to test.
 */
static inline int list_empty(const struct list_head *head)
{
 return head->next == head;
}

/**
 * list_empty_careful - tests whether a list is empty and not being modified
 * @head: the list to test
 *
 * Description:
 * tests whether a list is empty _and_ checks that no other CPU might be
 * in the process of modifying either member (next or prev)
 *
 * NOTE: using list_empty_careful() without synchronization
 * can only be safe if the only activity that can happen
 * to the list entry is list_del_init(). Eg. it cannot be used
 * if another CPU could re-list_add() it.
 */
static inline int list_empty_careful(const struct list_head *head)
{
 struct list_head *next = head->next;
 return (next == head) && (next == head->prev);
}

/**
 * list_is_singular - tests whether a list has just one entry.
 * @head: the list to test.
 */
static inline int list_is_singular(const struct list_head *head)
{
 return !list_empty(head) && (head->next == head->prev);
}

static inline void __list_cut_position(struct list_head *list,
  struct list_head *head, struct list_head *entry)
{
 struct list_head *new_first = entry->next;
 list->next = head->next;
 list->next->prev = list;
 list->prev = entry;
 entry->next = list;
 head->next = new_first;
 new_first->prev = head;
}

/**
 * list_cut_position - cut a list into two
 * @list: a new list to add all removed entries
 * @head: a list with entries
 * @entry: an entry within head, could be the head itself
 * and if so we won't cut the list
 *
 * This helper moves the initial part of @head, up to and
 * including @entry, from @head to @list. You should
 * pass on @entry an element you know is on @head. @list
 * should be an empty list or a list you do not care about
 * losing its data.
 *
 */
static inline void list_cut_position(struct list_head *list,
  struct list_head *head, struct list_head *entry)
{
 if (list_empty(head))
  return;
 if (list_is_singular(head) &&
  (head->next != entry && head != entry))
  return;
 if (entry == head)
  INIT_LIST_HEAD(list);
 else
  __list_cut_position(list, head, entry);
}

static inline void __list_splice(const struct list_head *list,
     struct list_head *prev,
     struct list_head *next)
{
 struct list_head *first = list->next;
 struct list_head *last = list->prev;

 first->prev = prev;
 prev->next = first;

 last->next = next;
 next->prev = last;
}

/**
 * list_splice - join two lists, this is designed for stacks
 * @list: the new list to add.
 * @head: the place to add it in the first list.
 */
static inline void list_splice(const struct list_head *list,
    struct list_head *head)
{
 if (!list_empty(list))
  __list_splice(list, head, head->next);
}

/**
 * list_splice_tail - join two lists, each list being a queue
 * @list: the new list to add.
 * @head: the place to add it in the first list.
 */
static inline void list_splice_tail(struct list_head *list,
    struct list_head *head)
{
 if (!list_empty(list))
  __list_splice(list, head->prev, head);
}

/**
 * list_splice_init - join two lists and reinitialise the emptied list.
 * @list: the new list to add.
 * @head: the place to add it in the first list.
 *
 * The list at @list is reinitialised
 */
static inline void list_splice_init(struct list_head *list,
        struct list_head *head)
{
 if (!list_empty(list)) {
  __list_splice(list, head, head->next);
  INIT_LIST_HEAD(list);
 }
}

/**
 * list_splice_tail_init - join two lists and reinitialise the emptied list
 * @list: the new list to add.
 * @head: the place to add it in the first list.
 *
 * Each of the lists is a queue.
 * The list at @list is reinitialised
 */
static inline void list_splice_tail_init(struct list_head *list,
      struct list_head *head)
{
 if (!list_empty(list)) {
  __list_splice(list, head->prev, head);
  INIT_LIST_HEAD(list);
 }
}

/**
 * list_entry - get the struct for this entry
 * @ptr: the &struct list_head pointer.
 * @type: the type of the struct this is embedded in.
 * @member: the name of the list_struct within the struct.
 */
#define list_entry(ptr, type, member)              \
 container_of(ptr, type, member)

#define container_of(ptr,type,member) ({                     \
  const typeof( ((type *)0)->member ) *__mptr = (ptr) ;  \
  (type *)( (char *) __mptr - offsetof(type,member) ) ;})

#define offsetof(type,member) \
 ((size_t) &((type *)0)->member)
  

/**
 * list_first_entry - get the first element from a list
 * @ptr: the list head to take the element from.
 * @type: the type of the struct this is embedded in.
 * @member: the name of the list_struct within the struct.
 *
 * Note, that list is expected to be not empty.
 */
#define list_first_entry(ptr, type, member) \
 list_entry((ptr)->next, type, member)

/**
 * list_for_each - iterate over a list
 * @pos: the &struct list_head to use as a loop cursor.
 * @head: the head for your list.
 */


/**
 * __list_for_each - iterate over a list
 * @pos: the &struct list_head to use as a loop cursor.
 * @head: the head for your list.
 *
 * This variant differs from list_for_each() in that it's the
 * simplest possible list iteration code, no prefetching is done.
 * Use this for code that knows the list to be very short (empty
 * or 1 entry) most of the time.
 */
#define __list_for_each(pos, head) \
 for (pos = (head)->next; pos != (head); pos = pos->next)

/**
 * list_for_each_prev - iterate over a list backwards
 * @pos: the &struct list_head to use as a loop cursor.
 * @head: the head for your list.
 */


/**
 * list_for_each_safe - iterate over a list safe against removal of list entry
 * @pos: the &struct list_head to use as a loop cursor.
 * @n:  another &struct list_head to use as temporary storage
 * @head: the head for your list.
 */
#define list_for_each_safe(pos, n, head) \
 for (pos = (head)->next, n = pos->next; pos != (head); \
  pos = n, n = pos->next)

/**
 * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
 * @pos: the &struct list_head to use as a loop cursor.
 * @n:  another &struct list_head to use as temporary storage
 * @head: the head for your list.
 */


/**
 * list_for_each_entry - iterate over list of given type
 * @pos: the type * to use as a loop cursor.
 * @head: the head for your list.
 * @member: the name of the list_struct within the struct.
 */


/**
 * list_for_each_entry_reverse - iterate backwards over list of given type.
 * @pos: the type * to use as a loop cursor.
 * @head: the head for your list.
 * @member: the name of the list_struct within the struct.
 */

/**
 * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
 * @pos: the type * to use as a start point
 * @head: the head of the list
 * @member: the name of the list_struct within the struct.
 *
 * Prepares a pos entry for use as a start point in list_for_each_entry_continue().
 */
#define list_prepare_entry(pos, head, member) \
 ((pos) ? : list_entry(head, typeof(*pos), member))

/**
 * list_for_each_entry_continue - continue iteration over list of given type
 * @pos: the type * to use as a loop cursor.
 * @head: the head for your list.
 * @member: the name of the list_struct within the struct.
 *
 * Continue to iterate over list of given type, continuing after
 * the current position.
 */


/**
 * list_for_each_entry_continue_reverse - iterate backwards from the given point
 * @pos: the type * to use as a loop cursor.
 * @head: the head for your list.
 * @member: the name of the list_struct within the struct.
 *
 * Start to iterate over list of given type backwards, continuing after
 * the current position.
 */

 

/**
 * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
 * @pos: the type * to use as a loop cursor.
 * @n:  another type * to use as temporary storage
 * @head: the head for your list.
 * @member: the name of the list_struct within the struct.
 */
#define list_for_each_entry_safe(pos, n, head, member)   \
 for (pos = list_entry((head)->next, typeof(*pos), member), \
  n = list_entry(pos->member.next, typeof(*pos), member); \
      &pos->member != (head);      \
      pos = n, n = list_entry(n->member.next, typeof(*n), member))

/**
 * list_for_each_entry_safe_continue
 * @pos: the type * to use as a loop cursor.
 * @n:  another type * to use as temporary storage
 * @head: the head for your list.
 * @member: the name of the list_struct within the struct.
 *
 * Iterate over list of given type, continuing after current point,
 * safe against removal of list entry.
 */
#define list_for_each_entry_safe_continue(pos, n, head, member)   \
 for (pos = list_entry(pos->member.next, typeof(*pos), member),   \
  n = list_entry(pos->member.next, typeof(*pos), member);  \
      &pos->member != (head);      \
      pos = n, n = list_entry(n->member.next, typeof(*n), member))

/**
 * list_for_each_entry_safe_from
 * @pos: the type * to use as a loop cursor.
 * @n:  another type * to use as temporary storage
 * @head: the head for your list.
 * @member: the name of the list_struct within the struct.
 *
 * Iterate over list of given type from current point, safe against
 * removal of list entry.
 */
#define list_for_each_entry_safe_from(pos, n, head, member)    \
 for (n = list_entry(pos->member.next, typeof(*pos), member);  \
      &pos->member != (head);      \
      pos = n, n = list_entry(n->member.next, typeof(*n), member))

/**
 * list_for_each_entry_safe_reverse
 * @pos: the type * to use as a loop cursor.
 * @n:  another type * to use as temporary storage
 * @head: the head for your list.
 * @member: the name of the list_struct within the struct.
 *
 * Iterate backwards over list of given type, safe against removal
 * of list entry.
 */
#define list_for_each_entry_safe_reverse(pos, n, head, member)  \
 for (pos = list_entry((head)->prev, typeof(*pos), member), \
  n = list_entry(pos->member.prev, typeof(*pos), member); \
      &pos->member != (head);      \
      pos = n, n = list_entry(n->member.prev, typeof(*n), member))

/*
 * Double linked lists with a single pointer list head.
 * Mostly useful for hash tables where the two pointer list head is
 * too wasteful.
 * You lose the ability to access the tail in O(1).
 */


#endif

  

list.c

 

#include <stdio.h>
#include <stdlib.h>
#include "mylist.h"
struct Data
{
    char data;
    struct list_head list;
};

typedef struct Data mydata;

void decimal_to_binary();
void binary_to_decimal();
void free_memory(struct list_head *pos,struct list_head *p,struct Data mylist,struct Data *tmp);


int main(int argc ,char *argv[])
{    
    int select = 0;
    printf("**************************************************************\n");
    printf("** 1.Decimal to binary **\n");
    printf("** 2.Binary to decimal **\n");
    printf("** 0.Exit **\n");
    printf("**************************************************************\n");
    printf("Please select which you want to convert:");
    scanf("%d",&select);
    getchar();
    switch (select){
        case 0:printf("Welcome to use next time!\n");break;
        case 1:decimal_to_binary();          break ;
        case 2:binary_to_decimal();              break;
        default:printf("Your select is not right!"); break;
    }

    return 0;
}
/***********************************************************************
 *Function name:dec_to_binary
 *Function Description: The function is used to covert a number from
 *                decimal to binary
 *Parameter:@num ,the decimal which will be coverted
 *Result:Display the num 's binary result
 ***********************************************************************/
void decimal_to_binary()
{
    long number,temp;
    mydata mylist,*tmp;
    struct list_head *pos,*p;
    INIT_LIST_HEAD(&mylist.list);
    
    printf("please input a number you want to convert:");
    scanf("%ld",&number);
    printf("Decemal number %ld's binary is:",number);
    
    if (number == 0) { 

        printf("%ld",number);
        printf("\n");
        return;
    }
    while (number != 0) {
        tmp = (mydata *)malloc(sizeof(mydata));
        temp = number % 2;
        tmp -> data = temp;
        list_add(&(tmp->list),&(mylist.list));
        number = number / 2;
    }
    __list_for_each(pos,&mylist.list) {
        tmp = list_entry(pos,struct Data,list);
        printf("%ld",(long)tmp->data);
    }
    printf("\n");
    



    list_for_each_safe(pos,p,&mylist.list){
        tmp = list_entry(pos,struct Data,list);
        list_del(pos);
        free(tmp);
    }
    if (list_empty(&mylist.list)){
        printf("The list now is empty!\n");
    }
}

/***********************************************************************
 *Function name:dec_to_binary
 *Function Description: The function is used to covert a number from
 *                binary to decimal
 *Parameter:void
 *Result:Display the num 's decimal result
 ***********************************************************************/
void binary_to_decimal()
{
    mydata mylist,*tmp;
    struct list_head *pos,*p;
    char ch = '0';
    long dec = 1; 

    long dec_number = 0;

    INIT_LIST_HEAD(&mylist.list);
    printf("Please input the binary number you want to convert:");
    ch = getchar();
    while ((ch == '0')||(ch == '1')){
        tmp = (struct Data *)malloc(sizeof(struct Data));
        tmp -> data = ch;
        list_add(&(tmp->list),&(mylist.list));
        ch = getchar();
    } 
     __list_for_each(pos,&mylist.list){
        tmp = list_entry(pos,struct Data,list);
        dec_number += (int)(tmp ->data - '0') * dec;
        dec *= 2;
    }
    printf("\n");
    printf("Decimal number is %ld\n",dec_number);


    list_for_each_safe(pos,p,&mylist.list){
        tmp = list_entry(pos,struct Data,list);
        list_del(pos);
        free(tmp);
    }
    if (list_empty(&mylist.list)){
        printf("The list now is empty!\n");
    }
}

 

 

listTest.c

 

#include<stdio.h>
#include<stdlib.h>
#include"mylist.h"
#include<string.h>
struct userinfo{
	char username[20];
	char password[20];
	struct list_head list;
};
typedef struct userinfo UserStruct;

int main(int argc,char *argv[]){
	char username[20],password[20];
	char flag[2]="#";
	UserStruct userlist,*user,*temp,*replacetest,*templist;
	struct list_head *pos,*p;
	//初始化双向循环链表
	INIT_LIST_HEAD(&(userlist.list));
	INIT_LIST_HEAD(&(templist->list));
	printf("please input your username and password:\n");
	scanf("%s",username);
	scanf("%s",password);
	getchar();
	
	//循环添加元素
	while(strcmp(username,flag) && strcmp(password,flag)){
		user=(struct userinfo*)malloc(sizeof(struct userinfo));
		strcpy(user->username,username);
		strcpy(user->password,password);
		list_add_tail(&(user->list),&(userlist.list));
		printf("please input your username and password:\n");
		scanf("%s",username);
		scanf("%s",password);
		getchar();
	}
	
	//利用一个新的节点替换第一个节点
	replacetest=(struct userinfo*)malloc(sizeof(struct userinfo));
	strcpy(replacetest->username,"username");
	strcpy(replacetest->password,"password");
	list_replace_init(userlist.list.next,&(replacetest->list));
	//将一个节点移动到双向循环链表末尾
	list_move_tail(userlist.list.next,&(userlist.list));
	//将一个节点移动到双向循环链表头
	list_move_tail(userlist.list.prev,&(userlist.list));

	if(list_is_last(&(replacetest->list),&(userlist.list))){
		printf("该节点是双向循环链表的最后一个节点\n");
	}

	if(!list_is_singular(&(userlist.list))){
		printf("该双向循环链表有多个节点\n");
	}
	//遍历双向循环链表
	printf("遍历双向循环链表\n");
	__list_for_each(pos,&(userlist.list)){
		temp=list_entry(pos,struct userinfo,list);
		printf("用户名:%s 密码:%s\n",temp->username,temp->password);
	}
	/*
	//双向循环链表的切割
	list_cut_position(&(templist->list),&(userlist.list),userlist.list.next);
	
	//遍历切割的双向循环链表
	printf("遍历切割的双向循环链表\n");
	__list_for_each(pos,&(templist->list)){
		temp=list_entry(pos,struct userinfo,list);
		printf("用户名:%s 密码:%s\n",temp->username,temp->password);
	}
	//合并链表
	__list_splice(&(templist->list),userlist.list.next,userlist.list.next->next);
	list_splice_init(&(templist->list),&(userlist.list));
	
	//遍历合并后双向循环链表
	printf("遍历合并后双向循环链表\n");
	
	__list_for_each(pos,&(userlist.list)){
		temp=list_entry(pos,struct userinfo,list);
		printf("用户名:%s 密码:%s\n",temp->username,temp->password);
	}
	*/
	//释放内存资源
	list_for_each_safe(pos,p,&(userlist.list)){
		temp=list_entry(pos,struct userinfo,list);
		list_del(pos);
		free(temp);
	}
	
	if(list_empty(&(userlist.list))){
		printf("双向循环链表为空\n");
	}



	return 0;
}

 

 

0
0
分享到:
评论

相关推荐

    Linux内核应用链表:kernel-list.zip

    linux内核链表移植来自内核当中的/include/list.h,并且给出相关应该例子在main.cpp文件中,方便在操作系统上使用。

    嵌入式开发系统实验说明书

    9.双向连表相关函数 LIST.H 245 6.触摸屏相关函数TCHSCR.H 246 7.键盘相关函数 KEYBOARD.H 246 8.液晶显示相关函数 LCD320.H 246 9. 串行口相关函数UHAL.H 247 10.字符串相关函数USTRING.H 248 11.系统图形...

    arm 2410for ucos 实验指导

    4.双向链表相关函数LIST.H 102 5.触摸屏相关函数TCHSCR.H 102 6.液晶显示相关函数 LCD.H 103 7.串行口相关函数UHAL.H 104 8.字符串相关函数USTRING.H 104 9.系统图形相关函数 FIGURE.H 105 10.系统启动时相关...

    C版本MD5库

    C版本MD5库 参考README.md 内容 ...至于选静态库还是动态库,就看具体应用场景了,静态库的坏处是把库代码编译进去了, 若是程序按字节收费还是可以的,(PS,吐槽那个写了一个10w,10G的程序中国神童)

    UnityDissector:.unity3d文件解压缩程序,以获取用.NET编写的.dll和资产文件[未维护]

    可以从.unity3d格式提取文件的命令行应用程序。 笔记 不支持Unity 5。 编译中 编译它的最简单方法是使用Visual Studio并按F6键或使用MonoDevelop。 您也可以使用最新版本的mono进行编译 git clone git://github....

    嵌入式Linux C语言应用程序设计

    其中lock.c是文件锁的源代码,seri.c和seri.h是串口设置的源代码,read_seri.c是读串口的源代码,write_seri.c是写串口的源代码。 程序代码\chapter10 文件夹中包含了第10章的示例源程序。其中alarm_read.c是设置...

    MySQL 5.1参考手册

    1.5.7. 与MaxDB有关的链接 1.6. MySQL发展大事记 1.6.1. MySQL 5.1的新特性 1.7. MySQL信息源 1.7.1. MySQL邮件列表 1.7.2. IRC(在线聊天系统)上的MySQL社区支持 1.7.3. MySQL论坛上的MySQL社区支持 1.8. MySQL...

    通用的C++数据结构代码实现,使用模板.rar

    //.h文件 #ifndef LIST_H #define LIST_H #include template struct Node_for_List //声明结点 { T data; Node_for_List* next; Node_for_List(Node_for_List* pnext = NULL){ next = pnext; } //构造空结点 ...

    MySQL 5.1参考手册 (中文版)

    1.5.7. 与MaxDB有关的链接 1.6. MySQL发展大事记 1.6.1. MySQL 5.1的新特性 1.7. MySQL信息源 1.7.1. MySQL邮件列表 1.7.2. IRC(在线聊天系统)上的MySQL社区支持 1.7.3. MySQL论坛上的MySQL社区支持 1.8. MySQL...

    C连接MYSQL5.1所需要的库文件

    注意是5.1版本的,库必须与MYSQL版本一致,不然会导致连接失败

    mysql官方中文参考手册

    1.5.7. 与MaxDB有关的链接 1.6. MySQL发展大事记 1.6.1. MySQL 5.1的新特性 1.7. MySQL信息源 1.7.1. MySQL邮件列表 1.7.2. IRC(在线聊天系统)上的MySQL社区支持 1.7.3. MySQL论坛上的MySQL社区支持 1.8. MySQL...

    MYSQL中文手册

    2.3.14. 在Windows环境下对MySQL安装的故障诊断与排除 2.3.15. 在Windows下升级MySQL 2.3.16. Windows版MySQL同Unix版MySQL对比 2.4. 在Linux下安装MySQL 2.5.在Mac OS X中安装MySQL 2.6. 在NetWare中安装MySQL...

    MySQL 5.1参考手册中文版

    1.5.7. 与MaxDB有关的链接 1.6. MySQL发展大事记 1.6.1. MySQL 5.1的新特性 1.7. MySQL信息源 1.7.1. MySQL邮件列表 1.7.2. IRC(在线聊天系统)上的MySQL社区支持 1.7.3. MySQL论坛上的MySQL社区支持 1.8. ...

    C语言程序设计标准教程

    实际上在前面的各章中我们已经多次使用了文件,例如源程序文件、目标文件、可执行文件、库文件 (头文件)等。文件通常是驻留在外部介质(如磁盘等)上的, 在使用时才调入内存中来。从不同的角度可对文件作不同的分类...

    汉字转拼音 自适应多音字处理 姓名自动切分 c++开源代码.zip

    0. 功能包括:自动分离姓名中的[姓,名];姓名转拼音(一对一,首字母+全拼音);姓名转拼音(一对多,首字母+全拼音) ...7. 使用方法:可以直接看本文件(.h文件)的注释 或 进入详情页面开,见第二条的网址

    Linux高级bash编程

    文件与归档命令 12.6. 通讯命令 12.7. 终端控制命令 12.8. 数学计算命令 12.9. 混杂命令 13. 系统与管理命令 13.1. 分析一个系统脚本 14. 命令替换 15. 算术扩展 16. I/O 重定向 16.1. 使用exec ...

    Advanced Bash-Scripting Guide <>

    12.5. 文件与归档命令 12.6. 通讯命令 12.7. 终端控制命令 12.8. 数学计算命令 12.9. 混杂命令 13. 系统与管理命令 13.1. 分析一个系统脚本 14. 命令替换 15. 算术扩展 16. I/O 重定向 16.1. 使用exec 16.2. 代码块...

    代码语法错误分析工具pclint8.0

    1.将pclint.rar解压至c:\, 这样lint文件就位与c:\pclint(安装目录)下了。 2.将c:\pclint\lnt 下的3个文件lib-w32.lnt,env-vc6.lnt,co-msc60.lnt拷贝至c:\pclint下, 再在安装目录下创建std.lnt和options.lnt两个...

    FreeRTOS V10.0.1 版本源码和例程

    与 UC/OSII 一样,FreeRTOS 在 STM32 的移植大致由 3 个文件实现,一个.h 文件定义编译器相关的数据类型 和中断处理的宏定义;一个.c 文件实现任务的堆栈初始化、系统心跳的管理和任务切换的请求;一个.s 文件实 现...

Global site tag (gtag.js) - Google Analytics