.

作者 : 万境绝尘

转载请注明出处http://www.hanshuliang.com/?post=30

.

结构体概述 : 结构体是 多个 变量的集合, 变量的类型可以不同;

-- 可进行的操作 : 结构体可以进行 拷贝 赋值操作, 可以作为 函数参数 和 函数返回值;

1. 结构体的基本使用

结构体声明 : struct 结构标记 {结构成员} 普通变量;

-- 结构体示例 :

	struct student
	{
		char *name;
		int age;
	};

-- 结构标记 : struct 后面的 student 是结构标记, 这个标记 可写 可不写, 其作用是 为结构命名, 结构标记可以代表 {} 中的声明的所有的成员变量;

-- 结构成员 : 在 {} 中定义的变量就是结构成员;

-- 普通变量 : 在声明结构体的时候后面可以加上若干普通变量, 相当于定义结构体变量;

结构体变量声明 : 可以在定义的时候声明变量, 也可以在定义完结构体使用 结构标记 声明变量;

-- 定义结构体时声明变量 : 这种声明变量的方式可以不用 结构标记, 变量名写在 花括号 后面, 用头号隔开;

	struct student
	{
		char *name;
		int age;
	} s1, s2, s3;

-- 使用结构标记声明 : 结构标记 student 代表了花括号的声明, 是 结构体的简写, 可以使用结构标记代替花括号中的内容;

struct student s4, s5, s6;

结构体内存分配 : 结构体内存是在声明变量的时候分配的, 如果只声明了结构体, 没有声明对应变量, 那么不会分配内存;

结构体变量初始化 :

-- 声明结构体的时候初始化 : struct student s1 = {"Tom", 12} ; 注意 初值表中必须时结构体对应类型的常量表达式;

-- 声明之后初始化 : 结构体变量名.成员名 可以访问结构体中的成员变量, s1.name = "Tom"; s2.age = 12;

结构体嵌套 : 结构体中的成员变量可以是 结构体变量;

	struct student
	{
		char *name;
		int age;
	} s1;

	struct class
	{
		struct student s1;
		struct student s2;
	} c1;

结构体代码示例 :

/*************************************************************************
    > File Name: base_struct.c
    > Author: octopus
    > Mail: octopus_work.163.com
    > Created Time: 2014年03月24日 星期一 10时49分46秒
 ************************************************************************/

#include<stdio.h>

int main(int argc, char **argv)
{
	/*
	 * 声明结构体 同时声明变量s1
	 */
	struct student
	{
		char *name;
		int age;
	} s1;

	/*
	 * 结构体嵌套
	 */
	struct class
	{
		struct student s1;
		struct student s2;
	} c1;

	struct student s2 = {"Tom", 12};/*只有声明的时候才能对结构体初始化才能使用花括号赋值*/
	struct class c2 = {{"Jack", 13}, {"Pig", 15}};
	s1.name = "Hack";		/*变量声明后对结构体赋值只能一个一个赋值*/
	s1.age = 14;
	//s1 = {"fuck", 1};		/*只有在初始化的时候才能使用 花括号初始化结构体变量*/
	c1.s1.name = "CJ";
	c1.s1.age = 21;
	c1.s2.name = "KW";
	c1.s2.age = 22;

	/*访问结构体中的变量, 使用 . 进行访问*/

	printf("s1 : name = %s, age = %d \n", s1.name, s1.age);
	printf("s2 : name = %s, age = %d \n", s2.name, s2.age);
	printf("c1 : s1 : name = %s, age = %d ; s2 : name = %s, age = %d \n", c1.s1.name, c1.s1.age, c1.s1.name, c1.s2.age);
	printf("c2 : s1 : name = %s, age = %d ; s2 : name = %s, age = %d \n", c2.s1.name, c2.s1.age, c2.s1.name, c2.s2.age);

	return 0;
}

执行结果

octopus@octopus-Vostro-270s:~/code/c/struct$ gcc base_struct.c
octopus@octopus-Vostro-270s:~/code/c/struct$ ./a.out
s1 : name = Hack, age = 14
s2 : name = Tom, age = 12
c1 : s1 : name = CJ, age = 21 ; s2 : name = CJ, age = 22
c2 : s1 : name = Jack, age = 13 ; s2 : name = Jack, age = 15

2. 结构体与函数

