<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[wlli1985的博客]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/wlli1985</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; wlli1985]]></copyright><item><title><![CDATA[Linux网络驱动示例之snull网络接口(三)：测试验证]]></title><link>https://blog.youkuaiyun.com/wlli1985/article/details/103877334</link><guid>https://blog.youkuaiyun.com/wlli1985/article/details/103877334</guid><author>wlli1985</author><pubDate>Tue, 07 Jan 2020 17:06:40 +0800</pubDate><description><![CDATA[1. 编译得到.ko文件后用insmod snull.ko添加模块；

2. 在/etc/networks中添加网络号：
  snullnet0  192.168.0.0
  snullnet1  192.168.1.0

3. 在/etc/hosts中添加主机IP号：
192.168.0.1 local0
192.168.0.2 remote0
192.168.1...]]></description><category></category></item><item><title><![CDATA[Linux网络驱动示例之snull网络接口(二)：设备方法的实现]]></title><link>https://blog.youkuaiyun.com/wlli1985/article/details/103874322</link><guid>https://blog.youkuaiyun.com/wlli1985/article/details/103874322</guid><author>wlli1985</author><pubDate>Tue, 07 Jan 2020 16:33:55 +0800</pubDate><description><![CDATA[上一节描述了snull网络接口的入口和出口函数，在入口函数分配一个net_device，用snull_init函数初始化net_device的成员，之后注册这个网络设备。初始化net_device成员主要是实现一些设备操作方法，如下所示：


static const struct net_device_ops snull_dev_ops = {
    .ndo_open = s...]]></description><category></category></item><item><title><![CDATA[Linux网络驱动示例之snull网络接口(一)：总体框架]]></title><link>https://blog.youkuaiyun.com/wlli1985/article/details/103852484</link><guid>https://blog.youkuaiyun.com/wlli1985/article/details/103852484</guid><author>wlli1985</author><pubDate>Mon, 06 Jan 2020 16:33:00 +0800</pubDate><description><![CDATA[《Linux设备驱动程序》(第三版)第十七章以snull网络接口为例讲解了网络驱动程序的设计，本文分析了snull这个示例，并对驱动程序做了一些简化和修改，只保留该程序的核心功能，并在2.6.31版本的内核上测试运行。

1. 入口和出口函数

    Linux网络设备驱动基本是围绕net_device这个结构做文章，程序的入口函数中主要是分配并注册net_device结构体，对...]]></description><category></category></item><item><title><![CDATA[Linux设备驱动并发控制的简单总结]]></title><link>https://blog.youkuaiyun.com/wlli1985/article/details/103024955</link><guid>https://blog.youkuaiyun.com/wlli1985/article/details/103024955</guid><author>wlli1985</author><pubDate>Tue, 12 Nov 2019 13:05:20 +0800</pubDate><description><![CDATA[设备驱动中并发控制的常用机制：中断屏蔽，原子操作，自旋锁，互斥量。

1. 中断屏蔽：
  Linux的进程调度都使用中断实现，屏蔽中断也就屏蔽了内核抢占引起的并发问题，但是中断屏蔽只针对本CPU，不能解决多 个CPU引起的竞争。
  local_irq_disable();     //屏蔽中断
  local_irq_enable();     //开中断
...]]></description><category></category></item><item><title><![CDATA[C++   Primer(第五版) 7.4--7.6节练习]]></title><link>https://blog.youkuaiyun.com/wlli1985/article/details/102737836</link><guid>https://blog.youkuaiyun.com/wlli1985/article/details/102737836</guid><author>wlli1985</author><pubDate>Fri, 25 Oct 2019 12:56:53 +0800</pubDate><description><![CDATA[7.33  pos位于类的作用域之外，无法直接使用，应改为Screen::pos。

7.34  放在最后一行无法通过编译，声明中使用的名字，包括返回类型和参数列表使用的名字，都必须在使用前确保可见。

7.35 


typedef string Type;
Type iniVal();    //Type为string
class Exercise {
public:
    t...]]></description><category></category></item><item><title><![CDATA[C++   Primer(第五版) 7.3.1--7.3.4节练习]]></title><link>https://blog.youkuaiyun.com/wlli1985/article/details/102720732</link><guid>https://blog.youkuaiyun.com/wlli1985/article/details/102720732</guid><author>wlli1985</author><pubDate>Thu, 24 Oct 2019 14:49:40 +0800</pubDate><description><![CDATA[7.23 


#ifndef	SCREEN_H
#define	SCREEN_H

class Screen {
public:
	using pos = std::string::size_type;
	Screen() = default;
	Screen(pos ht, pos wd): height(ht), width(wd), contents(ht * wd, ' ') { ...]]></description><category></category></item><item><title><![CDATA[C++   Primer(第五版)7.2--7.2.1节练习]]></title><link>https://blog.youkuaiyun.com/wlli1985/article/details/102719998</link><guid>https://blog.youkuaiyun.com/wlli1985/article/details/102719998</guid><author>wlli1985</author><pubDate>Thu, 24 Oct 2019 11:56:52 +0800</pubDate><description><![CDATA[7.16  访问说明符指定其后成员的访问级别，其出现次数没有严格规定，有效范围直到出现下一个访问说明符或到达类结尾。可在整个程序内被访问的成员定义为public的；只能被类的成员函数访问，不能被使用该类的代码访问，定义为private的。

