学习编程的几点看法

yy_galois
学习编程的几点看法

很多人开始学习一种编程语言,典型的比如C语言,在学习到一定程度以后,比如已经能够熟练应用if else, while , for 等等语句编写程序解决简单的逻辑智力题等等,学着学着突然迷茫了,不知道C语言有什么作用。同样的,在学习Java的时候,心血来潮,把《thinking in  Java》从头到位学习了一遍,把上面的练习题全做了一遍,不可谓不刻苦。但是学习完以后,也迷茫了。不知道能用Java做点啥。

进一步的,听到有高手说算法,数据结构很重要,于是又苦读一番算法的书。又听到有高手说Linux内核开源,学会了感觉如何如何酷,于是心痒痒又钻研一番Linux内核源代码。结果愣是啥也没学会。程序没编出几个来,自己感觉自己啥都懂一点,但是啥也不会。也许还继续看看网络编程第二卷,捣鼓捣鼓socket。等等。

看看招聘广告,一般都是这样的。精通C/C++,精通XX数据库,熟悉TCP/IP网络协议..扪心自问,我C++只懂得一些类的概念,C++只编写过几个练习题。C,我倒是很熟悉,但是别人问我精通不,我自己也没底。面试的时候没底气,工作的时候没自信。


其实,这主要是有一个概念没有分清楚。不清楚什么叫做业务,什么叫做手段。


比如,一个人做usb相关的开发,usb的相关知识就叫做业务知识。虽然USB的实现大多是C语言实现,但是那些知识不叫做C语言的知识,C语言只是实现USB相关协议的一种手段。 也可以使用C++, Java或者其它语言来实现。

又比如做路由协议,你要懂路由协议相关的知识。 同样它大多是用C语言实现的。但是这些协议知识,无穷无尽的RFC,都是业务知识。

比如你想自己写一个FTP工具,FTP以及相关的只是就变成了业务知识,至于你想采用C,C++或者其它来实现,那只是一种手段。看你的熟悉程度和业务的需要等具体情况。

知道了这点,应该知道什么叫做懂得C语言了吧。能够一个小时内独立编写一个找出两个字符串的最大子字符串的程序,那么你的C语言就入门了。因为你已经能够熟练的应用if else, while语句,同样,能够编程实现如下这道逻辑推理题,那么你应该知道如何定义结构体,枚举类型等语言知识。并且逻辑思维也不错。可以来做程序员。



顺便想说一点,操作系统是每个程序员都必懂的东西,而且是越多越好,但是是不是每个人都应该去钻研linux内核源代码呢?窃以为,除非你是做内核开发或则内核移植相关的工作,此时内核代码的了解成为你的业务知识,你没必要花太多的时间去研究这个。那些特懂内核的人也没必要太拽,别人或许比你更懂网络知识。每个人都有自己的业务,方向。努力把它学好学精,同时把业务需要的语言,哪怕只有一种语言,学好了。你就是牛人了。


逻辑题:请编程实现,时间一小时。
某天!一家珠宝公司被盗!警方怀疑是甲,乙,丙,丁四个人中的一个,因此对四人进行问话。
甲说:我不是强盗! ,乙说:丁是强盗,丙说:乙是强盗,丁说:我不是强盗
这四个人中只有一人说的是真话。请问谁是强盗!?

wwl
回应一下!哈哈请正!不是很熟悉C的语法!

main()
{
for (a=-1;a<=0;a++);
{
  for (b=-1;b<=0;b++);
   {
     for (c=-1;c<=0;c++);
      {
        for (d=-1;d<=0;d++);
          {
            if a+b+c+d=-1 then
            m=0;
            if a<>-1 then m=m-1;
            if d=-1  then m=m-1;
            if b=-1  then m=m-1;
            if d<>-1 then m=m-1;
           }
      }
   }
}
if m=-3 then
    if a=-1 then "it is a!~";
    if b=-1 then "it is a!~";
    if c=-1 then "it is a!~";
    if d=-1 then "it is a!~";
}

yy_galois
呵呵,不是按照我的意思写的。

gawk
是啊,语言就是一个工具而已

wwl
你是什么意思,讲一下,没有弄懂你是什么意思

wwl
你不会让我用逻辑知识进行解答吧,那还叫编程实现啊!:em14:

scutan
好像林锐那本书上有那道题

kewenliang
回复 #1 yy_galois 的帖子

进一步的,听到有高手说算法,数据结构很重要,于是又苦读一番算法的书。又听到有高手说Linux内核开源,学会了感觉如何如何酷,于是心痒痒又钻研一番Linux内核源代码。结果愣是啥也没学会。程序没编出几个来,自己感觉自己啥都懂一点,但是啥也不会。也许还继续看看网络编程第二卷,捣鼓捣鼓socket。等等。


惭愧啊  我就是这样的!!!!!

wwl
楼主弄个答案出来,瞧瞧!

cugb_cat
按照计算机的处理步骤,应该是这样,假设甲说的是真话,看乙丙丁之间的话是否与都是假话有冲突;如果有冲突,则假设乙的话是真话,看甲丙丁之间的话是否与都是假话矛盾;。。。依此类推。。。

yy_galois
我靠,刚才我编了两个小时。。

[quote]
/*filename: who_are_the_robbers.c*/

#include <stdio.h>

#define SUCCESS 0
#define FAILURE 1

typedef enum enStatus
{
    STATUS_IS_NOT_ROBBER = 0,
    STATUS_IS_ROBBER,
    STATUS_MAX
}EN_STATUS;

typedef enum enSpeaking
{
    SPEAKING_IS_NOT_TRUTH = 0,
    SPEAKING_IS_TRUTH,
    SPEAKING_MAX
}EN_SPEAKING;

extern int WhoIsTheRobber();
extern int WhoTellTheTruth(EN_STATUS sta, EN_STATUS stb, EN_STATUS stc, EN_STATUS std);
extern int TypeTheRobbers(EN_STATUS sta, EN_STATUS stb, EN_STATUS stc, EN_STATUS std);



int main(int arc, char *argv[])
{
    WhoIsTheRobber();
   
    return SUCCESS;
}


int WhoIsTheRobber()
{
    EN_STATUS sta, stb, stc, std;
    int totalRobbers;

    for (sta = STATUS_IS_NOT_ROBBER; sta < STATUS_MAX; sta++)
    {
        for (stb = STATUS_IS_NOT_ROBBER; stb < STATUS_MAX; stb++)
        {
            for (stc = STATUS_IS_NOT_ROBBER; stc < STATUS_MAX; stc++)
            {
                for (std = STATUS_IS_NOT_ROBBER; std < STATUS_MAX; std++)
                {
                    totalRobbers = sta + stb + stc + std;
                    /*only one robber in them*/
                    if (1 == totalRobbers)
                    {
                        WhoTellTheTruth(sta, stb, stc, std);
                    }
                }
            }
        }
    }
   
    return SUCCESS;
}

int WhoTellTheTruth(EN_STATUS sta, EN_STATUS stb, EN_STATUS stc, EN_STATUS std)
{
    EN_SPEAKING spa, spb, spc, spd;
    int totalTruth;

    if ((sta >= STATUS_MAX) || (stb >= STATUS_MAX) || (stc >= STATUS_MAX) || (std >= STATUS_MAX))
    {
        printf("everyone must be a robber or not be/r/n");
        return FAILURE;
    }
   

    /*a said he is not the robber*/
    if (STATUS_IS_NOT_ROBBER == sta)
    {
        spa = SPEAKING_IS_TRUTH;
    }
    else
    {
        spa = SPEAKING_IS_NOT_TRUTH;
    }

    /*b said d is the robber*/
    if (STATUS_IS_NOT_ROBBER == std)
    {
        spb = SPEAKING_IS_NOT_TRUTH;
    }
    else
    {
        spb = SPEAKING_IS_TRUTH;
    }

    /*c said b is the robber*/
    if (STATUS_IS_NOT_ROBBER == stb)
    {
        spc = SPEAKING_IS_NOT_TRUTH;
    }
    else
    {
        spc = SPEAKING_IS_TRUTH;
    }

    /*d said he is not the robber*/
    if (STATUS_IS_NOT_ROBBER == std)
    {
        spd = SPEAKING_IS_TRUTH;
    }
    else
    {
        spd = SPEAKING_IS_NOT_TRUTH;
    }

    totalTruth = spa + spb + spc + spd;
    /*only one tell the truth*/
    if (1 == totalTruth)
    {
        TypeTheRobbers(sta, stb, stc, std);
        printf("a = %d, b = %d, c = %d, d = %d/r/n", sta, stb, stc, std);
    }

   
    return SUCCESS;
}