结构体的合法操作 :

-- 整体复制 : 结构体可以复制;

-- 整体赋值 : 声明结构体的时候可以整体赋值, 在其它情况下不可以;

-- & 取地址 : 使用 & 运算符获取 结构体地址;

-- 访问成员 : 使用 结构体变量名.成员变量名 可以访问成员变量;

函数传递结构体方法 :

-- 传递结构体成员 : 将结构体拆开, 将其中的成员变量分别传入;

struct class create_class(struct student s2, struct student s3)
{
	struct class c1 = {s2, s3};
	return c1;
}

-- 传递结构体 :  将整个结构体当做参数传入, 这种情况和传递其它类型参数一样, 都是通过值传递的;

struct class create_class(struct student s2, struct student s3)
{
	struct class c1 = {s2, s3};
	return c1;
}

-- 传递结构体指针 : 传递结构体的指针, 访问形式如下;

/*
 * 传入一个结构体指针
 * 通过指针访问结构体的方法 :
 *   (*结构体指针变量).成员变量 访问;
 *   结构体指针变量 -> 成员变量 访问;
 */
void printf_struct_pointer(struct student *s)
{
	printf("student : (*s).name = %s, (*s).age = %d \n", (*s).name, (*s).age);
	printf("student : s->name = %s, s->age = %d \n", s->name, s->age);
}

结构体指针访问 :

-- 示例 : 定义一个结构体指针;

	struct student
	{
		char *name;
		int age;
	}*p;

-- "." 和 "->"优先级 : 这两个运算符都是从左到右运算, 都是右结合; "." 和 "->" 优先级比 "*" , "++" 优先级要高; 这两个运算符 与 () [] 是四个优先级最高的运算符;

-- ++p->age 分析 : 是对结构体中的 age 进行自增操作;

-- *p->name 分析 : 获取 结构体中的 name 字符串的值(注意不是指针|地址);

-- *p++->name 分析 : 先获取 name 字符串的值, 再将p自增;

结构体函数示例 :

/*************************************************************************
    > File Name: method_struct.c
    > Author: octopus
    > Mail: octopus_work.163.com
    > Created Time: 2014年03月24日 星期一 14时46分16秒
 ************************************************************************/

#include<stdio.h>

/*声明一个结构体类型, 其成员变量是普通变量*/
struct student
{
	char *name;
	int age;
};

/*声明一个结构体类型, 其成员变量是结构体*/
struct class
{
	struct student s1;
	struct student s2;
};

/*
 * 传递 2 个结构体的成员变量
 * 在函数中创建结构体并返回
 */
struct student create_student(char *name, int age)
{
	struct student s1 = {name, age};
	return s1;
}

/*
 * 传递 2 个结构体变量
 */
struct class create_class(struct student s2, struct student s3)
{
	struct class c1 = {s2, s3};
	return c1;
}

/*
 * 传入一个结构体指针
 * 通过指针访问结构体的方法 :
 *   (*结构体指针变量).成员变量 访问;
 *   结构体指针变量 -> 成员变量 访问;
 */
void printf_struct_pointer(struct student *s)
{
	printf("student : (*s).name = %s, (*s).age = %d \n", (*s).name, (*s).age);
	printf("student : s->name = %s, s->age = %d \n", s->name, s->age);
}

int main(int argc, char **argv)
{
	/*使用函数获取一个结构体, 传入结构体的值*/
	struct student s1 = create_student("Tom", 11);
	printf("student : name = %s, age = %d \n", s1.name, s1.age);

	/*创建一个成员变量是结构体的结构体, 并打印结构体数据*/
	struct class c1 = create_class(create_student("Jack", 12), create_student("CJ", 13));
	printf("c1 : s1 : name = %s, age = %d ; s2 : name = %s, age = %d \n", c1.s1.name, c1.s1.age, c1.s2.name, c1.s2.age);

	/*声明结构体指针*/
	struct student *p = &s1;
	printf_struct_pointer(p);
	return 0;
}

执行结果

octopus@octopus-Vostro-270s:~/code/c/struct$ gcc method_struct.c
octopus@octopus-Vostro-270s:~/code/c/struct$ ./a.out
student : name = Tom, age = 11
c1 : s1 : name = Jack, age = 12 ; s2 : name = CJ, age = 13
student : (*s).name = Tom, (*s).age = 11
student : s->name = Tom, s->age = 11 

