攻克恐惧点---查漏补缺

前言

一段时间的编程学习发现,时间的大量投入不一定能带来预期的效果。意味的寻求更好的学习方式,视频,读书,敲代码,项目实践都有所尝试,效果也不见得是好的。究竟该怎么克服学习进度缓慢,或者转牛角尖而延误大局的情况? 
我对自己的学习过程进行了一个观察,发现有几点需要总结。
人的本性是懒惰的,所以在学习的过程中,不是投入时间多就是足够努力。愿意观察自己的学习状态并且找到需要【刻意训练】的知识是提升的关键。而懒惰的自己往往忽略了这点,得过且过。
知识盲区就在自己的恐惧之处,有些知识认为麻烦,凌乱,繁琐而不去单独的学习掌握,长此以往可能的结果就是始终都不会。而攻克自己的恐惧点可能才是学习的关键之处。

**你总想轻易跳过的部分,总是你害怕学习的部分,因为懒惰而逃避。**   

把害怕的东西罗列出来,作为恐惧点克服。

把自己做不好的事情,反复去做直到做好为止。

至少我认为九成的人类学习能力差异不大,关键在于使用正确的方法,投入适当的时间

2016/8/27


  1. Python Socket 网路编程 (构建一个简单的网络聊天室) 浏览器运行是怎样的过程。
    参考:网络聊天室

通过实现一个python socket 聊天程序来学习网络编程 。
程序最好在Linux上运行,windows上部分程序无法运行。

打算加上GUI界面的,但是没找到合适的python图形库,所以只有核心代码,来实现功能。

#客户端程序
import socket
import select
import string 
import sys

def prompt():
    sys.stdout.write('<You> ')
    sys.stdout.flush()

#main 
if __name__ == "__main__":

    if(len(sys.argv)< 3):
        print 'Usage: python telnet.py hostname port'
        sys.exit()

    host = sys.argv[1]
    port = int(sys.argv[2])

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(2)

    try:
        s.connect((host,port))
    except:
        print "Unable to connect"
        sys.exit()

    print "Connected to remote host. Start sending messages"
    prompt()

    while 1:
        socket_list = [sys.stdin,s]

        read_sockets,write_sockets,error_sockets = select.select(socket_list,[],[])

        for sock in read_sockets:

            if sock == s:
                data = sock.recv(4096)
                if not data:
                    print '\nDisconnected from chat server'
                    sys.exit()
                else:

                    sys.stdout.write(data)
                    prompt()

            else:
                msg = sys.stdin.readline()
                s.send(msg)
                prompt()

#服务器程序

import socket
import select 

def broadcast_data(sock, message):

    for sockett in CONNECTION_LIST:
        if sockett != server_socket and sockett != sock:
            try:
                sockett.send(message)
            except:
                sockett.close()
                CONNECTION_LIST.remove(sockett)

if __name__ == "__main__":

    CONNECTION_LIST = []
    RECV_BUFFER = 4096
    PORT = 5000 



    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    server_socket.bind(("0.0.0.0",PORT))
    server_socket.listen(10)

    CONNECTION_LIST.append(server_socket)

    print "Chat server started on port" + str(PORT)


while 1:

    read_sockets,write_sockets,error_sockets = select.select(CONNECTION_LIST,[],[],5)

    for sock in read_sockets:
        #New connection 
        if sock == server_socket:
            sockfd,addr = server_socket.accept()
            CONNECTION_LIST.append(sockfd)

            print "Client(%s, %s)connected"%addr 

            broadcast_data(sockfd,"[%s,%s]entered roomn"%addr)

        else:

            try:
                data = sock.recv(RECV_BUFFER)
                if data:
                    broadcast_data(sock, "r"+''+data)

            except:
                broadcast_data(sock,"Client(%s,%s)is offline "%addr)
                print "Client(%s,%s) is offline" %addr 
                sock.close()
                CONNECTION_LIST.remove(sock)
                continue 
        server_socket.close()