int TypeTheRobbers(EN_STATUS sta, EN_STATUS stb, EN_STATUS stc, EN_STATUS std)
{
    return SUCCESS;
}

[/quote]

wwl
楼主是写得好,长见识了

win_hate
[quote]原帖由 [i]yy_galois[/i] 于 2008-6-24 20:04 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=8653612&ptid=1169721][img]http://bbs.chinaunix.net/images/common/back.gif[/img][/url]
逻辑题:请编程实现,时间一小时。
某天!一家珠宝公司被盗!警方怀疑是甲,乙,丙,丁四个人中的一个,因此对四人进行问话。
甲说:我不是强盗! ,乙说:丁是强盗,丙说:乙是强盗,丁说:我不是强盗
这四个人中只有一人说的是真话。请问谁是强盗!?
... [/quote]

不编程行不行?用一对布尔变量来描述一个人的状态 (v0, v1),  v0=0 表示说假话,1 真话;v1=0 表示非强盗,v1=1 表示强盗。

按我对题目的理解,强盗只有一人,说真话的也只有一人。设甲乙丙丁分别为 x,y,z,w,有:

x1=x0+1
w1=w0+1
w1=y0
y1=z0

把中间两个式子一加得到 w0+y0+1=0, 所以 w0,y0 中有一个是 1, 另一个是 0;
但 x0,y0,z0, w0 中只有一个 1, 所以 x0=z0=0;
由第一个式子可知道 x1=1

甲是强盗。

wwl
想请问楼主你这样编写这个程序的意义在哪里?就是完全按你的按你说的思想程序语言仅一种实现的手段.还是要说明问题本身所涉及到的业务知识.对于这个题目而言,业务知识又深入的指什么呢?不会是数学的算术解题方法吧?

yy_galois
我觉得这个程序充分体现了,计算机作为逻辑推理的过程中的本质,就是枚举方法。

(这里不讨论高级的,各式聪明的算法问题, 那其实加入了人本身的思考过程在其中)

枚举看起来简单,其实复杂的问题如何通过枚举解决,还是需要一些思考的。

简单的说就是逐层假设,然后条件检验。

这个逐层假设非常重要,要不逻辑思维就混乱起来了。

[quote]逻辑推理是人类特有的思维。

如果采用计算机来逻辑推理。

用计算机实现逻辑推理,本质上是枚举。

如何枚举呢。就是逐层假设。

一个复杂的逻辑推理分为n层条件。

对第一层条件,有k1种情况。通过枚举假设为k1种中的某种,

对第二层条件,有k2种情况,通过枚举遍历,假设为k2中的一种,

对第三层条件,有k3种情况,通过枚举遍历,假设为k3中的一种,

...

逐层遍历下去,直到第n层。

在遍历的同时,逐个检查其中的某种情况是否符合条件。

如果符合条件,则逻辑推理出其中一种结果。

总之,计算机的逻辑推理就是逐层遍历加上条件检测。

当然这是原始的计算机逻辑推理方法,但也是最有效的计算机逻辑推理方法。

所谓的程序员思维,这个该算是其中之一。

[/quote]

[[i] 本帖最后由 yy_galois 于 2008-6-24 23:04 编辑 [/i]]

yy_galois
下面这道逻辑题,我写了一部分。

[quote]
主席台的一排座位上坐着六个不同职业的男人
他们穿着不同颜色的礼服,用不同品牌的手机
开不同的小汽车,有不同的爱好。已知:

1、高老庭是老师
2、牛老麟是足球员,他不爱打排球
3、穿灰色礼服的人开保时捷
4、用摩托罗拉手机的人开奥迪,他旁边的人用三星手机
5、靓仔胜用诺基亚手机,开奔驰跑车
6、用索爱手机的人爱上网
7、作家爱看书
8、肥老朱坐在四眼金的右边
9、牛老麟坐在第二位
10、商人坐在宿老俊旁边,他开的是劳斯莱斯
11、用NEC手机的男士旁边的人不穿灰色礼服
12、歌手爱跳舞
13、坐最右边的人穿紫色礼服
14、开法拉利的人坐在穿白色礼服的人旁边
15、蓝色礼服旁边的市长正用飞利浦手机打电话
16、肥老朱穿黑色礼服,他爱打桌球
17、歌手旁边的人既不爱上网,又不爱看书
18、穿红礼服的人不坐在作家旁边
19、坐第四位的人爱下象棋
20、靓仔胜不是歌手