3. 结构体数组

(1) 结构体数组声明初始化

声明结构体数组 :

-- 声明结构体的时候声明结构体数组 : 格式为 : struct 结构标记 {} 数组名[];

-- 使用结构标记声明结构体数组 : 格式为 : struct 结构标记 数组名[];

结构体数组声明初始化 :

-- 逐个元素初始化 : 数组名[] = {{结构体1}, {结构体2}};

-- 总体初始化 : 数组名[] = {常量1, 常量2 ...};

结构体初始化 :

/*************************************************************************
    > File Name: array_struct.c
    > Author: octopus
    > Mail: octopus_work.163.com
    > Created Time: 2014年03月24日 星期一 16时40分15秒
 ************************************************************************/

#include<stdio.h>

/*
 * 声明结构体
 * 同时也声明结构体类型数组
 * 为数组初始化
 * 直接将每个结构体成员的值依次列出即可
 */
struct student
{
	char *name;
	int age;
} team1[] =
{
	"Tom", 12,
	"Jack", 13
};

int main(int argc, char **argv)
{
	int i;
	/*将每个结构体初始化, 赋值, 每个结构体初始化内容使用 花括号括起来*/
	struct student team2[] = {{"CJ", 34}, {"KI", 32}};
	for(i = 0; i < 2; i++)
	{
		printf("team1 : team1[i].name = %s, team1[i].age = %d \n", team1[i].name, team1[i].age);
	}

	for(i = 0; i < 2; i++)
	{
		printf("team2 : team2[i].name = %s, team2[i].age = %d \n", team2[i].name, team2[i].age);
	}

	return 0;
}

执行结果

octopus@octopus-Vostro-270s:~/code/c/struct$ gcc array_struct.c
octopus@octopus-Vostro-270s:~/code/c/struct$ ./a.out
team1 : team1[i].name = Tom, team1[i].age = 12
team1 : team1[i].name = Jack, team1[i].age = 13
team2 : team2[i].name = CJ, team2[i].age = 34
team2 : team2[i].name = KI, team2[i].age = 32 

(2) 结构体数组示例程序

需求 : 实现一个统计 C 语言关键字出现次数;

代码 :

/*************************************************************************
    > File Name: word_count.c
    > Author: octopus
    > Mail: octopus_work.163.com
    > Created Time: 2014年03月24日 星期一 17时12分32秒
 ************************************************************************/

#include<stdio.h>
#include<ctype.h>
#include<string.h>

#define MAXWORD 10

/*
 * 定义结构体类型 key
 * 该类型结构体中存储一个 字符串(关键字) 和 int 数据(关键字出现次数)
 * 同时声明一个结构体数组
 * 对结构体数组进行初始化
 *
 *
 */
struct key
{
        char *word;
        int count;
}key_count[] =
{
        "auto", 0,
        "break", 0,
        "case", 0,
        "char", 0,
        "const", 0,
        "continue", 0,
        "default", 0,
        "void", 0,
        "volatitle", 0,
        "while", 0
};

int main(int argc, char **argv)
{
        int n;
        char word[MAXWORD];

        /*循环接收字符串, 如果字符串与结构体数组中匹配, 结构体的count ++*/
        while(getword(word, MAXWORD) != EOF)
                if(isalpha(word[0]))
                        if((n = binsearch(word, key_count, 10)) >= 0)
                                key_count[n].count++;

        /*打印大于0的关键字 及 个数*/
        for (n = 0; n < 10; n ++)
                if(key_count[n].count > 0)
                        printf("%2d %s\n", key_count[n].count, key_count[n].word);

        return 0;
}

/*
 * 重要api解析 :
 *  int getc(FILE *stream) 从标准输入流中读取字符
 *  int ungetc(int c, FILE *stream) 将字符退回到标准输入流中
 *  int isspace(int c) 判断字符是否是 空格 '\f' '\r' '\n' '\t' '\v'
 *  int isalpha(int c) 判断是否是字母
 */