总结: 通过整个过程了解到socket 网络编程基本原理,没有想象的那么复杂。可以学习到了基本的对话聊天过程在网络中是如何实现的。



2.C语言进阶知识(细分如下)

 在C语言学习过程中,有些部分学习的时候接触比较少,能够使用到的机会不对,对于这部分知识掌握不够扎实。每次在实际应用的时候,遇到该部分知识都要去搜索别人的博客。所以在这里进行一个详细的总结,把自己C语言学习过程中的拦路虎都解决掉。

(一)数据类型与常量

1.基本数据类型:float,double,int,char,_Bool

2.C语言中任何单个字符,数字,字符串都被当做常量。

3.int 表示八进制数时,前面都有0, 输出的时候用%o (无0),%#o (有0)。

4.十六进制的时候,前面有0x,包含0-9 a-f, 输出时用%x(小写), %X (大写)。

5.整数、浮点数、字符数的存储都有存储范围,因计算机系统而定。

6.浮点数,想要用科学计数法表示的时候不妨用%g和%e。

7.除非特别说明,C语言所有的浮点型都默认double型处理,是float存储空间的二倍。如果需要float存储要特比加上f或F ,例如:12.5F

8.用_Bool可定义布尔变量为其赋值0或1,但为方便可加入#include < stdbool> 则布尔变量为bool ,值为True 或 False。

9.类型修饰符有:long, long long, short, unsigned ,signed
long int 表示长整型变量,很多系统中长整型变量和普通变量的范围是一样的32位。对应的数字后面加上L表示,输出显示的时候也在%ld 这样。

10.long long int a; 这样定义的数字最少占64位存储空间,输出则为%lld。

11.与long相反,short加在不同数据类型前面表示占用内存较小,可以节省内存。但不少于16位

12.long int 可以省略int

(二)循环 和 判断
1.C语言最多运行127层循环。

2.有时候很多算法我们注重的是实现他们,而不是理解他们的原理是怎么来的。

(三)数组
1.如果定义的时候没有明确规定数组长度,就按照最大下标算。例如:num[] = {[3] = 20, [7] = 30, [12] = 40} 表示长度为12

2.const 修饰的变量 在程序运行过程中不能被改变,提高程序可读性和安全性,编译器可以决定其放置在只读内存中。

(四)函数
1.函数定义时,包含谁能定义这个函数、函数返回值类型、函数的名字、函数的参数。

2.自动变量和静态变量,auto每次调用都被重新分配内存,不再访问的时候空间被收回,下次调用的时候里面的值会消失,重新赋值。而用static是静态变量,默认值是0,只在程序一开始的时候初始化一次,之后这个值保持不变。

(五)结构体

    struct date   //定义了一种新的数据类型  
    {
        int year;
        int month;
        int day;

    };
struct date today,yestoday;  //声明了两个该数据类型的变量

1.定义结构 和 声明一个结构变量之间的差别是: 前者不会分配内存,后者会为对应的变量分配空间。

2.复合字面量:给一个结构体多个成员变量赋值。

today = (struct date){9, 25, 2004};

3.结构的变形


    struct date   //定义了一种新的数据类型  
    {
        int year;
        int month;
        int day;

    }today,yestoday; //同时声明了两个该数据类型的变量 

如果已经声明完需要的全部变量,可以不写数据类型名date。

(六)字符串
1.const char word[] = {‘H’, ‘e’, ‘l’, ‘l’, ‘o’,’\0’}; 定义字符串变量,等价的代码还有:char word[] = {“Hello”}; 和 char word[] = “Hello”;
以及 char word[7] = {“Hello!”}; 这里长度包含结尾’\0’的空间,编译器会自动加上去。否则没有空间,且不会报错。

2.getchar() 和 scanf() 的区别在于前者只能读取一个字符,而且在使用的时候更加方便。而后者遇到 空白 时会停止读取。

3.gets() 用于读取一行文本

(七)指针
1.若x是一个变量,则&x 是x的指针。 int *p; p = &x;