请问谁开宝马?
[/quote]


[quote]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define SUCCESS 0
#define FAILURE 1

typedef enum enName
{
    NAME_GAO = 0,
    NAME_NIU,
    NAME_SHENG,
    NAME_ZHU,
    NAME_JIN,
    NAME_SU,
   
    NAME_MAX   
}EN_NAME;

typedef enum enVocation
{
    VOCATION_TEACHER = 0,
    VOCATION_FOOTBALLER,
    VOCATION_WRITER,
    VOCATION_SINGER,
    VOCATION_MERCHANT,
    VOCATION_MAYOR,

    VOCATION_MAX
}EN_VOCATION;

typedef enum enColor
{
    COLOR_RED = 0,
    COLOR_GRAY,
    COLOR_PURPLE,
    COLOR_BLACK,
    COLOR_WHITE,
    COLOR_BLUE,
   
    COLOR_MAX
}EN_COLOR;

typedef enum enPhone
{
    PHNOE_MOTO = 0,
    PHNOE_SAMSUNG,
    PHNOE_NEC,
    PHNOE_SONY,
    PHNOE_NOKIA,
    PHNOE_PHILLIPS,

    PHNOE_MAX
}EN_PHONE;

typedef enum enCar
{
    CAR_BENZ = 0,
    CAR_AUDI,
    CAR_ROLLSROYCE,
    CAR_BMW,
    CAR_PORSHCE,
    CAR_FERRARI,

    CAR_MAX
}EN_CAR;

typedef enum enInterest
{
    INTEREST_VOLLYBALL = 0,
    INTEREST_WEB,
    INTEREST_READING,
    INTEREST_SNOOKER,
    INTEREST_CHESS,
    INTEREST_DANCING,
   
    INTEREST_MAX
}EN_INTEREST;

typedef enum enSeat
{
    SEAT_ONE = 0,
    SEAT_TWO,
    SEAT_THREE,
    SEAT_FOUR,
    SEAT_FIVE,
    SEAT_SIX,

    SEAT_MAX
}EN_SEAT;

typedef struct tagPerson
{
    int name;
    int vocation;
    int color;
    int phone;
    int car;
    int interest;
    int seat;
}PERSON;

extern int SixMenName(PERSON *pa, PERSON *pb, PERSON *pc, PERSON *pd, PERSON *pe, PERSON *pf);
extern int SixMenVocation(PERSON *pa, PERSON *pb, PERSON *pc, PERSON *pd, PERSON *pe, PERSON *pf);
extern int SixMenColor(PERSON *pa, PERSON *pb, PERSON *pc, PERSON *pd, PERSON *pe, PERSON *pf);
extern int SixMenPhone(PERSON *pa, PERSON *pb, PERSON *pc, PERSON *pd, PERSON *pe, PERSON *pf);
extern int SixMenCar(PERSON *pa, PERSON *pb, PERSON *pc, PERSON *pd, PERSON *pe, PERSON *pf);
extern int SixMenInterest(PERSON *pa, PERSON *pb, PERSON *pc, PERSON *pd, PERSON *pe, PERSON *pf);
extern int SixMenSeat(PERSON *pa, PERSON *pb, PERSON *pc, PERSON *pd, PERSON *pe, PERSON *pf);



int main(int argc, char* argv[])
{
    PERSON pa = {0};
    PERSON pb = {0};
    PERSON pc = {0};
    PERSON pd = {0};
    PERSON pe = {0};
    PERSON pf = {0};

    SixMenName(&pa, &pb, &pc, &pd, &pe, &pf);
   
    return SUCCESS;
}



int SixMenName(PERSON *pa, PERSON *pb, PERSON *pc, PERSON *pd, PERSON *pe, PERSON *pf)
{
    pa->name = NAME_GAO;
    pb->name = NAME_NIU;
    pc->name = NAME_SHENG;
    pd->name = NAME_ZHU;
    pe->name = NAME_JIN;
    pf->name = NAME_SU;

    SixMenVocation(pa, pb, pc, pd, pe, pf);
   
    return SUCCESS;
}