int getword(char *word, int lim)
{
        int c, getc(FILE*), ungetc(int, FILE*);
        char *wp = word;

        /*过滤空格, 如果输入的不是 空, 就继续向下执行*/
        while(isspace(c = getc(stdin)));

        /*如果输入的不是结束符, 那么 wp指针, 先取值, 之后地址自增*/
        if(c != EOF)
                *wp++ = c;

        /*如果输入的不是字母, 直接返回, 关键字里面没有数字开头的*/
        if(!isalpha(c))
        {
                *wp = '\0';
                return c;
        }

        /*
         * 循环条件 a. 接收的最大字符个数 lim, 每读取一个字符, 该变量自减
         * 当该变量自减为0时停止循环接收字符串
         * 循环条件 b. 当读取到的字符 不是 字母 或者数字的时候, 停止循环
         */
        for(; --lim > 0; wp++)
        {
                if(!isalnum(*wp = getc(stdin)))
                {
                        ungetc(*wp, stdin);
                        break;
                }
        }

        *wp = '\0';
        return word[0];
}

/*
 * 参数解析 : word 是要查找的字符串 tab 字符串数组 n 字符串大小
 */
int binsearch(char *word, struct key tab[], int n)
{
        /*
         * cond 判断 查找的字符串 是在mid 坐标之前 (<0) 之后(>0) 或者就是mid坐标
         *
         * 如果查找的不是正好中间的变量符合, 就返回 -1 失败
         */
        int cond, low, high, mid;

        low = 0;
        high = n - 1;
        /*
         * 要找的值的下标在low 和 high之间
         * mid 是 low 和 high 的中值
         * 如果 word 小于中值下标 将比较范围 缩小
         */
        while(low <= high)
        {
                mid = (low + high) / 2;
                if((cond = strcmp(word, tab[mid].word)) < 0)
                        high = mid - 1;
                else if(cond > 0)
                        low = mid + 1;
                else
                        return mid;
        }
        return -1;
}

执行结果 :

[root@ip28 struct]# gcc word_count.c
[root@ip28 struct]# ./a.out
auto
break
break
char
 1 auto
 2 break
 1 char

宏定义方法 : 获取结构体数组大小;

-- sizeof 方法 : sizeof (对象) | sizeof (类型名称) 可以获取对象 或者 类型占用的存储空间, 其返回值是 size_t 类型的, 定义在stddef.h 头文件中;

-- 使用类型测量 :

#define KEYS (sizeof(key_count) / sizeof(struct key))

-- 使用对象测量

#define KEYS (sizeof(key_count) / sizeof(struct key_count[0])

4. 指向结构体指针

(1) 使用指针方式实现上面的关键字统计程序

使用指针进行二分查找 :

-- 使用下标找中值 : 在之前找中值时通过 mid = (low + high)方法, 这样做可行是因为 low 从0开始的;

-- 如果是指针情况 : mid low high 都是指针, 那么就不能使用上面的那种方法了, 使用 mid = low + (high - low) / 2;.

-- 指针操作情况的 high 和 low : 其中 low 是首元素的 首地址, high 是 尾元素的尾地址, 只有这样 它们的差的 0.5 倍才是准确的中值的首地址;

指针指向数组注意点 : 不要生成非法的指针, 指针不能指向数组之外的元素;

-- &key_count[-1] : 这个指针时非法的;

-- &key_count[n] : 对数组的最后一个元素后面的第一个元素进行 & 运算时合法的, 其它操作都是非法的;

示例程序 :

/*************************************************************************
    > File Name: pointer_struct.c
    > Author: octopus
    > Mail: octopus_work.163.com
    > Created Time: Tue 25 Mar 2014 12:31:08 AM CST
 ************************************************************************/

#include<stdio.h>
#include<ctype.h>
#include<string.h>

#define MAXWORD 20
/*计算结构体数组的大小*/
#define KEYS (int)(sizeof(key_count) / sizeof(struct key))

struct key
{
	char *word;
	int count;
} key_count[] =
{
	"auto", 0,
	"break", 0,
	"case", 0,
	"char", 0,
	"const", 0
};

int getword(char *, int);
struct key *binsearch(char*, struct key*, int);

int main(int argc, char **argv)
{
	char word[MAXWORD];
	struct key *p; /*存放查找方法返回的结构体指针, 该指针指向数组中查找到元素的下标*/

	while(getword(word, MAXWORD) != EOF)
		if(isalpha(word[0]))
			if((p = binsearch(word, key_count, KEYS)) != NULL)
				p->count++;

	for(p = key_count; p < key_count + KEYS; p++)
		if(p->count > 0)
			printf("%2d %s \n", p->count, p->word);

	return 0;
}