7.17  默认访问权限不同，struct所有成员是public的，class所有成员是private的。

7.18  封装可以隐藏类的实现细节...]]></description><category></category></item><item><title><![CDATA[C++   Primer(第五版)7.1.4节练习]]></title><link>https://blog.youkuaiyun.com/wlli1985/article/details/102719332</link><guid>https://blog.youkuaiyun.com/wlli1985/article/details/102719332</guid><author>wlli1985</author><pubDate>Thu, 24 Oct 2019 11:30:53 +0800</pubDate><description><![CDATA[7.11  添加构造函数


struct Sales_data {
	Sales_data()= default;
	Sales_data(const string &amp;s): bookNo(s) { }
	Sales_data(const string &amp;s, unsigned n, double p): 
				bookNo(s), units_sold(n), reve...]]></description><category></category></item><item><title><![CDATA[C++ Primer(第五版) 7.1.1--7.1.3节练习]]></title><link>https://blog.youkuaiyun.com/wlli1985/article/details/102676764</link><guid>https://blog.youkuaiyun.com/wlli1985/article/details/102676764</guid><author>wlli1985</author><pubDate>Tue, 22 Oct 2019 10:45:44 +0800</pubDate><description><![CDATA[7.1  Sales_data类：


#ifndef	SALES_DATA_H
#define	SALES_DATA_H

#include &lt;iostream&gt;
#include &lt;string&gt;

using namespace std;

struct Sales_data {
	string bookNo;
	unsigned units_sold = 0;
...]]></description><category></category></item><item><title><![CDATA[C++ Primer(第五版) 6.6--6.7节练习]]></title><link>https://blog.youkuaiyun.com/wlli1985/article/details/102623175</link><guid>https://blog.youkuaiyun.com/wlli1985/article/details/102623175</guid><author>wlli1985</author><pubDate>Fri, 18 Oct 2019 12:46:18 +0800</pubDate><description><![CDATA[6.49  函数匹配时，对应的重载函数集称为候选函数；考察提供的实参，候选函数中能够被这组实参调用的函数，叫做可行函数。

6.50  (a) 二义性调用，无法匹配；
     (b) 精确匹配void f(int);
     (c) 精确匹配void f(int, int);
     (d) 精确匹配void f(double, double);
...]]></description><category></category></item><item><title><![CDATA[C++ Primer(第五版) 6.5.1--6.5.3节练习]]></title><link>https://blog.youkuaiyun.com/wlli1985/article/details/102621495</link><guid>https://blog.youkuaiyun.com/wlli1985/article/details/102621495</guid><author>wlli1985</author><pubDate>Fri, 18 Oct 2019 12:05:07 +0800</pubDate><description><![CDATA[6.40  (b) 错误，ht被赋予默认值，则其后的所有形参都必须有默认值。

6.41  (a) 非法，至少要提供第一个参数；
     (b) 合法；
     (c) 合法，但不符合预期，'*'被传递给第二个参数。

6.42 


#include &lt;iostream&gt;

using namespace std;

string make...]]></description><category></category></item><item><title><![CDATA[C++ Primer(第五版)6.3.2--6.4节练习]]></title><link>https://blog.youkuaiyun.com/wlli1985/article/details/102619537</link><guid>https://blog.youkuaiyun.com/wlli1985/article/details/102619537</guid><author>wlli1985</author><pubDate>Fri, 18 Oct 2019 10:49:05 +0800</pubDate><description><![CDATA[6.30  1)for循环中的return没有返回值，编译器报错；
     2)for循环之后没有return语句，编译器无法发现这一错误。

6.31  当引用绑定的是函数的局部变量时，返回的引用或常量引用都是无效的。

6.32  合法。功能是把数组按照其索引号赋值。get函数接受一个数组指针和索引号为参数，返回数组该元素的引用，然后在main函数的for循环中赋值。...]]></description><category></category></item><item><title><![CDATA[C++ Primer(第五版)6.2.4--6.2.6节练习]]></title><link>https://blog.youkuaiyun.com/wlli1985/article/details/102603284</link><guid>https://blog.youkuaiyun.com/wlli1985/article/details/102603284</guid><author>wlli1985</author><pubDate>Thu, 17 Oct 2019 12:25:23 +0800</pubDate><description><![CDATA[6.21 


int cmp(const int a, const int *p)
{
	return (a &gt; *p)? a : *p;
}


6.22 


#include &lt;iostream&gt;

using namespace std;

void myswap(int *&amp;p1, int *&amp;p2)
{
	auto temp = p1;
...]]></description><category></category></item><item><title><![CDATA[C++ Primer(第五版)6.2.1--6.2.3节练习]]></title><link>https://blog.youkuaiyun.com/wlli1985/article/details/102580687</link><guid>https://blog.youkuaiyun.com/wlli1985/article/details/102580687</guid><author>wlli1985</author><pubDate>Thu, 17 Oct 2019 11:34:55 +0800</pubDate><description><![CDATA[6.10 