int SixMenVocation(PERSON *pa, PERSON *pb, PERSON *pc, PERSON *pd, PERSON *pe, PERSON *pf)
{   
    /*高老庭是老师 */
    pa->vocation = VOCATION_TEACHER;
    /*牛老麟是足球员*/
    pb->vocation = VOCATION_FOOTBALLER;

    /*c语言的弱点就在这里,排列组合还要程序员自己来实现
          而java, python都有序列类型的数据结构,不需要程序员来实现
          排列组合
          总之,c的枚举类型远远不如python,java的序列好用*/
   
    for (pc->vocation = VOCATION_TEACHER, pc->vocation < VOCATION_MAX, (pc->vocation)++)
    {
        if ((pc->vocation == pa->vocation) || (pc->vocation == pb->vocation))
        {
            break;
        }

        /*靓仔胜不是歌手*/
        if (pc->vocation == VOCATION_SINGER)
        {
            break;
        }

        for (pd->vocation = VOCATION_TEACHER, pd->vocation < VOCATION_MAX, (pd->vocation)++)
        {
            if ((pd->vocation == pa->vocation) || (pd->vocation == pb->vocation) || (pd->vocation == pc->vocation))
            {
                break;
            }

            for (pe->vocation = VOCATION_TEACHER, pe->vocation < VOCATION_MAX, (pe->vocation)++)
            {
                if ((pe->vocation == pa->vocation) || (pe->vocation == pb->vocation)
                   || (pe->vocation == pc->vocation) || (pe->vocation == pd->vocation))
                {
                    break;
                }

                for (pf->vocation = VOCATION_TEACHER, pf->vocation < VOCATION_MAX, (pf->vocation)++)
                {
                    if ((pf->vocation == pa->vocation) || (pf->vocation == pb->vocation)
                       || (pf->vocation == pc->vocation) || (pf->vocation == pd->vocation)
                       || (pf->vocation == pe->vocation))
                    {
                        break;
                    }   

                    SixMenColor(pa, pb, pc, pd, pe, pf);
                }
            }
        }
        
    }
   
    return SUCCESS;
}

int SixMenColor(PERSON *pa, PERSON *pb, PERSON *pc, PERSON *pd, PERSON *pe, PERSON *pf)
{

    return SUCCESS;
}

int SixMenPhone(PERSON *pa, PERSON *pb, PERSON *pc, PERSON *pd, PERSON *pe, PERSON *pf)
{

    return SUCCESS;
}

int SixMenCar(PERSON *pa, PERSON *pb, PERSON *pc, PERSON *pd, PERSON *pe, PERSON *pf)
{

    return SUCCESS;
}

int SixMenInterest(PERSON *pa, PERSON *pb, PERSON *pc, PERSON *pd, PERSON *pe, PERSON *pf)
{

    return SUCCESS;
}

int SixMenSeat(PERSON *pa, PERSON *pb, PERSON *pc, PERSON *pd, PERSON *pe, PERSON *pf)
{

    return SUCCESS;
}

[/quote]

heixia108
上面的逻辑题用for循环解决不完美~

jerrymy
看看先。:) :)

zszyj
[quote]原帖由 [i]yy_galois[/i] 于 2008-6-24 20:04 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=8653612&ptid=1169721][img]http://bbs.chinaunix.net/images/common/back.gif[/img][/url]
很多人开始学习一种编程语言,典型的比如C语言,在学习到一定程度以后,比如已经能够熟练应用if else, while , for 等等语句编写程序解决简单的逻辑智力题等等,学着学着突然迷茫了,不知道C语言有什么作用。同 ... [/quote]
很好的体会, 有同感.

zszyj
[quote]原帖由 [i]yy_galois[/i] 于 2008-6-24 20:04 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=8653612&ptid=1169721][img]http://bbs.chinaunix.net/images/common/back.gif[/img][/url]
很多人开始学习一种编程语言,典型的比如C语言,在学习到一定程度以后,比如已经能够熟练应用if else, while , for 等等语句编写程序解决简单的逻辑智力题等等,学着学着突然迷茫了,不知道C语言有什么作用。同 ... [/quote]
知道了,甲是强盗嘛.