/*
 * 没有循环控制变量的 for 循环, 在内部通过条件 break
 */
int getword(char *word, int max)
{
	int c, getc(FILE*), ungetc(int, FILE*);
	char *wp = word;

	/*处理第一个字符, 第一个字符不是 空 不是 EOF 再进行下面的操作*/
	while(isspace(c = getc(stdin)));
	if(c != EOF)
		*wp++ = c;
	if(!isalpha(c))
	{
		*wp = '\0';
		return c;
	}

	/*循环接收字符串, 字符串接收到非标识符 或者 到达个数上限停止循环*/
	for(; --max > 0; wp++)
		if(!isalnum(*wp = getc(stdin)))
		{
			ungetc(*wp, stdin);
			break;
		}
	*wp = '\0';
	return word[0];
}

/*
 * 注意点 :
 *   取两个地址的中值 : 一个数组n个元素, 其中值计算 是由 首元素的首地址 和 尾元素的尾地址计算的
 *   二分查找 :
 *     如果要把区间前移, 那么就需要将尾地址设置为 中间元素前一个元素的尾地址, 即中间元素的首地址
 *     如果要把区间后移, 那么就需要将首地址设置为 中间元素后一个元素的首地址, 即中间元素 + 1 的地址
 *
 * 指向结构体数组的指针 :
 *   struct key tab * 是指向结构体数组指针, 该指针可以操作结构体数组
 */
struct key *binsearch(char *word, struct key *tab, int n)
{
	int cond;
	struct key *low = &tab[0];	/*0元素的首地址*/
	struct key *high = &tab[n];	/*尾元素的尾地址*/
	struct key *mid;

	while(low < high)
	{
		/*计算中间值的地址*/
		mid = low + (high - low) / 2;
		if((cond = strcmp(word, mid->word)) < 0)
			high = mid;	/*mid 是 中间元素前一个元素的尾地址*/
		else if(cond > 0)
			low = mid + 1; /*这里low要成为mid后一个元素的首地址*/
		else
			return mid;
	}
	return NULL;
}

执行结果

octopus@octopus-Vostro-270s:~/code/c/struct$ gcc pointer_struct.c
octopus@octopus-Vostro-270s:~/code/c/struct$ ./a.out
auto
case
auto
break
 2 auto
 1 break
 1 case 

(2) 结构体大小讨论

结构体数组指针算术运算 : struct key *p = word_count; 指针 p 指向 结构体数组, 如果 p + 1 , 结果是 p 地址 加上 结构体所占内存大小;

结构体大小 : 结构体的大小不是完全等于各个成员的长度之和, 对象之间有对齐要求;

-- 空穴 : 对象间对齐, 会产生空穴, 占有空间, 但是不存储数据;

示例 : 结构体中由一个 char 和 int , 占用的空间却是 8个字节, 它们的和是 5个字节;

/*************************************************************************
    > File Name: memory_struct.c
    > Author: octopus
    > Mail: octopus_work.163.com
    > Created Time: 2014年03月25日 星期二 12时55分45秒
 ************************************************************************/

#include<stdio.h>

struct word
{
	char c;
	int i;
};

int main(int argc, char **argv)
{
	printf("sizeof(struct word) = %d \n", sizeof(struct word));
	return 0;
}

执行结果

octopus@octopus-Vostro-270s:~/code/c/struct$ gcc memory_struct.c
octopus@octopus-Vostro-270s:~/code/c/struct$ ./a.out
sizeof(word) = 8

.

作者 : 万境绝尘

转载请注明出处 : http://www.hanshuliang.com/?post=30

.

