黑马程序员-----高质量C语言编程

---------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------

高质量C语言编程


一、函数设计
1、参数规则
1>参数命名有象征意义最好,eg:srcDestination
2>目的参数在前
3>如果参数是指针,且仅做输入,应该在类型前加const,防止指着在函数体内被以外修改
4>如果参数以值传递的方式传递对象,则改用“const&”方式传递,这样可以省去临时对象的构造和析构过程,从而提高效率
2、返回值
1>函数名与返回值类型在语义上要一致,不可冲突eg:int getchar(void)返回值居然是整型
2>正常值用输出参数获取,而错误标志用return语句返回eg:getchar(void)改为bool GetChar(char *c)
3>如果返回值是一个对象,有些时候可以用“引用传递”替换“值传递”提高效率,有些时候只能用“值传递”
4>return语句不可以返回指向“栈内存”的指针或者“引用”,因为该内存会在函数结束时被销毁eg:
char *Func(void)
{
char str[] = "hello world";//str内存在栈内存上,跟后面的"hello world"字符串没有多大关系
  //只是将该字符串拷贝到str所在的栈内存空间而已。


...


return str;//将导致错误因为在Func调用结束后,str数组的栈内存空间已经被系统销毁,
  //不会影响在静态区的字符串"hello world"那么对这块内存的读写将是非法的
}
5>return时候如果是返回对象注意效率性检查eg:
return String(s1 + s2);//编译器直接把临时对象创建并初始化在保存返回值的外部存储单元,省去拷贝和析构的消耗


String temp(s1 + s2);
return temp;           //这两句编译器需要创建temp对象并初始化,而后将构造函数和temp的值拷贝到外部存储单元
3、函数体
1>在函“入口处”对参数进行有效性检查用assert(断言)eg:
void *memcpy(void *pvTo, const void *pvFrom, size_t size)
{
assert((pvTo != NULL) && (pvFrom != NULL));//断言,参数检查


}
2>尽量不使用static局部变量,除非必需的,因为带有记忆功能的函数,其行为是不可预测的


二、内存处理
1、内存的分配方式
1>从静态存储区分配eg:static变量,全局变量,常量
2>在栈上分配eg:局部变量
3>从堆上分配,亦称为动态分配
2、内存误区
1>内存必须分配成功再去使用malloc之后应检查指针是否为NULL
2>分配成功但是没有初始化就使用
3>野指针,对已经释放的内存进行操作
4>内存操作越界,只要是数组越界。
5>内存泄露,使用完内存必须进行内存的释放。
6>内存释放后即free和delete之后一定要将p = NULL;
3、指针,引用和数组
1>指针和数组
①数组名只是一个符号,既不是引用也不也是指针
②当数组名作为函数参数进行传递时,该数组自动同类型的指针
③例子
char *Func1(void)
{
char str[] = "hello world";//str内存在栈内存上,跟后面的"hello world"字符串没有多大关系
  //只是将该字符串拷贝到str所在的栈内存空间而已。
...


return str;//将导致错误因为在Func调用结束后,str数组的栈内存空间已经被系统销毁,
  //不会影响在静态区的字符串"hello world"那么对这块内存的读写将是非法的
}


char *Func2(void)
{
//char str* = "hello world";
char str* = (char *)malloc(sizeof(char)*100);
strcpy(str,"hello world");//str指向的是hello world字符串在静态存储区的地址,
//,不存在像数组一样的拷贝问题,生存周期直到整个程序结束
return str;
}


2>引用和指针
①引用是一个变量别名就是变量本身,而指针是一个变量,用于存放另一个变量的地址。
②引用必须与一个合法存储单元关联,不能是NULL而指针可以是NULL
③引用被创建的同是必须被初始化,而指针可以在任何时候被初始化;
而且引用一旦被初始化就不能改变引用的关系,而指针则可以随时改变指向


三、小零碎点
1、合理空格或者空行
1>逗号","语句的每个逗号","后面加空格eg:void(int a, int b);
2>如果分号";"不是本行的结束,在";"后面添加空格eg:for(int i; i < 10; i++)
3>二元的操作符前后夹空格eg:+,-,*,/,=,&&,||等等
2、对齐
长表达式要在低优先级操作符处拆分成新行,操作符放在新行之首,突出操作符eg:
if((条件表达式1)
  && (条件表达式2)
  && (条件表达式3))
3、*和&修饰符应该紧靠变量名
4、for循环语句
1>多重循环,应当将最长的循环放在最内层,最短的循环放在最外层,减少CPU跨切循环层的次数
2>如果循环体内存在逻辑判断,并且循环次数很大,宜将逻辑判断转移到循环体外面,不能让逻辑判断打断循环“流水线”,
这样这样编译器就不能对循环做出相应的优化eg:
for(int i = 0; i < N; i++)
{
if(condition)
DoSomething();
else
DoOtherting();
}
//循环程序简洁,但是效率低


if(condition)
{
for(int i = 0;i < N;i++)
DoSomething();
}
else
{
for(int i = 0;i < N;i++)
DoOtherthing();
}
//循环程序不够简洁,但是效率很高


当然如果N比较小那么区别不是很大,如果N比较大应该采用第二种结构


5、基本数据类型占用空间较小的放在前边声明。较大的放在后边。这样占用的内存空间就会相对小很多。类数据成员内存分配规则和结构体也是一样的。 (引用自黑马论坛)


---------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------详细请查看:www.itheima.com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值