2.结构体指针:

    struct date 
    {
        int month;
        int day;
        int year;
    }today;

    struct date *datePtr;

    datePtr = &today;  //指针指向结构体

    (*datePtr).day = 21; //用指针表示结构体的值

    datePtr->day = 21; //另一种方式表示结构体值

3.结构体中包含指针

    struct intPtrs
    {
        int *p1;
        int *p2;
    };

    struct intPtrs pointers;

    pointers.p1 = &i1;
    pointers.p2 = &i2;
    *pointers.p2 = -79; 

4.链表 中指针的应用:

`   n1.next = &n2;  //n1 n2链表进行连接起来
    n2.next = &n3;   //n2 n3 链表连接, 都赋予指针

    i = n1.next->value;` //给i赋予链表的成员值

5.链表的结尾要用NULL结束,n3.next = (struct entry *) 0;

6.const 和指针 :同样表示不能修改值,但是此处有两个注意,一是指针是否会被修改,二是指针所指的值是否会被修改。

    char *const charPtr = &c; //读法是charPtr是一个指向字符的指针常量 
    const char *charPtr = &c; //读法是charPtr指向一个字符常量 
    const char *const *charPtr = &c; //都不会不 变 

7.函数中用指针来实现对于数值的改变,参数传递值。

8.求一个数的负数,先对其求补然后减去1。n位最多可存储的范围是2(n-1次幂)至-2(n-1次幂)

9.各种类型的整数都可以用位运算,但是浮点型不能适用。

10.按位与用于保留某些位数,其他位清零。按位或用于将某些位设定为1,其他位清零。异或运算的有趣应用是不用存储单元的情况下高速交换两个值:

    temp = i1;  //一般这样进行交换 
    i1 = i2;
    i2 = temp; 

    i1 ^= i2;   //异或运算方法交换 
    i2 ^= i1;
    i1 ^= i2; 

11.记住按位与比按位或的运算级高,会影响运算结果的。~(~a & ~b) 等价于 a | b,~( ~a | ~b ) 等价于 a & b

12.左移以为相当于乘以2, 大多数计算机上左移操作比乘法操作快得多。

13.位域可以用来节省存储空间,比如用来标记的布尔值,其实可以只保存在一个单独的位中,而不必重新定义变量。实现这个功能有两种方法:一、像前面一样用与运算保留需要的位。二、通过位域实现一个打包信息的结构体。
一、把所有需要的变量位的和得到,定义一个单独的变量,其上的不同位可以分别表示不同的变量值。大大节省空间。
二、通过位域实现结构体:

    struct date{
        int day:16;    //只有16位  多出的没法保存
        int month:16;
        int year:32;
    };

(八)预处理器 + 预处理语句
1.C语言中使用宏的好处是不用考虑类型,使用宏还要比使用函数快一点。

2.宏定义只是简单的文本替换,有时候不是我们想要的结果,需要加上小括号来保证结果正确。

3.字符转换函数islower()和toupper()

4.#define printint(var) printf(#var “= %d\n” , var)

5.## 作用是把左右的量合并起来 如 【X ## 2】就是 【X2】

6.

    #ifdef UNIX
    #define DATADIR "/aa/data"
    #else
    #define DATADIR "\aa\data"
    #endif 

8.取消一个预先定义的宏 :#undef name
(九)数据类型
1.枚举类型 enum color{ red, blue, green}; 编译器为其中赋初值 0,1,2
然后 enum newcolor; newcolor只能从0,1,2中选取。

2.typedef 的使用:给数据类型起一个不同的名字

typedef int Counter;  //该符号与int等价
typedef char Linebuf[81]; //
Linebuf  a,b;

/*等价于*/
char a[81], b[81];

typedef char *StringPtr; //字符指针 

使用步骤:
1.写出声明变量的正常方法
2.变量名用新类型名替换
3.前面加上typedef

用例:

typedef struct{
    float x;
    float y;
}Point;   //换成点类型表示

Point origin = {0.0, 0.0}; //原点 

未完。。。 (C语言部分)
/***************************/

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值