【嵌入式开发】C语言 结构体相关 的 函数 指针 数组的更多相关文章

  1. C语言结构体中的函数指针

      这篇文章简单的叙述一下函数指针在结构体中的应用,为后面的一系列文章打下基础 本文地址:http://www.cnblogs.com/archimedes/p/function-pointer-in ...

  2. 对嵌入式开发C语言结构体的一点总结

    今天冬至居然不上班,公司的良心啊!这回有心情写博客和日志了,好了,废话不多说.直接看下文: 鉴于嵌入式开发过程中,C语言结构体的使用当然是必不可少.话说,基础什么的比你会更牛逼的算法更重要,基础不牢, ...

  3. C语言 结构体相关 函数 指针 数组

    . 作者 : 万境绝尘 转载请注明出处 : http://www.hanshuliang.com/?post=30 . 结构体概述 : 结构体是 多个 变量的集合, 变量的类型可以不同; -- 可进行 ...

  4. 复习C语言系列二:动态调用函数指针数组

    a:用call_fun_ptr调用afun(),b:用call_fun_ptr调用bfun() a 请输入给您指定的函数输调用的参数 afun_par ------------------------ ...

  5. 嵌入式开发—C语言面试题

    嵌入式开发—C语言面试题 源地址:http://blog.csdn.net/xdx2ct1314/article/details/7358929   1. 用预处理指令#define 声明一个常数,用 ...

  6. C#委托与C语言函数指针及函数指针数组

    C#委托与C语言函数指针及函数指针数组 在使用C#时总会为委托而感到疑惑,但现在总新温习了一遍C语言后,才真正理解的委托. 其实委托就类似于C/C++里的函数指针,在函数传参时传递的是函数指针,在调用 ...

  7. c语言.函数指针数组

    函数指针: 一个指向函数的指针.一般用函数名表示. 函数指针数组:元素为函数指针的数组.转移表.c语言中函数不可以定义为数组,只能通过定义函数指针来操作. #include<stdio.h> ...

  8. C语言结构体及typedef关键字定义结构体别名和函数指针的应用

    结构体(struct)的初始化 struct autonlist { char *symbol; struct nlist nl[2]; struct autonlist *left, *right; ...

  9. C语言 结构体中的零长度数组

    /* C语言零长度数组大小和取值问题 */ #include <stdio.h> #include <stdlib.h> #include <string.h> s ...

随机推荐

  1. iOS 用RunTime来提升按钮的体验

    用RunTime来提升按钮的体验 载请标明出处:http://blog.csdn.net/sk719887916/article/details/52597388,作者:Ryan 经常处理按钮问题都是 ...

  2. Android通过WebService实现图片的上传和下载(一)

    这篇文章将讲解Android如果通过访问WebService接口实现图片的上传和下载,当然这不但需要大家懂得Android还要懂得WebService技术,安卓属于客户端,而webservice则属于 ...

  3. RxJava(七) 使用debounce操作符 优化app搜索功能

    欢迎转载,转载请标明出处: http://blog.csdn.net/johnny901114/article/details/51555203 本文出自:[余志强的博客] 一.抛出问题 现在几乎所有 ...

  4. XMPP(二)-基于asmack+openfire的安卓客户端(仿QQ)的介绍以及个人心得

    关于XMPP第一篇-openfire的搭建写完后,就一直在赶本篇所要介绍的这个基于asmack+openfire的安卓客户端,费了不少精力,因为有不少同学在还在焦急的等待着(自恋了呵呵),所以紧赶慢赶 ...

  5. [virtualenv]生产环境中使用virtualenv

    virtualenv 对于python开发和部署都是好工具,可以隔离多个python版本和第三方库的版本,这里作者总结了几个常用python服务怎么样结合virtual部署 原文链接 Python 中 ...

  6. ubuntu16.04主题美化和软件推荐

    前几天把ubuntu从15.10更新到了16.10,在网上看到有很多直接更新出问题的,正好赶上换SSD,于是采用全新安装,之前用ubuntu的时候装软件最让人头疼了,这回又得头疼一次了!! 索性把他记 ...

  7. Cocos2D中Action的进阶使用技巧(一)

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 大家对Cocos2d中动作的使用大概都很清楚了,其实本身act ...

  8. Linux中printk()实例

    新建hello.c #include <linux/kernel.h> #include <linux/module.h> int init_module(void) { pr ...

  9. 概率论:假设检验-t检验和Augmented Dickey–Fuller test

    http://blog.csdn.net/pipisorry/article/details/51184556 T检验 T检验,亦称student t检验(Student's t test),学生t检 ...

  10. 任务执行器——Executor

    上节说到接收器Acceptor在接收到socket后会有一系列简单的处理,其中将socket扔进线程池是最重要的一步,线程池是一个怎样东西?其原理在前面的"线程池原理"章节已经说明 ...