相信函数大家都比较熟悉了,这里就是简单的记录一点。
def greet_user(username):
""" 显示简单语句"""
print("hello, " + username.title() + ".")
greet_user('yubo')
上面就是简单的一个函数原型和调用的方法。首先,python定义函数需要关键词def表明这是一个函数定义。后面紧接着是函数名称,括号里面是形参,你可以简单的理解为参数。参数就是你需要处理的数据,它可有可无,这个不是必须的。按照python的语法结构,这个语法块就是一个整体,不可分割。一般的函数还有返回值,这个函数显性没有返回值,但是它会向调用者打印一串字符串
# 默认值, 比如,上面的用法就是可以这样的:
def greet_user(username = 'yubo'):
...
# 实参变成可选的,下面这个函数有三个参数,这样的话,你的形参不可缺少
def get_formatted(first_name, middle_name, last_name):
""" 返回全名"""
full_name = first_name + ' ' + middle_name + ' ' + last_name;
return full_name.title()
name = get_formatted('bo', 'zi', 'bo')
print(name)
### 将参数用空值符表示出来,同时判断条件
def get_formatted(first_name, last_name, middle_name = ''):
if middle_name:
full_name = first_name + ' ' + middle_name + ' ' + last_name
else:
full_name = first_name + ' ' + last_name
return full_name.title()
name_1 = get_formatted('Bo', 'yu')
name_2 = get_formatted('bo', 'yu', 'zi')
print(name_1)
print(name_2)
# 看下面的这个函数,有意思
def get_formatted(first_name, last_name):
full_name = first_name + ' ' + last_name
return full_name.title()
while True:
print("\n Please input your name\n")
print("enter 'q' to quit the exam:\n")
f_name = raw_input("First name:")
if f_name == 'q':
break
l_name = raw_input("Last name:")
if l_name == 'q':
break
formatted = get_formatted(f_name, l_name)
print(formatted)
# 传递列表
def greet_user(names):
for name in names:
print("Hello, " + name.title() + "!")
name_list = ['yubo', 'hechun','xiaoxiao']
greet_user(name_list)
# 在函数中修改列表
def print_list(unprinted_designs, complete_models):
""" 模拟打印每个设计,直到没有未打印的设计为止"""
while unprinted_designs:
current_design = unprinted_designs.pop()
# 模拟根据设计制作3D打印
print("Printing model: " + current_design)
complete_models.append(current_design)
def show_list(complete_models):
""" 显示打印好的模型"""
print("\n The following models have been printed")
for complete_model in complete_models:
print(complete_model)
unprinted_designs = ['iphone', 'robot', 'winphone']
complete_models = []
print_list(unprinted_designs, complete_models)
show_list(complete_models)
# 禁止函数修改列表,则要将列表的副本传递给函数,比如,上面的例子:
print_list(unprinted_designs[:], complete_models)
# 不过,你除非有充足的理由这样做,否则这样会花时间和内存创建副本,
#这样会影响效率
# 向函数传递任意多的参数, 需要在形参名字前面加上星号(*)
def make_pizza(*topping):
print(topping)
""" 当然,实参位置还是需要注意的"""
make_pizza('yubo')
make_pizza('hechun', 'xiaoxiao')
# 使用任意数量的关键字实参
def build_profile(first, last, **user_info):
"""创建一个字典, 其中包含我们知道的一切"""
profile = {}
profile['first_mane'] = first;
profile['last_name'] = last;
for key, value in user_info.items():
profile[key] = value
return profile
user_profile = build_profile('bo', 'yu',
location = 'Qingdao', phone = '123')
print(user_profile)
列表的基本操作。
比如构造一个1、3、5、7...的列表,使用什么方法呢。这是比较笨的方法。
L = []
i = 1
while i <= 99:
L.append(i)
i = i + 2
print (L)
# or
j = 1
k = 0
while j <= 99:
L[k] = j
j = j + 2
k = k + 1
print (L)
效果虽然一样,但是还是有点问题的。问题之一就是效率,写的太啰嗦了。
切片就是在列表中,以下标的方式读取元素的方法。举个例子
L = ["1",'2', '3', '4']
print L[0:2] # 打印从第0个到第2个的元素
# 等价于
print L[:2]
# 还可以
print L[1:2] # 从第1个元素到第2个元素
# 还可以
print L[-1] # 这个打印的是倒数第一个元素 4
请看下面的例子:
>>> l = ['1','2','3','4']
>>> print l[-1]
4
>>> print l[:-1] # 从正数第一个取到倒数第一个(但是并不会取到)。
['1', '2', '3']
>>> print l[-1:] # 从倒数第一个取,取到最后,只有他自己
['4']
>>> print l[-3 :-1] # 从倒数第一取到倒数第1,
['2', '3']
>>> print l[-2:] # 从倒数第2取到最后
['3', '4']
>>>
首先新建一个包含100个元素的列表。
>>> yubo = list(range(100))
>>> print (yubo)
详情可以参考注释。
>>> hechun = ['yubo','hehe','haha']
>>> print (hechun)
['yubo', 'hehe', 'haha']
>>> hechun.append(123)
>>> print (hechun)
['yubo', 'hehe', 'haha', 123]
# 在指定位置插入元素
>>> hechun.insert(1, 'csl')
>>> print (hechun)
['yubo', 'csl', 'hehe', 'haha', 123]
# 删除指定元素,其元素已不在list中
>>> del hechun[1]
>>> print (hechun)
['yubo', 'hehe', 'haha', 123]
# 使用pop方法,并可以继续访问这个值
>>> tmp = hechun.pop()
>>> print (tmp) #默认是最后一个元素
123
>>> tmp = hechun.pop(0) #可以指定元素位置
>>> print (tmp)
yubo
>>> print (hechun)
['hehe', 'haha', '123']
>>> hechun.remove('haha')
>>> print (hechun)
['hehe', '123']
这里有排序、打印、长度等操作
# 排序
>>> print (hechun)
['hehe', '123']
>>> hechun.sort()
>>> print (hechun)
['123', 'hehe']
#反序
>>> hechun.sort(reverse=True)
>>> print (hechun)
['hehe', '123']
#使用sorted()可以保存原来列表的内容,你可以将新的列表
#复制给新的列表
### 倒序打印列表
>>> print (hechun)
['hehe', '123']
>>> hechun.reverse()
>>> print (hechun)
['123', 'hehe']
操作列表,就是在列表上执行某一特定操作。
# 复制A,全复制
# 你对原列表的改动,可以影响复制后的列表
>> yubo = ['123','hello','world']
>>> hechun = yubo
>>> yubo.append('456')
>>> print (yubo)
['123', 'hello', 'world', '456']
>>> print (hechun)
['123', 'hello', 'world', '456']
# 复制列表,但对于复制后的不影响
>>> test = yubo[:]
>>> print (yubo)
['123', 'hello', 'world', '456']
>>> yubo.append('789')
>>> print (yubo)
['123', 'hello', 'world', '456', '789']
>>> print (test)
['123', 'hello', 'world', '456']
字典里面可以储存更多的信息,理解它后,你就可以更加准确的为各种真实物体建模了。字典是一系列键-值对,
# 访问元素
>>> alien_0 = {'color': 'green','point':5}
>>> ptinr(alien_0['color'])
>>> print(alien_0['color'])
green
# 加入有这么一个游戏,是你现在获得的point
# 注意str函数,这是将列表、元组或者字典里面的字符转化为字符串
>>> new_point = alien_0['point']
>>> print("You just earned" + str(new_point) + "points!" )
You just earned5points!
# 添加元素,注意,字典添加元素使用[]添加进去的
>>> alien_0['x_position'] = 0
>>> alien_0['y_position'] = 25
>>> print(alien_0)
{'color': 'green', 'y_position': 25, 'x_position': 0, 'point': 5}
# 修改某一键值
>>> alien_0['color'] = 'yellow'
>>> print(alien_0)
{'color': 'yellow', 'y_position': 25, 'x_position': 0, 'point': 5}
# 删除键, 注意,永远消失
>>> del alien_0['point']
>>> print(alien_0)
{'color': 'yellow', 'y_position': 25, 'x_position': 0}
# 遍历字典 items()
>>> alien_0.items()
[('color', 'yellow'), ('y_position', 25), ('x_position', 0)]
#使用for, 分别得到键、值.注意,对于数值型的字符,注意转换
>>> for attr, value in alien_0.items():
... print("\n attr: " + attr)
... print("\n value: " + str(value))
...
attr: color
value: yellow
attr: y_position
value: 25
attr: x_position
value: 0
# 只得到键, 实际上,它得到一个列表
>>> for value in alien_0.keys():
... print(str(value))
...
color
y_position
x_position
#只得到值,返回一个列表
for value in alien_0.values():
# 多个字典在一个字典中
# 注意这里,将三个字典放入一个字典中,使用列表包围起来
alien_0 = {'color': 'green', 'point':5}
alien_1 = {'color': 'yellow','point':10}
alien_2 = {'color':'red', 'point': 15}
aliens = [alien_0, alien_1, alien_2]
print(alines)
# 字典里储存列表
pizza = {
'crust': 'thick',
'toppings': ['mushroom', 'extra sheese'],
}
print("You ordered a " + pizza['crust'] + "-crust pizza" +
" with the following the topping:")
for topping in pizza['toppings']:
print("\t" + topping)
# 再看一个简单的例子
favorite_languages = {
'yubo' : ['c,','python'],
'hechun' : ['math', 'c', 'shell'],
'hecheng' : ['shell'],
}
for name, language in favorite_languages.items():
print("Person's name is " + name.title())
for lan in language:
print("\t" + str(lan) + " ")
# 字典里面嵌套字典
下面这段代码综合利用了上面的知识:
# 注意字典的这样输入法
favorite_languages = {
'yubo': 'pytthon',
'hechun': 'math',
'xiaoxiao': 'c',
}
friends = ['yubo', 'hechun']
# 可以使用sorted(favorite_languages.keys())进行排序后的输出
for name in favorite_languages.keys():
print(name.title())
if name in friends:
print(" Hi " + name.title() +
", i see you favorite languages is " +
favorite_languages[name].title() + "!")
用户输入填充字典, 有些东西需要raw_input()函数实现。
responses = {}
polling_active = True
while polling_active:
name = raw_input("\n What is your name? ")
response = raw_input("Which mountain would you like to climb someday?")
# 将答案存在字典中, 我自己这里写错了
responses[name] = response
# 看看是否还有其他人参与调查问卷
repeat = raw_input("Would you like to let another people response?")
if repeat == 'no':
polling_active = False
print("\n-----[pull]-------\n")
for person ,mount in responses.items():
print(person + " Would like to climb " + mount + ".")
这篇文章从内核的角度来看ICMP的,现在,ping命令就是利用icmp实现的。
首先看一个大概。
```c
/*
*/
#include
#define MAX_WAIT_TIME 5 #define MAX_NO_PACKETS 3 #define PACKET_SIZE 4096 char sendpacket[PACKET_SIZE]; char recvpacket[PACKET_SIZE];
#1 普通文件
在写c语言的程序中,我们随手丢上了一个
至少在我的系统上(debian - 9),只要像上面没有前缀的c库头文件,默认位置存储在
/usr/include/*
上面*是为了md文件的显示好看,自己输入的时候只需要一个*.
ls /usr/include/st
stab.h stdint.h stdio.h string.h stropts.h
stdc-predef.h stdio_ext.h stdlib.h strings.h
看,有你熟悉的文件吗?
#2.有前缀的<sys/socket.h>
这个文件在编写unix网络程序的时候,是必须用到的文件之一,那么,这个文件位于哪里?记住,首先这种文件位于/usr/include/目录下。
使用命令查找一下就可以了。
find /usr/include/ -name socket.h
在我的系统上显示了如下的内容:
yubo@debian:~$ find /usr/include/ -name socket.h
/usr/include/linux/socket.h
/usr/include/asm-generic/socket.h
/usr/include/x86_64-linux-gnu/bits/socket.h
/usr/include/x86_64-linux-gnu/sys/socket.h
/usr/include/x86_64-linux-gnu/asm/socket.h
那么,从头文件上来看,上面第4个文件符合我的目的。
好了,有了以下内容,请看一下下面的头文件:
#include <stdio.h>
#include <signal.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <stdlib.h>
#include <netdb.h>
#include <setjmp.h>
#include <errno.h>
其实这里面还涉及到一个glibc的问题,我们有时间再讲这方面的内容,
用法: 在变量定义之前如果使用该变量,则在使用之前加上extern关键词,作用域从声明开始,到本文件结束。但有一点注意,还得定义一遍,只不过前面加上了关键词。
#include <stdio.h>
int mysum(int x, int y);
int main(int argc, char *argv[])
{
int result;
extern int x; /* 这里的类型名字可以去掉,但是会有警告产生 */
extern int y;
result = mysum(x, y);
printf("The max number is %d\n", result);
return 0;
}
int x = 10;
int y = 15;
int mysum(int x, int y)
{
return x + y;
}
如果整个工程由多个文件组成,在一个文件中可以引用另外一个文件中已经定义的外部变量时,则只需使用关键字extern加以声明即可,可见,这时的变量作用域从一个文件扩展到了多个文件。
测试的例子:
a.c:
#include <stdio.h>
extern int mysum(int x, int y);
int main(int argc, char **argv)
{
int result = mysum(1, 3);
printf("Here, our result from extern mysum is %d\n", result);
}
b.c
int mysum(int x, int y);
int x = 10;
int y = 15;
int mysum(int x, int y)
{
return x + y;
}
注意编译的命令为: gcc a.c b.c -o test
还有利用这种方法去定义接口,在上面的例子中就是a.c中,再一次定义一个变量,在b.c中,使用extern关键字来声明变量即可,然后因为你在a.c中调用的函数,所以你就可以改变传递给函数的参数了。
那么,这种方法与通过函数形参传递变量的区别在哪里?如果仅仅是传值,估计是起不到作用的,你会想到传地址的方法,这样可以,但是在一个大型项目中,可能有很多程序同时调用函数,这里就会涉及到竞态的问题。使用extern的方式就比较安全。
我一开始也有误解,现在看来,结构体的有些不同。
a.c :
#include<stdio.h>
#include "b.h"
#include "c.h" /*引入 print() */
A_class local_post = {1, 2, 3};
A_class next_post = {4,5,6};
int main(int argc, char **argv)
{
A_class ret;
print("first point", local_post);
print("second point", next_post);
ret = function(local_post, next_post);
printf("The vector is (%d %d %d)\n", ret.x, ret.y, ret.z);
printf("Or print with function(print) from c.h:\n");
print("After two array", ret);
return 0;
}
b.c
#include<stdio.h>
#include "b.h"
/* 配合b.h,*/
A_class function(A_class first, A_class next)
{
A_class ret;
ret.x = next.x - first.x;
ret.y = next.y - first.y;
ret.z = next.z - first.z;
return ret;
}
b.h:
#ifndef __B_H
#define __B_H
#if 1
typedef struct {
int x;
int y;
int z;
} A_class;
#endif
extern A_class local_post; /* 外部结构体声明*/
extern A_class function(A_class x, A_class y); /* 接口函数声明*/
#endif
c.c
#include<stdio.h>
#include "b.h"
int print(char *str, A_class post)
{
printf("%s: (%d, %d, %d)\n", str, post.x, post.y, post.z);
return 0;
}
c.h
#ifndef __C_H
#define __C_H
extern int print(char *, A_class post);
#endif
之所以还贴这么多代码,主要是觉得这个例子在内核中大量存在。除了extern关键字外,还有预定义符号,多复习。
#4 用extern声明函数 记住两点:
定义函数时,需要声明函数值返回值为extern,表示这个函数是外部函数,可以供外部文件使用。
调用函数事,也要使用extern关键字。
代码就先不贴了。
First :
libmnl: libnftnl libmnl: git://git.netfilter.org/libmnl libnftnl: git://git.netfilter.org/libnftnl
./autogen.sh
./configure
make
make install
ldconfig
If you have error as below:
./configure: line 3960: syntax error near unexpected token `LIBMNL,'
./configure: line 3960: `PKG_CHECK_MODULES(LIBMNL, libmnl >= 1.0.0)'
please refer to here:
http://blog.anarey.info/2014/08/pkg_check_moduleslibmnl-libmnl-1-0-0-error/