资源描述
给程序员的七个建议
(1)练内功。不要只花功夫学习各种流行的编程语言和工具,以及某些公司招聘广告上要求的科目。要把数据结构、算法、数据库、操作系统原理、计算机体系结 构、计算机网络,离散数学等基础课程学好。大家不妨试试高德纳所著The Art of Computer Programming里的题目,如果你能够 解决其中的大部分题目,就说明你在算法方面有一定的功力了。
(2)多实战。通过编程的实战积累经验、巩固知识。很多中国大学毕业生缺乏编程和调试经验;学习C语言,考试过关就算学会了;课题项目中,只要程序能够编 译,运行,并且输入输出满足要求就算了事。这些做法是不行的。写程序的时候,大家必须多想想如何把程序写得更加精炼、高效、高质量。建议大家争取在大学四 年中积累编写十万行代码的经验。我们必须明白的是:好程序员是写出来的,不是学出来的。
(3)求实干。不要轻视任何实际工作,比如一些看似简单的编码或测试。要不懈追求对细节一丝不苟的实干作风与敬业精神。我发现不少程序员对于知识的掌握很 肤浅,不求甚解,没有好奇心,不会刨根问底。比如,学会了C++,是否了解一个对象在编译后,在汇编代码中是如何被初始化的?这个对象的各个成员在内存中 是如何存放的?当一个成员函数被调用时,编译器在汇编代码中加入了哪些额外的动作?虚函数的调用是如何实现的? 这些东西恐怕在编程语言或编译原理中都没 有详细提到,只有通过踏实的实干才能真正掌握。
(4)重视数学学习。数学是思维的体操,数学无处不在。学计算机至少要学习离散数学、概率论、布尔代数、集合论和数理逻辑。这些知识并不难,但是对你未来 的工作帮助会很大。 尤其当你对一些“数学密集型”的领域如视频、图像处理等有兴趣时,这些知识将成为你手中的利器。
(5)培养团队精神,学会与人合作。今天的软件工程早已经不是一个人可以单独操作的,而必须靠团队合作才能成功。不懂得合作的人是不能成大器的。大家要多去寻找可以与人一起做项目的机会。
(6)激励创新意识,培养好奇心,不要死记硬背。没有掌握某种算法技术的根本原理,就不会有应变和创新的能力。想成为一位好程序员(其实从事任何一个行业 都是如此),重要的是要养成钻研,好奇,创新,动手,合作的优秀习惯,不满足于填鸭,不满足于考试交差,不满足于表象。这不是学几门课能够一蹴而就的。
(7)有策略地“打工”。在不影响学业的前提下,寻找真正有意义的暑期工作或兼职。去找一个重视技术的公司,在一个好的“老板”指导下完成真正会被用户使 用的程序。不要急于去一个要你做“头”而独挡一面的地方,因为向别人学习才是你的目的。找工作也是一样,不要只看待遇和职衔,要挑一个你能够学习的环境, 一个愿意培养员工的企业,一个重视你的专业的公司。最后,还要挑一个好老板。
CSDN特别收录 --- 超强的指针 *一辈子都找不到的牛B贴
(2009-04-23 23:00:54)
转载▼
标签:
杂谈
分类: C/C++
C语言所有复杂的指针声明,都是由各种声明嵌套构成的。如何解读复杂指针声明呢?右左法则是一个既著名又常用的方法。不过,右左法则其实并不是C标准里面的内容,它是从C标准的声明规定中归纳出来的方法。C标准的声明规则,是用来解决如何创建声明的,而右左法则是用来解决如何辩识一个声明的,两者可以说是相反的。右左法则的英文原文是这样说的:
The right-left rule: Start reading the declaration from the innermost parentheses, go right, and then go left. When you encounter parentheses, the direction should be reversed. Once everything in the parentheses has been parsed, jump out of it. Continue till the whole declaration has been parsed.
这段英文的翻译如下:
右左法则:首先从最里面的圆括号看起,然后往右看,再往左看。每当遇到圆括号时,就应该掉转阅读方向。一旦解析完圆括号里面所有的东西,就跳出圆括号。重复这个过程直到整个声明解析完毕。
笔者要对这个法则进行一个小小的修正,应该是从未定义的标识符开始阅读,而不是从括号读起,之所以是未定义的标识符,是因为一个声明里面可能有多个标识符,但未定义的标识符只会有一个。
现在通过一些例子来讨论右左法则的应用,先从最简单的开始,逐步加深:
int (*func)(int *p);
首先找到那个未定义的标识符,就是func,它的外面有一对圆括号,而且左边是一个*号,这说明func是一个指针,然后跳出这个圆括号,先看右边,也是一个圆括号,这说明(*func)是一个函数,而func是一个指向这类函数的指针,就是一个函数指针,这类函数具有int*类型的形参,返回值类型是int。
int (*func)(int *p, int (*f)(int*));
func被一对括号包含,且左边有一个*号,说明func是一个指针,跳出括号,右边也有个括号,那么func是一个指向函数的指针,这类函数具有int *和int (*)(int*)这样的形参,返回值为int类型。再来看一看func的形参int (*f)(int*),类似前面的解释,f也是一个函数指针,指向的函数具有int*类型的形参,返回值为int。
int (*func[5])(int *p);
func右边是一个[]运算符,说明func是一个具有5个元素的数组,func的左边有一个*,说明func的元素是指针,要注意这里的*不是修饰func的,而是修饰func[5]的,原因是[]运算符优先级比*高,func先跟[]结合,因此*修饰的是func[5]。跳出这个括号,看右边,也是一对圆括号,说明func数组的元素是函数类型的指针,它所指向的函数具有int*类型的形参,返回值类型为int。
int (*(*func)[5])(int *p);
func被一个圆括号包含,左边又有一个*,那么func是一个指针,跳出括号,右边是一个[]运算符号,说明func是一个指向数组的指针,现在往左看,左边有一个*号,说明这个数组的元素是指针,再跳出括号,右边又有一个括号,说明这个数组的元素是指向函数的指针。总结一下,就是:func是一个指向数组的指针,这个数组的元素是函数指针,这些指针指向具有int*形参,返回值为int类型的函数。
int (*(*func)(int *p))[5];
func是一个函数指针,这类函数具有int*类型的形参,返回值是指向数组的指针,所指向的数组的元素是具有5个int元素的数组。
要注意有些复杂指针声明是非法的,例如:
int func(void) [5];
func是一个返回值为具有5个int元素的数组的函数。但C语言的函数返回值不能为数组,这是因为如果允许函数返回值为数组,那么接收这个数组的内容的东西,也必须是一个数组,但C语言的数组名是一个右值,它不能作为左值来接收另一个数组,因此函数返回值不能为数组。
int func[5](void);
func是一个具有5个元素的数组,这个数组的元素都是函数。这也是非法的,因为数组的元素除了类型必须一样外,每个元素所占用的内存空间也必须相同,显然函数是无法达到这个要求的,即使函数的类型一样,但函数所占用的空间通常是不相同的。
作为练习,下面列几个复杂指针声明给读者自己来解析,答案放在第十章里。
int (*(*func)[5][6])[7][8];
int (*(*(*func)(int *))[5])(int *);
int (*(*func[7][8][9])(int*))[5];
实际当中,需要声明一个复杂指针时,如果把整个声明写成上面所示的形式,对程序可读性是一大损害。应该用typedef来对声明逐层分解,增强可读性,例如对于声明:
int (*(*func)(int *p))[5];
可以这样分解:
typedef int (*PARA)[5];
typedef PARA (*func)(int *);
这样就容易看得多了。
===============================================================
转载述:这是一篇比较老的关于指针的文章,作者站在初学者的角度对指针作了深入的剖析。如果你在学习指针的时候有什么问题,看一看这篇文章定有收获。
一。指针的概念
1。指针的类型
2。指针所指向的类型
3。指针的值
二。指针的算术运算
三。运算符&和*
四。指针表达式
五。数组和指针的关系
jackeroo(404956837) 2013/12/5 星期四 9:17:27
请问在ucos下,cpu是lpc1768,对flash操作是否需要互斥保护?
1133(1048489820) 2013/12/5 星期四 9:18:16
什么叫互斥保护?
jackeroo(404956837) 2013/12/5 星期四 9:18:42
防止并发竞争
比如用信号量 或中断什么的
1133(1048489820) 2013/12/5 星期四 9:20:07
哦
jackeroo(404956837) 2013/12/5 星期四 9:36:24
ucosii只能在调度点(比如osdelay之类的)才能调度?对ucosii
JIN(1150660744) 2013/12/5 星期四 9:52:03
是
奋斗!(343498968) 2013/12/5 星期四 9:54:17
群里有没有在南昌工作的仁兄?
♯~\(≧∮≦)/~♫(395997361) 2013/12/5 星期四 10:15:10
南昌混了四年的飘过,
奋斗!(343498968) 2013/12/5 星期四 10:16:51
我问下,在南昌搞ucos好不好找工作?
我在网上看都没有
♯~\(≧∮≦)/~♫(395997361) 2013/12/5 星期四 10:17:32
南昌小城市。
空间不大。
奋斗!(343498968) 2013/12/5 星期四 10:17:43
我现在南京工作,准备明年去南昌
♯~\(≧∮≦)/~♫(395997361) 2013/12/5 星期四 10:18:21
天气不好那边,四季随机播放。
我都走了。
不对,应该说是冬夏两季。
奋斗!(343498968) 2013/12/5 星期四 10:18:57
我在赣州读过书,感觉一年就夏冬两季
呵呵,同感
你现在在哪儿工作
(No need)(58223001) 2013/12/5 星期四 10:19:38
搞ucos应用还是移植?
奋斗!(343498968) 2013/12/5 星期四 10:19:46
都搞
(No need)(58223001) 2013/12/5 星期四 10:20:20
移在ARM上?
奋斗!(343498968) 2013/12/5 星期四 10:21:16
什么都移,FPGA,STM32,摩托的
不过移植好弄,好多ucos移植网上都有
奋斗!(343498968) 2013/12/5 星期四 10:23:29
到南昌找工作,我估计很难找个薪水高的
¤ ☻(379211943) 2013/12/5 星期四 10:49:05
南昌地方好吗?
ZeroOne(631640356) 2013/12/5 星期四 10:52:25
奋斗!(343498968) 2013/12/5 星期四 10:52:26
江西总体来说适合人居住
ZeroOne(631640356) 2013/12/5 星期四 10:52:27
请教个问题
奋斗!(343498968) 2013/12/5 星期四 10:53:49
问题是啥
ZeroOne(631640356) 2013/12/5 星期四 10:53:52
任务0 获得了按键信息,然后把信息打印到缓存,然后发送一个邮箱,说明缓存已经更新,可以刷新显示了,然后就休眠了
显示任务 取出更新的一个信息 后跟新了显示,然后就清空了显存
ZeroOne(631640356) 2013/12/5 星期四 10:55:18
现在 问题是 就是更新了显示 后,过了一会儿 屏幕又清屏了
但是 没有按键按下啊,及没有发送刷新显示的信息
ZeroOne(631640356) 2013/12/5 星期四 10:57:41
显示 任务 取刷新显示的信息用的是等待一个信号量
风月(332738158) 2013/12/5 星期四 10:58:05
请问一下,用了高版本的IAR把D版的JLINK固件给丢失了,现在从新刷固件按照网上的顺序,Write Flash按钮总是失效,刷不了,大家遇到过嘛
ZeroOne(631640356) 2013/12/5 星期四 10:59:15
没有 信息了应该返回超时啊
奋斗!(343498968) 2013/12/5 星期四 11:00:02
任务0发送邮件的时候,发错了
写反了吧
ZeroOne(631640356) 2013/12/5 星期四 11:01:19
我是用 指针传递了一个 命令啊
传递的是 1就刷新
奋斗!(343498968) 2013/12/5 星期四 11:01:42
我知道啊
但是你应该先赋值,再发送啊
你怎么先发送,再赋值啊
ZeroOne(631640356) 2013/12/5 星期四 11:02:35
==
奋斗!(343498968) 2013/12/5 星期四 11:02:57
干脆用信号量得了,怎么用邮箱啊
ZeroOne(631640356) 2013/12/5 星期四 11:04:09
我试试
ZeroOne(631640356) 2013/12/5 星期四 11:04:33
可能是我发送错了吧
因为没有考虑内核怎么处理的
谢谢指教
奋斗!(343498968) 2013/12/5 星期四 11:05:34
不客气
ZeroOne(631640356) 2013/12/5 星期四 11:07:01
果然正常了
jackeroo(404956837) 2013/12/5 星期四 14:03:41
请问ucosii虽然不是按照时间片调度的但是不是给每个任务分配了固定的运行时间,时间到了才触发调度?
ZeroOne(631640356) 2013/12/5 星期四 14:11:45
我测试过了
不会的
ZeroOne(631640356) 2013/12/5 星期四 14:12:02
运行的永远都是优先级最高的
假如有个任务0 在运行,任务0没有调用OS_Delay
或者 等待什么信号的话
任务0是永远在运行的
ZeroOne(631640356) 2013/12/5 星期四 14:15:35
我也要问个问题。T0 是按键任务优先级为 0 ,T1是一个简单的任务,优先级为1,T2是另一任务,优先级为2.
现在,如果T1 运行到1半了,T0按键发出指令,要求不再运行T1,要运行T3了,怎么处理啊
奋斗!(343498968) 2013/12/5 星期四 14:24:08
你要挂起T0,T1,如果时间允许的话就延时TO,T1
ZeroOne(631640356) 2013/12/5 星期四 14:27:19
T0 是通过延时 来挂起的
奋斗!(343498968) 2013/12/5 星期四 14:28:17
那T1就用suspend
suspend(self)
ZeroOne(631640356) 2013/12/5 星期四 14:28:36
T0 发出命令后就延时挂起了,然后希望以后都不在运行T1了,如果要运行就从头开始运行
奋斗! 我现在是做一个菜单,菜单里面有很多项。
奋斗!(343498968) 2013/12/5 星期四 14:29:47
那就用删除吧,等用T1的时候再创建
jackeroo(404956837) 2013/12/5 星期四 14:30:06
通过t1给t3发信号量 post pend
ZeroOne(631640356) 2013/12/5 星期四 14:30:45
==
奋斗!(343498968) 2013/12/5 星期四 14:31:18
不用发信号量,T1延时挂起,T2删除,T3就自动调度运行了
ZeroOne(631640356) 2013/12/5 星期四 14:31:35
嗯
这个知道
谢谢
ZeroOne(631640356) 2013/12/5 星期四 14:33:41
这是一个菜单,也就是任务T1,任务T1里面有3个函数F1 F2 F3
可能在运行F1的时候,用户直接退出菜单,那么就直接将这个任务删除掉。
如果用户希望直接不运行F1了,跳到F3去,怎么处理啊。
ZeroOne(631640356) 2013/12/5 星期四 14:35:46
谢谢大家。
奋斗!(343498968) 2013/12/5 星期四 14:36:37
用ucos做菜单,你厉害啊
ZeroOne(631640356) 2013/12/5 星期四 14:36:58
我之前菜单做好了的啊
只是要用到UCOS
但是没有用过 只能硬着头皮上咯
ZeroOne(631640356) 2013/12/5 星期四 14:38:19
菜单里面的每一个小项 都做成1个任务好不好
奋斗!(343498968) 2013/12/5 星期四 14:38:28
麻烦
ZeroOne(631640356) 2013/12/5 星期四 14:38:49
需要用到的时候 就创建任务,不要就删了
按照傻孩子的菜单模式写的
奋斗!(343498968) 2013/12/5 星期四 14:39:26
ucos任务多了不好,经常创建再删除也不好
你这菜单模式不懂,也没法给你建议
ZeroOne(631640356) 2013/12/5 星期四 14:40:56
你没有用UCOS 做过实际的工程
我想一下UCOS 的具体用法
目前 觉得还不入用全局变量好
可能是不懂操作系统的一个误区吧
奋斗!(343498968) 2013/12/5 星期四 14:41:55
用过,都是自动化控制
ZeroOne(631640356) 2013/12/5 星期四 14:42:49
有个 比较小的应用,就是不涉及到 什么产权之类的,就发我一个吧
感激不尽
奋斗!(343498968) 2013/12/5 星期四 14:43:16
呵呵,我这边电脑加密,什么东西都发不出去
ZeroOne(631640356) 2013/12/5 星期四 14:43:37
哦!
奋斗!(343498968) 2013/12/5 星期四 14:44:07
你网上搜下吧
ZeroOne(631640356) 2013/12/5 星期四 14:44:22
网上找的资料 基本就是源码 或者移植的其他东西。根本不是结合实际来做的
好多没有发挥UCOS了作用
往最後的森林(627515898) 2013/12/5 星期四 14:45:10
其实你想知道的是 如何基于RTOS的程序设计
ZeroOne(631640356) 2013/12/5 星期四 14:45:27
嗯
书 看过好多遍了。
奋斗!(343498968) 2013/12/5 星期四 14:45:48
我推荐你一本书吧
往最後的森林(627515898) 2013/12/5 星期四 14:45:53
找书吧, 我以前在图书馆翻过,不多,但是有
ZeroOne(631640356) 2013/12/5 星期四 14:46:05
但是基本没有用,还得实际操作,边调试边看书
奋斗,说吧
往最後的森林(627515898) 2013/12/5 星期四 14:46:23
不是那种讲原理的
奋斗!(343498968) 2013/12/5 星期四 14:46:38
基于嵌入式实时操作系统的程序设计技术
讲实用的
应用为主
很不错
ZeroOne(631640356) 2013/12/5 星期四 14:47:26
哦!谢谢
之前都围绕着 这个在转
ZeroOne(631640356) 2013/12/5 星期四 14:49:28
讲得还是很清晰的,加上有源代码,看懂基本没有问题。
但是 用就麻烦
往最後的森林(627515898) 2013/12/5 星期四 14:51:31
跟一般OS的程序设计其实没有差多少
ZeroOne(631640356) 2013/12/5 星期四 14:52:46
嗯,会了的时候我也会这么认为的
现在还是小白
往最後的森林(627515898) 2013/12/5 星期四 14:56:45
底层在手 顶层练练差不多了
菜单为何不用GUI
谁的童年不天真。(545083977) 2013/12/5 星期四 14:58:52
你的菜单就一个ui的task好了
谁的童年不天真。(545083977) 2013/12/5 星期四 14:58:58
为何要1个菜单一个任务?
(No need)(58223001) 2013/12/5 星期四 15:31:32
你们讨论得很好,其实网上也有ucos的课程,可以听一下。目标是设计os,以ucos为切入点,不仅仅是让你知道怎么用os,也不仅仅是教你怎么移植os。听了之后让你永远不害怕os
ZeroOne(631640356) 2013/12/5 星期四 15:32:18
12864也就
液晶
用GUI 估计够呛
谁的童年不天真。(545083977) 2013/12/5 星期四 15:32:51
那就自己写菜单咯
一个菜单任务,所有的处理都在这个里面处理
ZeroOne(631640356) 2013/12/5 星期四 15:33:16
是1个菜单
菜单 返回的时候处理,我很迷糊
谁的童年不天真。(545083977) 2013/12/5 星期四 15:33:48
回调
界面的切换都用回调
这样方便很多
ZeroOne(631640356) 2013/12/5 星期四 15:34:37
比如,有的时候是直接 退出菜单,有的时候是从1级菜单跳转到 其他兄弟菜单
谁的童年不天真。(545083977) 2013/12/5 星期四 15:35:21
那就定义到一个界面的属性里咯
ZeroOne(631640356) 2013/12/5 星期四 15:35:55
回调 是要简单很多。显示我是作为一个任务处理的。 如果直接回调的话,好像又脱离了UCOS了
谁的童年不天真。(545083977) 2013/12/5 星期四 15:36:14
回调跟ucos不冲突
ZeroOne(631640356) 2013/12/5 星期四 15:36:45
觉得就是 简单的把UCOS 当调度器用了
然后下面有几个任务,任务里面的实现就是 普通的裸机程序一样
ZeroOne(631640356) 2013/12/5 星期四 15:48:10
ZLG/GUI 可以用于12864吧
我的意思 是不是 为这类点阵打造的
展开阅读全文