整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

从零开始C语言-02 命名方式and基本数据类型

从零开始C语言-02 命名方式and基本数据类型

命名方式

任何程序员都应该保持一个良好的编码习惯,以便于以后的维护

常见的命名方式分别有

驼峰命名法、匈牙利命名法、帕斯卡命名法和下划线命名法,其中前三种是较为流行的命名法

  1. 骆驼式命名法就是当变量名或函数名是由一个或多个单词连结在一起,而构成的唯一识别字时第一个单词以小写字母开始;从第二个单词开始以后的每个单词的首字母都采用大写字母,如:myFirstName、myLastName,这样的变量名看上去就像骆驼峰一样此起彼伏,故得名。
  2. 匈牙利命名法。广泛应用于象Microsoft Windows这样的环境中。Windows 编程中用到的变量(还包括宏)的命名规则为匈牙利命名法,这种命名技术是由一位能干的 Microsoft 程序员查尔斯-西蒙尼(Charles Simonyi) 提出的。如:m_lpszStr
  3. 帕斯卡(pascal)命名法。与驼峰命名法类似,二者的区别在于:驼峰命名法是首字母小写,而帕斯卡命名法是首字母大写,如:DisplayInfo(); string UserName;

基本数据类型

  1. char为一个字节
  2. short为两个字节
  3. int为4字节
  4. float为4字节
  5. double为8字节
  6. long为4字节
  7. long long 为8字节
  8. __int32为4字节
  9. __int64为8字节
int main()
{
	char ch='h';
	short sh=5;
	int n=10;
	float lf=3.14f;
	double dbl=9.65000;
	long l=1016;
	long long ll=10647;
	__int32 i32=45;
	__int64 i64=8963210;
	printf("ch=%c and siezof=%d\r\n", ch,sizeof(ch));
	printf("sh=%d and sizeof=%d\r\n",sh,sizeof(sh));
	printf("n=%d and sizeof=%d\r\n", n, sizeof(n));
	printf("lf=%lf and sizeof=%d\r\n", lf, sizeof(lf));
	printf("dbl=%f and sizeof=%d\r\n", dbl, sizeof(dbl));
	printf("l=%d and sizeof=%d\r\n", l, sizeof(l));
	printf("ll=%lld and sizeof=%d\r\n", ll, sizeof(ll));
	printf("i32=%d and sizeof=%d\r\n", i32, sizeof(i32));
	printf("i64=%I64d and sizeof=%d\r\n", i64, sizeof(i64));
	return 0;
}


程序运行结果

printf可以留着明天学啦。


在我们平时刷题的时候,你可能会写过很多诸如

int a,b,c
int [] arrays=new int arrays[10];
if((numbers > 10 && flag=='true') || flag=='false')

这种代码,对于我们自己练习编程或者解决一个算法题,当然没有问题。但是如果是在一个工程中,尤其是几十上百人维护了几年的工程中,还使用这种写法,倾泻自己天马行空的才华,保证leader不打死你哦。

所以,对于代码的整洁性,可读性,自古以来就有很多大神做出过总结,比如这本《clean code》,中文名叫做《代码整洁之道》,今天,我们就来看看吧。

命名

命名思想

首先就是命名,命名可以说是一切程序的基础,如果用三个字来形容那就是——“有意义”。

你要做到,当一个人看到你的命名,就知道这个变量/函数是干什么的

来看这一段代码:

public List<int[]> getThem() {
  List<int[]> list1=new ArrayList<int[]>();
  for (int[] x : theList)
    if (x[0]==4)
      list1.add(x);
  return list1;
}

这段代码非常简洁,但是非常模糊,我们不知道theList到底是什么,为什么x==4作为判断,list1又是什么?

现在我们来改一改:

public List<int[]> getFlaggedCells() {
  List<int[]> flaggedCells=new ArrayList<int[]>();
  for (int[] cell : gameBoard)
  if (cell[STATUS_VALUE]==FLAGGED)
  flaggedCells.add(cell);
  return flaggedCells;

复制代码

从上面的代码中,我们可以马上看出来,flaggedCells表达的是标致cell,而cell位于gameBoard中,就是一个游戏面板,只需要再通过文件名,知道这是一个【扫雷游戏】,那么cell就是每一个格子,if语句中就是判断每一个格子是否被点击过,如果是,就添加到flaggedCells中,我们显然知道他想要干什么——搜集玩家点击过的格子并返回。

但是,上面的代码吗使用的是 int 数组,比如int[] cell,每一个数组内部的数表示cell的状态,可是cell并不需要那么多状态,而且这样导致每次使用这个状态的时候都要重新定义数组,状态是cell的一个属性,所以,完全可以定义一个cell的类,将他的状态封装进入。

public List<Cell> getFlaggedCells() {
  	List<Cell> flaggedCells=new ArrayList<Cell>();
    for (Cell cell : gameBoard)
    if (cell.isFlagged())
    flaggedCells.add(cell);
    return flaggedCells;
}

这样子很清晰看出,gameBoard由Cell组成,从gameBoard中取出标记过的cell放入flaggedCells中,这样的代码是不是感觉浑然天成,自然而然呢?

命名规范

通过以上事例,你应该理解在写工程项目时,诸如数组,链表,字典这些底层结构应该要封装在User,Cell,Address这种类中,使用的时候直接使用这些类即可,这是一种大局观的思维,现在我们来做一些较为细节的落地规范。对于什么驼峰命名,匈牙利命名我相信你不会陌生,但是我在这里再强调两个地方。

  • 类名 类作为一个对象,需要的是名词或者名词短语,gameBoard,Ueser都是如此,不要使用模糊名词(就是概念很大的名词),比如Data,因为可以细分为UserData,MoneyData等,对于可以细分的模糊名词,一定要用名词短语。 类名都是第一个字母大写的名词组合。
  • 方法名 方法作为具体干事的执行者,当然是使用动词或者动词短语了,同样注意的是,不要使用模糊动词,和上面不一样的是,解决模糊名词的方法是增加名词修饰,而解决模糊动词的方法是【换更精准的动词】 比如getInformation,就不好,因为get太大了,你的information是pull过来的还是clone过来的?是被动接受的还是主动去取的?Information这个词也很模糊,所以可以根据情况拆分为直接取用户数据——fetchUserData,上传新数据再取用户数据——uploadAndfetchUserData。 不是不能用get,是说如果有更好的选择,尽量用更精准的动词。 注意方法名第一个字母小写。

函数

第一原则

短小

如果还有第二原则,那还是短小。

短小到什么程度,最多20~30行吧,

所以要求,一个函数,只做一件事情

什么叫做只做一件事情呢?

就拿处理数据来说,我们说【处理用户数据】是一件事,你也可以说是做了三件事:

  1. 取数据
  2. 处理数据
  3. 返回数据

当然,这个例子有点抬杠的意思,不过反映的现实是,代码中各种逻辑往往你中有我,我中有你,到底一件事情的边界在哪里?

这个因人而异,我只能提出书中的方法。

  1. 同一抽象级 刚才那个取数据,就是在同一抽象级下完成的事情,就可以看做是一件事,如果再来一件——保存用户数据,显然,可以归到前面,还是一件事,如果再来一件——取车辆数据,显然,就是另外一个抽象的东西了。
  2. 分割判定与处理 这个好理解,就是立法与司法的分割,比如: if (set("username", "unclebob")) ... 复制代码就让人迷惑,他表达的意思是不是如果unclebob成功赋值给username就返回true呢?还是说如果username为null时就用unclebob 赋值进入呢?username到底是属性还是碰巧一个字符串叫做username呢?随便猜。 但是我们这样修改: if (attributeExists("username")) { setAttribute("username", "unclebob"); ... } 复制代码如果有username这个属性,就赋值,非常清晰,也就是说,判定与处理要分隔开。

你可能会说,对于像if,while,switch这种语句,往往动辄十几行,短不了啊!

首先,这个原则不是铁律,实在太长也没办法

其次,对于这些语句,完全可以讲里面的逻辑做一个封装,比如这种:

public static String renderPageWithSetupsAndTeardowns(
  PageData pageData, boolean isSuite) throws Exception {
  if (isTestPage(pageData))
    includeSetupAndTeardownPages(pageData, isSuite);
  return pageData.getHtml();
}

if 语句之后做了一件includeSetupAndTeardownPages的事情,不仅极大增强了可读性,而且代码短了不少。

关于参数

当你看jdk源码或者是android源码的时候,你会发现他们经常做调用,尤其是同名的方法重载,在看《算法》这本书的时候,也是,比如关于快速排序的:

public static void quickSort(int [] arrays){
  quickSort(arrays,0,arrays.length-1);
}
private static void quickSort(int [] arrays,int left,int right){
  ...
}

我在一开始接触的时候,觉得虽然好看,但未免麻烦,随着经验的提升,这是一种非常好的编程习惯。

首先,对于用户来说,他想要进行快排,想传的只有数组,左右边界都包含进去了,你为什么要他多传参数?同时第一个方法使用的是public,就表示这是暴露给用户的。

其次,第二个方法在第一个方法中被调用,用private保护了起来,避免了无数麻烦

所以,越是业务层的逻辑,越要写参数少的代码,如果参数必须要很多,那就用一个private的函数封装起来,你让用户拥有一百个参数输入,对他来说,那不是自由,那是灾难。

苹果和微信的使用体验就是将这种哲学贯彻到极致的代表。

注释

最好的注释,就是代码本身

用代码能解释清楚的事情,尽量少用注释,如果注释太多,只能证明代码写得烂……

不过有些地方还是有必要写代码的。

位置

最好写在方法顶部,不插入到实际代码中,比如那个面试几乎必问的String中的equals方法,源码如下:

 ... 
 * @see  #compareTo(String)
 * @see  #equalsIgnoreCase(String)
 */
public boolean equals(Object anObject) {
    if (this==anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString=(String)anObject;
        int n=length();
        if (n==anotherString.length()) {
            int i=0;
            while (n-- !=0) {
                if (charAt(i) !=anotherString.charAt(i))
                        return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

警示的注释

这里可以写一些告诫他人的代码,让后来的接盘侠能够引起重视。

//When I wrote this, only God and I understood what I was doing
//Now, God only knows

简单说就是,下面的代码一定有用,但是我也看不懂了,你别碰O(∩_∩)O哈哈~

在知乎上看到还有这样的。

//如果这段报错,你在机器上装一个360安全卫士,相信我我
以为是开玩笑,结果装了就真的好了。这个是前人留给我的。
//这个服务有问题的话,你可以问某某某,这段是他写的。
这个是在我离职交接时写的,出卖了未离职的一个同事。
//执行成功后发送一条通知短信,稳定后注释掉
手机号是写死的,我看到这段的时候还没有注释,这一年每天凌晨他都能收到短信。

这些人水平怎么样另说,但是对于后人还是用心的。

TODO注释

这个就不说了,很常用。


看完了有用的注释,我们来看看没用的注释

多余的

// Utility method that returns when this.closed is true. Throws an exception
// if the timeout is reached.
public synchronized void waitForClose(final long timeoutMillis)
  throws Exception
  {
		if(!closed)
	{
  wait(timeoutMillis);
  	if(!closed)
  		throw new Exception("MockResponseSender could not be closed");
  }
}

这就是把代码做了什么又描述一遍,没有任何意义。

被注释掉的代码

InputStreamResponse response=new InputStreamResponse();
response.setBody(formatter.getResultStream(), formatter.getByteCount());
// InputStream resultsStream=formatter.getResultStream();
// StreamReader reader=new StreamReader(resultsStream);
// response.setContent(reader.read(formatter.getByteCount()));

相信很多人都有这样的行为,在自己写算法题的时候用来测一测没有任何问题,但是对于后来者来说,他该怎么办?

他一定会想:也许是有用的呢?不然为什么之前要写。

但是他又看不懂或者觉得没必要看,于是就留了下,然后这样的代码就会越来越多,最终成为传说中的祖传代码。

不用心

注释要清楚,如果注释还要写注释来解释,根本没有意义。

比如下面这个,为什么要用200?

/*
* start with an array that is big enough to hold all the pixels
* (plus filter bytes), and an extra 200 bytes for header info
*/
this.pngBytes=new byte[((this.width + 1) * this.height * 3) + 200];

小结

对于多数人来说,命名函数与注释基本上就是程序的主要组成部分,能够处理好这三样就能写出非常好的代码了,当leader看到你的提交的时候,看到的是如此优雅的代码,我想,他也会觉得是一种享受吧,就和诗歌一样。

作者:神鹰梦泽

链接:https://juejin.im/post/5f14043b6fb9a07e802055ce

来源:掘金

ello,大家好,暖宝给大家带来js新的干货,觉得文章不错,点击右上角关注暖夕H2

ECMAScript和Dom和Bom的区别

ECMAScript是一种由Ecma国际(前身为欧洲计算机制造商协会,英文名称是European Computer Manufacturers Association)通过ECMA-262标准化的脚本程序设计语言。这种语言在万维网上应用广泛,它往往被称为JavaScript或JScript,但实际上后两者是ECMA-262标准的实现和扩展。它是一种翻译核心解释器,ECMAScript实际上是一种脚本在语法和语义上的标准。

Dom文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标志语言的标准编程接口,它是操作Html的一种能力。

Bom BOM(Browser Object Model) 是指浏览器对象模型。

undefined的情况定义

1》未定义

2》变量定义为空

parseInt()与parseFloat()

parseInt()用来转整数,parseFloat()用来转小数

隐世类型转换

“==”先转换类型后比较

“===”不转换类型,直接比较

举例:

作用域

局部变量在定义的函数里使用,全局变量在任何地方都能够使用

闭包:子函数可以使用父函数的局部变量

举例:

变量命名规则

变量的命名规则为可读性,易看懂,规范性。

匈牙利命名法是由匈牙利程序员Charles Simonyi发明的一种编程语言中对变量进行命名的规范。基本原则是:变量名=属性+类型+对象描述,其中每一对象的名称都要求有明确含义,可以取对象名字全称或名字的一部分。要基于容易记忆容易理解的原则。保证名字的连贯性是非常重要的。

举例:表单的名称为form,那么在匈牙利命名法中可以简写为frm,则当表单变量名称为Switchboard时,变量全称应该为 frmSwitchboard。这样可以很容易从变量名看出Switchboard是一个表单,同样,如果此变量类型为标签,那么就应命名成lblSwitchboard。可以看出,匈牙利命名法非常便于记忆,而且使变量名非常清晰易懂,这样,增强了代码的可读性,方便各程序员之间相互交流代码。

好了,今天干货到这里了,记得关注暖夕H2,更多好的技术干货带给你。