编程技巧
⑴ 程序员如何提高自己的编程技巧
可读性:函数命名随意,实现逻辑混乱,代码格式不统一。。。
可靠性:程序运行很难稳定,bug百出。。。
维护性:代码逻辑没有层次,混成一团,很难维护改进
移植性、重用性:许多人写的代码,只能各自使用,很少有能共享的功能性代码
高效性:很少从算法、资源占用、执行效率等角度去考虑,经常导致服务器负载过重
那么我们改进时,就可以从以上几点出发。
总结了一下自己以前的经验,主要有以下几点:
提高自己的程序语言基础。对于许多新手程序员来说,只是简单的学会了该语言,知道一些简单的用法。但是实际编程的时候,许多写法、用法不标准。举一个很常见的例子:许多人刚刚学c++,java等面向对象编程的语言时,虽然知道了类、知道了类一般都有“多态”的特性,但是他们还是经常会用“类型判断”去判断某个对象是属于哪个类的实例、然后强制转换、再调用方法。却完全忽略可以用多态来避免这种丑陋的实现!
熟悉语言规范。如果不知道自己所学的语言还有规范,那么建议你现在去查找。说个简单的规范,Java的类名要取得有意义、首字母要大写。再比如:一个函数只实现一个功能。再比如一个复杂的:连续的if else条件判断最好不要超过10个。
培养自己严谨的逻辑思维能力。我们写程序,至少都会在脑海里走一遍程序的流程。如果流程走通最后却出现bug,那么就是流程的某个细节我们没有考虑到!有的时候,我们总是自认为自己已经考虑的非常全面了,其实不然。同样举一个例子:对一个集合,写个for循环按照一定的条件删除里面的元素。其实这里面隐藏了一个“集合在动态变化”的陷阱。比如说,将第一个元素删除了,如果集合的数据结构是将第二个元素移动到第一个元素上,那么,第二个元素就遍历不到了。所以,有时候,我们看似很简单,觉得逻辑非常正确的代码,可能就潜伏着陷阱。
熟悉所用语言的API。学一门语言,其实不只是学语法,学语义。更重要的是学基本的API类库。因为你实际编程的时候,自己所写的代码其实很少,大部分都是用的别人的API,将许多API的功能穿起来,才是自己实现的功能。用好的API,能增加代码质量、提高代码可读性、减少代码bug、减少工作量。就比如说堆栈这个数据结构,程序员基本都知道,但是大部分人可能都不能实现一个正确的堆栈API。
熟悉了解一些数据结构、算法。平常写程序时,或多或少都要接触一些常用的数据结构,比如说链表、map等,了解它们的原理对于那些没学过数据结构的人来说很重要。很多时候,一个简单的功能被实现的超级复杂的原因就是没有使用简单清晰的数据结构。
掌握一些编程思想、设计模式,这会让你的代码更加具有结构性、条理更加清晰!比如说,面向接口的编程思想,能让你的代码易于修改、易于扩展。如果更进一步,站在架构的角度去考虑。
多看高手代码,读一些优秀的开源代码,看一些经典的书籍。比如说《Effective C++》、《Effective Java》、lucene的源码。这些会让你提升巨大,只有了解到高手眼中的世界,才能有成为高手的可能!
代码重构。多回顾之前写的代码,进行一个系统性的整理。因为我们起初开发,不是面面都能想到,许多新东西是不可避免的,这就意味着可能会导致一些逻辑混乱。在开发完成后,多回顾回顾,寻找能改进之处,这也是一种进步。
即时缺少高屋建瓴的能力,我们也应该多从全局的角度去考虑整个工程的代码的层次、模块、架构等问题点。可以尝试着进行功能点拆分、接口交互设计等工作。
为自己的代码添加测试用例。可能因为懒惰,许多程序员基本都不会为自己的代码添加测试用例,这其实是一个不好的习惯。即时是有测试人员的团队,添加测试用例对你的好处也是显而易见的。
至于从团队的角度,可以考虑建立以下几点:完整的规范、执行流程、review机制和辅助工具。由于本篇文章主要针对的是个人,就不展开。工具方面,可以考虑开源的ReviewBoard。
个人的代码质量提上来,团队的水平才能提上来,公司的效率才能提升。其实最主要的是,个人的层次、境界才能提升!
⑵ 刚开始学编程需要掌握哪些知识和技巧
1 许多人都说要养成良好的编程习惯,那请问什么才算是良好的编程习惯? 1. 遵循命名规则 一个应用程序的命名规划必须保持一致性和可读性。任何一个实体的主要功能或用途必须能够根据命名明显的看出来。因为ActionScript是一个动态类型的语言,命名最好是包含有代表对象类型的后缀。一般而言,名词_动词和形容词_名词之类的语法是最常用的命名方式,如: 影片名字:my_movie.swf URL实体:course_list_output 组件或对象名称:chat_mc 变量或属性:userName 方法和变量的名称应该以小写字母开头,对象和对象的构造方法应该大写。命名变量的时候使用大小写混和的方式,并且使用字母打头,还可以包含数字和下划线。 下面的一些命名是非法的: _count =5 ;//首字符不能使用下划线 5count = 0;//首字符不能使用数字 foo/bar = true;//包含非法字符 另外,ActionScript使用的保留字不能用来命名变量。 ActionScript是基于ECMAScript,所以我们可以根据ECMAScript的规范来命名。如, course_list_output = "foo"; //全部小写,使用下划线分割字串 courseListOutput = "foo"; // 大小写混和的方式 BASEURL = http://www.foo.com; // 常量使用全部大写 MAXCOUNTLIMIT = 10; MyObject = function(){ }; // 构造函数 f = new MyObject(); // 对象 注意;良好的命名规范还可以使用Flash的代码提示功能。 2. 给你的代码添加注释 使用代码注释能够使得程序更清晰,也便于我们阅读。Flash支持的代码注释方法有两种: 单行注释,通常用于变量的说明 var clicks = 0; // variable for number of button clicks 多行注释,通常用于功能说明和大段文字的注释: /* Initialize the clicks variable that keeps track of the number of times the button has been clicked. */ 一些具有特定意思的注释方法: // :TODO: topic 表明一个主题的开始 // :BUG: [bugid] topic 显示了一个BUG所在 // :KLUDGE: 表明下面的代码并不完善,可能存在问题 // :TRICKY: 告诉开发人员下面的代码具有相互作用,修改之前请谨慎 3. 保持代码的整体性 无论什么情况,应该尽可能保证所有代码在同一个位置,这样使得代码更容易搜索和调试。我们在调试程序的时候很大的困难就是定位代码,如果大部分代码都集中在同一帧,问题就比较好解决了。通常,我们把代码都放在第一帧中,并且单独放在最顶层。如果在第一帧中集中了大量的代码,记得用注释标记区分,并在开头加上代码说明。 //=========================================== // 视频语音聊天系统 // FCAVPresence组件 // Copyright ◎2002 Macromedia, Inc. All rights reserved. // 完 善: Liu21st, [email protected] //--------------------------------------------------------- 在独立的功能模块前面加上类似的标注: //=========================================== // 参数初始化 //--------------------------------------------------------- 4. 初始化应用程序 记得一定要初始化你的应用程序,init函数应该是你的应用程序类的第一个函数,如果使用面向对象的编程方式则应该在构造函数中进线初始化工作。该函数只是对应用程序中的变量和对象初始化,其它的调用可以通过事件驱动。 下面的例子可以说明如何进线初始化 function FCAVPresenceClass() { this.init(); } FCAVPresenceClass.prototype.init = function() { this.name = (this._name == null ? "_DEFAULT_" : this._name); this.prefix = "FCAVPresence." + this.name + "."; }; 5.使用局部变量 所有的局部变量使用关键字var来申明,这样可以避免被全局变量访问,更重要的是,可以保证变量不被覆盖和混淆程序逻辑。例如,下面的代码没有使用var来申明,覆盖了其它变量。 counter = 7; function loopTest() { trace(counter); for(counter = 0; counter < 5; counter++) { trace(counter); } } trace(counter); loopTest(); trace(counter); 输出结果为: 7 7 0 1 2 3 4 5 6. 创建对象时使用原型添加方法和属性 当我们创建一个对象的时候,应当使用原型方式来添加对象的方法或属性,使得该方法或属性能够被所有该对象或子对象的实体所访问。这种能够确保内存中每个函数只有一份拷贝。作为一般的规则,不要在构造函数中定义方法。下面是一个正确的例子: // Best practice for creating an object MyObject = function() { } MyObject.prototype.name = ""; MyObject.prototype.setName = function(name) { this.name = name; } MyObject.prototype.getName = function() { return this.name; } 下面这段代码是不可取的: // Less desirable practice for creating an object MyObject = function() { this.name = ""; this.setName = function(name) { this.name = name; } this.getName = function() { return this.name; } } 使用上面的方式在每个对象的实体被创建的时候都会实体重新复制每一个属性和方法,会加重系统的内存开销。 7. 规范命名方式获取代码提示功能 在平时学习理论知识的时候要主意些什么?实践的时候又应该主意什么? 理论学需要注意1 .联系实际应用 比如: 你学了一种算法,就要想那里会用到。 2.避免前人的犯过的错误 比如:指针初始化 实践的时候: 1.不断总结自己犯下的错误 ,哪怕是非常小的,这样天长日久才能养成良好的编程风格。 2.读别人的代码。从中吸取你需要的,因为不是每个编程项目,都是要从零开始的。只有站在前人的肩膀上才能走的更远。 3 许多人都说编程思想是编程里面非常重要的一点,请问对于初学者该怎么样从一开始就慢慢领悟这种思想? 答:思想来源与不断的实践 ,不断总结前人和自己的错误,不断地与人分享自己的观点(比如我现在回答你的问题),不断地讨论(其中可能有意想不到的灵感) 只有勤奋,与执着的追求才能让你成为一位优秀的编程人员 4 曾经有人跟我说过学编程搞软件开发还需要学习微机原理,请问是不是如此?如果是,请顺便指点一下此课程的学习方法 答:学习微机原理? 初学者不需要学它。那是做开发用的。你现在是要把基础打好,等你打好基础,在慢慢就能看到其中的奥秘 谢谢! 欢迎交流
⑶ 求编程方法
求编程方法?C语言是面向过程的,而C++是面向对象的
C和C++的区别:
C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现过程(事务)控制)。
C++,首要考虑的是如何构造一个对象模型,让这个模型能够契合与之对应的问题域,这样就可以通过获取对象的状态信息得到输出或实现过程(事务)控制。 所以C与C++的最大区别在于它们的用于解决问题的思想方法不一样。之所以说C++比C更先进,是因为“ 设计这个概念已经被融入到C++之中 ”。
C与C++的最大区别:在于它们的用于解决问题的思想方法不一样。之所以说C++比C更先进,是因为“ 设计这个概念已经被融入到C++之中 ”,而就语言本身而言,在C中更多的是算法的概念。那么是不是C就不重要了,错!算法是程序设计的基础,好的设计如果没有好的算法,一样不行。而且,“C加上好的设计”也能写出非常好的东西。
原题
解题
思路
初始化i=100。
①取i的各位数,百位a,十位b,个位c。
②判断i==a∧3+b∧3+c∧3 是否成立
③如果成立则输出,否则不输出。
④i=i+1,当i小于1000重复①,否则结束。
关键算法:取任意三位数的各位数
小编推荐一个学C语言/C++的学习裙【 二六三,六八八,二七六 】,无论你是大牛还是小白,是想转行还是想入行都可以来了解一起进步一起学习!裙内有开发工具,很多干货和技术资料分享!
算法一:除减法
①将数除以100,由整型数据特点,小数点后被忽略,取得百位a。
②该数减去a * 100,除以10,得到十位b。
③该数减去a * 100和b * 10即得个位c。
代码实现
a = i / 100;b = (i - 100 * a) / 10;c = i - 100 * a - 10 * b;
完整代码:
void NarcissusNumber(int m) { int a; //三位数的百位 int b; //三位数的十位 int c; //三位数的个位 int d; //各位数字立方和与数的差值 a = m / 100; b = (m - 100 * a) / 10; c = m - 100 * a - 10 * b; d = a*a*a + b*b*b + c*c*c - m; if (d==0) //各位数字立方和与数相等,输出 { printf("%d ", m); }}
好处:易理解,菜鸟基本都会这算法。
不足:当数字位数较大时,减法操作需要进行多次,比较代码比较冗长。
⑷ 学习编程有什么技巧
还是需要动手操作联系,看视频,或者看书,感觉都是理所当然,但自己实际操作起来,就又不会了,所以还是要真正动手,编程,不能眼高手低
⑸ 几个C#编程的小技巧
主要方法
参数地址传递
有点时候需要对两个参数操作,这样用返回值实现其来就复杂了。要明白引用传递,对于值类型来说:修饰符ref修饰。
参数个数方法
在写方法时,有时常为参数个数发愁。例如有的参数希望如果调用传值了就用所串的值,如果没有传值就不处理它。这里有道一个修饰符 params。如果个数不确定就用数组
params int[]number
循环比较思想
想找出一个集合中的之最,就用循环比较法,例如找一个数组中的最大值。这种编程思想可以应用的很多,要发散思维。
?private static int GetMax(int[] arr)
{
int max = arr[0];
for (int i = 0; i< arr.Length; i++)
{
if (max < arr[i])
{
max = arr[i];
}
}
return max;
}
保留小数位问题
有客户需求要保留两位小数,可是有的恰好就一位小数怎么办。这里用到format方法。string numStr = string.Format("{0:0.00}",2.3);
字符串处理
查找字符串中的字符
IndexOf(keyWord,index)返回值是字符所在索引,index 开始查询位置,keyWord是要查找的字符。
字符串切割与拼接方法
?
1、Split(new char[]{ ' ' }, StringSplitOptions.RemoveEmptyEntries);
这是按照空格切成字符串数组,要注意后面的参数表示去掉空字符串。
2、string.Join(" ", text);拼接字符串 以空格连接字符串数组中元素
3、将字符串转化成字符数组 ToCharArray()
索引器的编写
有的一些对象可以像调用数组那样调用,例如person[0]。其实这是应为有“索引器”
public string this[int index]
{
get { returnNames[index]; }
set { Names[index] = value;}
}
反向排序
反向拍序思想,以简单的数组为例。
1总结
这节没有将太多新知识,都是写小知识点。关于一些思想也是特简单的,但是要明白它们不止可以用于数组。也可以用于集合,比较对象的某个字段。
⑹ C语言编程的一些技巧
也没啥技巧,就是要注意,一般情况下,开头的main函数,以及“;”符号,还有“{}”
⑺ 数控编程技巧
循环钻孔指令没有深度Z,X是半径Y是起始夹角。G90格式:后面依次写每个孔与起始轴的夹角(用Y)就可以了,适用于非均匀分布的孔。用G91格式钻均匀分布孔更方便,格式
……(相同,省略)
G91 Y(每孔之间夹角) K(孔数量);
G80 G15;
⑻ C语言中有哪些实用的编程技巧
这篇文章主要介绍了C语言高效编程的几招小技巧,本文讲解了以空间换时间、用数学方法解决问题以及使用位操作等编辑技巧,并给出若干方法和代码实例,需要的朋友可以参考下
引言:
编写高效简洁的C语言代码,是许多软件工程师追求的目标。本文就工作中的一些体会和经验做相关的阐述,不对的地方请各位指教。
第1招:以空间换时间
计算机程序中最大的矛盾是空间和时间的矛盾,那么,从这个角度出发逆向思维来考虑程序的效率问题,我们就有了解决问题的第1招——以空间换时间。
例如:字符串的赋值。
方法A,通常的办法:
代码如下:
#define LEN 32
char string1 [LEN];
memset (string1,0,LEN);
strcpy (string1,“This is a example!!”);
方法B:
代码如下:
const char string2[LEN] =“This is a example!”;
char * cp;
cp = string2 ;
(使用的时候可以直接用指针来操作。)
从上面的例子可以看出,A和B的效率是不能比的。在同样的存储空间下,B直接使用指针就可以操作了,而A需要调用两个字符函数才能完成。B的缺点在于灵 活性没有A好。在需要频繁更改一个字符串内容的时候,A具有更好的灵活性;如果采用方法B,则需要预存许多字符串,虽然占用了大量的内存,但是获得了程序 执行的高效率。
如果系统的实时性要求很高,内存还有一些,那我推荐你使用该招数。
该招数的变招——使用宏函数而不是函数。举例如下:
方法C:
代码如下:
#define bwMCDR2_ADDRESS 4
#define bsMCDR2_ADDRESS 17
int BIT_MASK(int __bf)
{
return ((1U << (bw ## __bf)) - 1) << (bs ## __bf);
}
void SET_BITS(int __dst, int __bf, int __val)
{
__dst = ((__dst) & ~(BIT_MASK(__bf))) | /
(((__val) << (bs ## __bf)) & (BIT_MASK(__bf))))
}
SET_BITS(MCDR2, MCDR2_ADDRESS, RegisterNumber);
方法D:
代码如下:
#define bwMCDR2_ADDRESS 4
#define bsMCDR2_ADDRESS 17
#define bmMCDR2_ADDRESS BIT_MASK(MCDR2_ADDRESS)
#define BIT_MASK(__bf) (((1U << (bw ## __bf)) - 1) << (bs ## __bf))
#define SET_BITS(__dst, __bf, __val) /
((__dst) = ((__dst) & ~(BIT_MASK(__bf))) | /
(((__val) << (bs ## __bf)) & (BIT_MASK(__bf))))
SET_BITS(MCDR2, MCDR2_ADDRESS, RegisterNumber);
函数和宏函数的区别就在于,宏函数占用了大量的空间,而函数占用了时间。大家要知道的是,函数调用是要使用系统的栈来保存数据的,如果编译器里有栈检查 选项,一般在函数的头会嵌入一些汇编语句对当前栈进行检查;同时,CPU也要在函数调用时保存和恢复当前的现场,进行压栈和弹栈操作,所以,函数调用需要 一些CPU时间。而宏函数不存在这个问题。宏函数仅仅作为预先写好的代码嵌入到当前程序,不会产生函数调用,所以仅仅是占用了空间,在频繁调用同一个宏函 数的时候,该现象尤其突出。
D方法是我看到的最好的置位操作函数,是ARM公司源码的一部分,在短短的三行内实现了很多功能,几乎涵盖了所有的位操作功能。C方法是其变体,其中滋味还需大家仔细体会。
第2招:数学方法解决问题
现在我们演绎高效C语言编写的第二招——采用数学方法来解决问题。
数学是计算机之母,没有数学的依据和基础,就没有计算机的发展,所以在编写程序的时候,采用一些数学方法会对程序的执行效率有数量级的提高。
举例如下,求 1~100的和。
方法E
代码如下:
int I , j;
for (I = 1 ;I<=100; I ++){
j += I;
}
方法F
代码如下:
int I;
I = (100 * (1+100)) / 2
这个例子是我印象最深的一个数学用例,是我的计算机启蒙老师考我的。当时我只有小学三年级,可惜我当时不知道用公式 N×(N+1)/ 2 来解决这个问题。方法E循环了100次才解决问题,也就是说最少用了100个赋值,100个判断,200个加法(I和j);而方法F仅仅用了1个加法,1 次乘法,1次除法。效果自然不言而喻。所以,现在我在编程序的时候,更多的是动脑筋找规律,最大限度地发挥数学的威力来提高程序运行的效率。
第3招:使用位操作
实现高效的C语言编写的第三招——使用位操作,减少除法和取模的运算。
在计算机程序中,数据的位是可以操作的最小数据单位,理论上可以用“位运算”来完成所有的运算和操作。一般的位操作是用来控制硬件的,或者做数据变换使用,但是,灵活的位操作可以有效地提高程序运行的效率。举例如下:
方法G
代码如下:
int I,J;
I = 257 /8;
J = 456 % 32;
方法H
int I,J;
I = 257 >>3;
J = 456 - (456 >> 4 << 4);
在字面上好像H比G麻烦了好多,但是,仔细查看产生的汇编代码就会明白,方法G调用了基本的取模函数和除法函数,既有函数调用,还有很多汇编代码和寄存 器参与运算;而方法H则仅仅是几句相关的汇编,代码更简洁,效率更高。当然,由于编译器的不同,可能效率的差距不大,但是,以我目前遇到的MS C ,ARM C 来看,效率的差距还是不小。相关汇编代码就不在这里列举了。
运用这招需要注意的是,因为CPU的不同而产生的问题。比如说,在PC上用这招编写的程序,并在PC上调试通过,在移植到一个16位机平台上的时候,可能会产生代码隐患。所以只有在一定技术进阶的基础下才可以使用这招。
第4招:汇编嵌入
高效C语言编程的必杀技,第四招——嵌入汇编。
“在熟悉汇编语言的人眼里,C语言编写的程序都是垃圾”。这种说法虽然偏激了一些,但是却有它的道理。汇编语言是效率最高的计算机语言,但是,不可能靠着它来写一个操作系统吧?所以,为了获得程序的高效率,我们只好采用变通的方法 ——嵌入汇编,混合编程。
举例如下,将数组一赋值给数组二,要求每一字节都相符。
代码如下:
char string1[1024],string2[1024];
方法I
代码如下:
int I;
for (I =0 ;I<1024;I++)
*(string2 + I) = *(string1 + I)
方法J
代码如下:
#ifdef _PC_
int I;
for (I =0 ;I<1024;I++)
*(string2 + I) = *(string1 + I);
#else
#ifdef _ARM_
__asm
{
MOV R0,string1
MOV R1,string2
MOV R2,#0
loop:
LDMIA R0!, [R3-R11]
STMIA R1!, [R3-R11]
ADD R2,R2,#8
CMP R2, #400
BNE loop
}
#endif
方法I是最常见的方法,使用了1024次循环;方法J则根据平台不同做了区分,在ARM平台下,用嵌入汇编仅用128次循环就完成了同样的操作。这里有 朋友会说,为什么不用标准的内存拷贝函数呢?这是因为在源数据里可能含有数据为0的字节,这样的话,标准库函数会提前结束而不会完成我们要求的操作。这个 例程典型应用于LCD数据的拷贝过程。根据不同的CPU,熟练使用相应的嵌入汇编,可以大大提高程序执行的效率。
虽然是必杀技,但是如果轻易使用会付出惨重的代价。这是因为,使用了嵌入汇编,便限制了程序的可移植性,使程序在不同平台移植的过程中,卧虎藏龙,险象环生!同时该招数也与现代软件工程的思想相违背,只有在迫不得已的情况下才可以采用。切记,切记。