#include &lt;iostream&gt;

using namespace std;

void iswap(int *a, int *b)
{
	int temp = *a;
	*a = *b;
	*b = temp;
}

int main()
{
	int a = 1, b = 2;
	cout &lt;&lt; a &lt;&lt; " " &lt;&lt;...]]></description><category></category></item><item><title><![CDATA[C++ Primer(第五版) 6.1--6.1.3节练习]]></title><link>https://blog.youkuaiyun.com/wlli1985/article/details/102579128</link><guid>https://blog.youkuaiyun.com/wlli1985/article/details/102579128</guid><author>wlli1985</author><pubDate>Wed, 16 Oct 2019 10:16:21 +0800</pubDate><description><![CDATA[6.1  函数定义中的参数是形参；调用函数时所用的参数为实参。实参是形参的初始值。

6.2  (a) 函数定义的返回值为int，函数体中返回值为string，不匹配；
    (b) 缺少返回类型；
    (c) 形参名字重复；
    (d) 缺少花括号。

6.3 


int fact(int val)
{
	if (val &gt; 1)
	...]]></description><category></category></item><item><title><![CDATA[C++ Primer(第五版) 5.4.1--5.6.3节练习]]></title><link>https://blog.youkuaiyun.com/wlli1985/article/details/102561471</link><guid>https://blog.youkuaiyun.com/wlli1985/article/details/102561471</guid><author>wlli1985</author><pubDate>Tue, 15 Oct 2019 12:12:43 +0800</pubDate><description><![CDATA[5.14 


#include &lt;iostream&gt;
#include &lt;vector&gt;

using namespace std;

//统计单词及次数的数据结构
struct wcnt {
	string word;
	int cnt;
};

int main()
{
	string word;
	vector&lt;string&gt; svec;
	
	w...]]></description><category></category></item><item><title><![CDATA[C++ Primer(第五版) 5.1--5.3.2节练习]]></title><link>https://blog.youkuaiyun.com/wlli1985/article/details/102541339</link><guid>https://blog.youkuaiyun.com/wlli1985/article/details/102541339</guid><author>wlli1985</author><pubDate>Mon, 14 Oct 2019 10:49:04 +0800</pubDate><description><![CDATA[5.1  只有一个单独分号的语句是空语句；当语法需要但逻辑上不需要时用到空语句；

5.2  复合语句也被称作块，是指用花括号括起来的语句和声明序列；语法上需要一条语句，但逻辑上需要多条语句，应该用到块。

5.3  while (val &lt;= 10)
       sum += val,++val;  //可读性降低

5.4  (a) 非法，iter...]]></description><category></category></item><item><title><![CDATA[C++ Primer(第五版)4.9--4.11.3节练习]]></title><link>https://blog.youkuaiyun.com/wlli1985/article/details/102514354</link><guid>https://blog.youkuaiyun.com/wlli1985/article/details/102514354</guid><author>wlli1985</author><pubDate>Sat, 12 Oct 2019 11:00:17 +0800</pubDate><description><![CDATA[4.28 


#include &lt;iostream&gt;

using namespace std;

int main()
{
	cout &lt;&lt; "char: " &lt;&lt; sizeof(char) &lt;&lt; endl;
	cout &lt;&lt; "short: " &lt;&lt; sizeof(short) &lt;&lt; endl;
	co...]]></description><category></category></item><item><title><![CDATA[C++ Primer(第五版) 4.5--4.8节练习]]></title><link>https://blog.youkuaiyun.com/wlli1985/article/details/102494662</link><guid>https://blog.youkuaiyun.com/wlli1985/article/details/102494662</guid><author>wlli1985</author><pubDate>Fri, 11 Oct 2019 11:29:45 +0800</pubDate><description><![CDATA[4.17  前置版本：先将运算对象加1，将改变后的对象作为求值结果；后置版本：将运算对象加1，但求值结果是运算对象改变之前的那个值的副本。

4.18  使用前置，pbeg先加1，再解引用，无法输出第一个元素，而且最后会越界。

4.19  (a)先判定ptr是否有效，有效则判定ptr指向的值是否为0，并递增ptr；
     (b)先判定ival是否为0，非0则继续检查(...]]></description><category></category></item><item><title><![CDATA[C++ Primer(第五版) 4.1.2--4.4节练习]]></title><link>https://blog.youkuaiyun.com/wlli1985/article/details/102475846</link><guid>https://blog.youkuaiyun.com/wlli1985/article/details/102475846</guid><author>wlli1985</author><pubDate>Thu, 10 Oct 2019 11:08:32 +0800</pubDate><description><![CDATA[4.1  105

4.2  (a)  *(vec.begin())shiyong
    (b)  (*(vec.begin())) + 1

4.3  两个准则可以避免缺陷：
    1.  不确定求值顺序时使用括号；
    2.  如果改变了某个对象的值，在表达式其他地方不要再使用这个对象，例外：改变运算对象的子表达式本身是另外一个...]]></description><category></category></item></channel></rss>