如何写出很牛的代码,提高你的代码质量?

转自http://blog.csdn.net/yashiz/article/details/1035005

首先要使用C/C++的灵活性,然后要了解,写这些代码,是为了提高效率,而不是做show,好,现在就开始吧。

No1:

scanf("  ")

这里一个空格表示跳一个字符,然后读取,可用于清空前面空格和回车,比如有下面一段程序:

#include <cstdio>
int main()
{
 char nTemp;
 while(true)
 {
 scanf(" %c",&nTemp);
 printf("%c/n",nTemp);
 }
 return 0;
}

可以防止nTemp接收到回车;因为%C会收取回车的。

No2:

如何让scanf接受空格? 由于默认状态在用scanf接受字符串时,会以空格和回车作为结束符。

scanf("%[^/n]s",str);

^表示非,也就是[ ]中的东西在起作用,^/n表示,只要是非回车,就全部接收,所以,这个功能还有下面的用法

scanf("%[Hoj]s",str);

如果input:

Hoiabjo

那么str中字符,将是Hojo.      也就是说,只接受Hoj三种字符。

如果只输入数字,那么可以用[0-9],而不需要[0123456789]

No3:

做ACM-ICPC的朋友肯定再熟悉不过了,就是循环输入,直到遇到流结束符号

可以用 while(scanf("%d",&nTemp)==1){}

或while(cin>>nTemp) {}

都可以达到这个效果。

No4;

printf( "%.* f ",4,fRes);

.*f 是利用一个漏洞(至少有人是这么说的),它将会被4,所代替。

 如下代码:

#include <cstdio>
int main()
{
 float fRes=1.456789;
 int n=5;
 while(n--)printf("%.*f/n",n,fRes);
 return 0;
}

结果是:

1.4568
1.457
1.46
1.5
1

No 5:

充分利用三元操作符,由于它不是一个语句,使得它比if ... else 灵活得多。

#include <cstdio>
int main()
{
 int a,b,c;
 a=1;b=2;
 c=(a>b)?a:b;
 printf("%d/n",c);
 return 0;
}

结果是2;

还有:

for (unsigned i = 0; i < lis.size(); i++)
printf(i+1 < lis.size() ? "%d " : "%d/n", seq[lis[i]]);

可以使结果输出前面n-1个元素,每个后紧跟一个空格,最后一个元素跟一个回车。

达到,如这样的效果: cout<<"Y a s h i z"<<endl;

No6:  ( 参考 http://www.codeproject.com/cpp/complex_declarations.asp )

int RollNum[30][4]; 
int (*p)[4]=RollNum; 
int *q[5];

如这样一些申明,是否了解了?

这里,p被声明为一个指向一个4元素(int类型)数组的指针,而q被声明为一个包含5个元素(int类型的指针)的数组。

& * 的混用也有有趣的效果;
int **p1; // p1 is a pointer  to a pointer  to an int. 
int *&p2; // p2 is a reference to a pointer  to an int.

关于const的运用:

const int *p; 
int const *q;

都是 int的const 指针。也就是说,指向的内容int 不能改变。以上两种效果相差不大: 

而 int * const r= &n;

才真正达到效果, 使得指针不能改变,允许改变内容int.

还有更多这类用法:

char ** p1;         

const char **p2;       

char * const * p3;


const char * const * p4;   

char ** const p5;       

const char ** const p6;    

char * const * const p7;   

 const char * const * const p8;

p1是指向char类型的指针的指针;p2是指向const char类型的指针的指针;p3是指向char类型的const指针;p4是指向const char类型的const指针;p5是指向char类型的指针的const指针;p6是指向const char类型的指针的const指针;p7是指向char类型const指针的const指针;p8是指向const char类型的const指针的const指针。

函数指针 可以达到非常拽的效果:

一起来看看吧: (来自 苍蝇的博客)

int (*p)(char);

这里p被声明为一个函数指针,这个函数带一个char类型的参数,并且有一个int类型的返回值。另外,带有两个float类型参数、返回值是char类型的指针的指针的函数指针可以声明如下:

char ** (*p)(float, float);

那么,带两个char类型的const指针参数、无返回值的函数指针又该如何声明呢?参考如下:

void * (*a[5])(char * const, char * const);

 

“右左法则”[重要!!!]

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 * (* (*fp1) (int) ) [10];

阅读步骤: 
1. 从变量名开始 -------------------------------------------- fp1 
2. 往右看,什么也没有,碰到了),因此往左看,碰到一个* ------ 一个指针 
3. 跳出括号,碰到了(int) ----------------------------------- 一个带一个int参数的函数 
4. 向左看,发现一个* --------------------------------------- (函数)返回一个指针 
5. 跳出括号,向右看,碰到[10] ------------------------------ 一个10元素的数组 
6. 向左看,发现一个* --------------------------------------- 指针 
7. 向左看,发现int ----------------------------------------- int类型


总结:fp1被声明成为一个函数的指针,该函数返回指向指针数组的指针.


再来看一个例子:

int *( *( *arr[5])())();

阅读步骤: 
1. 从变量名开始 -------------------------------------------- arr 
2. 往右看,发现是一个数组 ---------------------------------- 一个5元素的数组 
3. 向左看,发现一个* --------------------------------------- 指针 
4. 跳出括号,向右看,发现() -------------------------------- 不带参数的函数 
5. 向左看,碰到* ------------------------------------------- (函数)返回一个指针 
6. 跳出括号,向右发现() ------------------------------------ 不带参数的函数 
7. 向左,发现* --------------------------------------------- (函数)返回一个指针 
8. 继续向左,发现int --------------------------------------- int类型

总结:??


还有更多的例子:

float ( * ( *b()) [] )();       // b is a function that returns a 
                    // pointer to an array of pointers 
                    // to functions returning floats.

void * ( *c) ( char, int (*)());    // c is a pointer to a function that takes 
                    // two parameters: 
                    //   a char and a pointer to a 
                    //   function that takes no 
                    //   parameters and returns 
                    //   an int 
                    // and returns a pointer to void.

void ** (*d) (int &, 
char **(*)(char *, char **));    // d is a pointer to a function that takes 
                    // two parameters: 
                    //   a reference to an int and a pointer 
                    //   to a function that takes two parameters: 
                    //    a pointer to a char and a pointer 
                    //    to a pointer to a char 
                    //   and returns a pointer to a pointer 
                    //   to a char 
                    // and returns a pointer to a pointer to void

float ( * ( * e[10]) 
  (int &) ) [5];          // e is an array of 10 pointers to 
                    // functions that take a single 
                    // reference to an int as an argument 
                    // and return pointers to 
                    // an array of 5 floats. 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值