Ugly Code
看到几行令人纠结的代码:
const int size = 1000; // array of 1000 integers int array [size]; int n = 0; // read an integer into the n+1 th element of array while (cin >> array[n++]); n--; // it got incremented once too many times //下面处理array与n的代码省略
搞不明白这里
while (cin >> array[n++]); n--; // it got incremented once too many times
为什么要这样,明明可以这样写的
while (cin >> array[n])n++;
这种代码看的让人蛋疼。
gcc中关于C/C++标准的选项
man gcc里面说到gcc使用指定的标准编译C/C++的选项是:-std=standard,其中standard可以是
c89(传说中的c89)
iso9899:1990
Support all ISO C90 programs (certain GNU extensions that conflict with ISO C90
are disabled). Same as -ansi for C code.
iso9899:199409
ISO C90 as modified in amendment 1.
c99(传说中的c99)
c9x
iso9899:1999
iso9899:199x
ISO C99. Note that this standard is not yet fully supported; see
<http://gcc.gnu.org/gcc-4.2/c99status.html> for more information. The names c9x
and iso9899:199x are deprecated.
gnu89
GNU dialect of ISO C90 (including some C99 features). This is the default for C code.
gnu99
gnu9x
GNU dialect of ISO C99. When ISO C99 is fully implemented in GCC, this will
become the default. The name gnu9x is deprecated.
c++98
The 1998 ISO C++ standard plus amendments. Same as -ansi for C++ code.
gnu++98
GNU dialect of -std=c++98. This is the default for C++ code.
还有一个选项就是-ansi,上面也说到了。
以上是在gcc4.2.4里面看到的。
《编程之美》中不要被阶乘吓倒的一个注解
这一节中的第二个问题:求N!的二进制表示中最低位1的位置。其中第二个解法提出N!含有质因数2的个数等于N减去N的二进制表示中1的数目,不过没有给出证明,自己推导了一下,如下所示。
假设N=anan-1...a1a0,其中ai属于{0, 1},an=1。由于N!中含有质因数2的个数为
[N/2] + [N/4] + [N/8] + [N/16] + ...
=anan-1...a1 + anan-1...a2 + ... + anan-1 + an = S (1)
以上式子两边同时乘以2,得到
anan-1...a10 + anan-1...a20 + ... + anan-10 + an0 + 0 = 2S (2)
(2) - (1)错位减,得到:
anan-1...a10 - a1 - a2 - ... - an=S
整理得到
N-(a0 + a1 + a2 + ... + an) = S
注意到ai属于{0, 1},因此就得到证明。
Linux目录权限相关问题
最近老是忘记这个东西,现在总结一下不然下次又忘掉了。
R:就是读权限,用ls命令的的时候必须有这个权限,但是单纯的R权限又没有多大作用,一般是要带X(执行)权限。
W:写权限,比较好理解,删除,修改,创建文件都需要写权限,需要W权限的相关命令是mv,rm等等,但是依旧有一个问题,如果没有X权限还是没多大用处。
X:执行权限,如果在文件上的话比较好理解就是“可执行”的意思,但是用在目录这里则是表示“可以进入”的意思,就是你要进入这个目录时候就要求这个权限,比如cd,ls命令都需要相应目录的X权限。
C语言结构体赋值相关
看UNPv1的时候,在第四章看到ipv6结构体的赋值,里面说到C语言的结构体变量无法直接赋值为该结构的常值结构,但是可以用变量赋值,并且如果是初始化的时候也是可以的,废话少说,还是上代码说的明白:
typedef struct A { int a; char b; } A; int main() { A b = {2, 'b'}; //OK A a = {1, 'a'}; //OK /* a = {1, 'b'} //非法,结构体赋值不能用常量结构赋值,不过可以这样: */ a = b; /* 合法,b是同类型的结构体变量 */ return 0; }
C语言预处理指令总结
预处理指令严格来说不属于程序语句的一部分,所有的预处理语句在程序编译之前被预处理器处理完成。每一条预处理语句总是以"#"字符开始,并且不能超过一行,一旦遇到换行符语句就被当做结束。一般来说,预处理语句的后面不能加分号。另外,唯一的一种能将预处理语句扩展到多行的办法就是在换行符之前加一个反斜杠('\')。
宏定义(#define,#undef)
#define指令主要用于定义常量还有就是定义带有参数的”函数“。
#define PI 3.1416 #define MAX(a,b) (a)>(b)?(a):(b)
有一个值得注意的就是括号的使用。
#undef用于取消之前定义过的宏定义。
”函数“型宏定义接受两个特殊的运算符(#,##)
使用#使得#之后的第一个参数作为一个带引号的字符串返回。例如
#define str(x) #x cout << str(test);
被处理后相当于
cout << "test";
使用##连接##之前和之后的内容。例如
#define glue(a,b) a ## b glue(c,out) << "test";
处理后相当于
cout << "test";
条件包含指令(#ifdef, #ifndef, #if, #endif, #else ,#elif)
#ifdef micro some codes here #endif
如果宏被使用#define 定义,命令后边的代码被编译。
#if expression some code here #endif
如果表达式为真,命令后边的代码被编译。
#ifndef跟#ifdef相反。
#if 和#elif后面 的表达式用于比较操作时候只允许用整数。例如
#if VERBOSE == "on" // NOT ALLOWED print("trace message"); #endif #if VERBOSE >= 2.0 // NOT ALLOWED print("trace message"); #endif
另外,#ifdef和#ifndef也可以分别用运算符 defined 和 !defined取得相同的效果。例如
#if !defined TABLE_SIZE #define TABLE_SIZE 100 #elif defined ARRAY_SIZE #define TABLE_SIZE ARRAY_SIZE int table[TABLE_SIZE];
行控制(#line)
语法:
#line line_number "filename"
#line命令可以简单的改变下一行__LINE__
和__FILE__
的值,文件名是可选的,__LINE__
和__FILE__
表示当前文件名和当前行的行号。
这条命令
#line 10 "main.cpp"
…改变更改下一行行号改为10,当前文件名为”main.cpp”。
错误指令(#error)
#error message
当编译器遇到#error命令的时候会被迫停止编译,并输出错误信息和出错行号
文件包含(#include)
最常用,一共有两种方式
#include "file" #include <file>
双引号表示在当前目录搜索,然后在系统定义的目录搜索,而尖括号表示直接在系统目录搜索。
Pragma 指令(#pragma)
#pragma lexems
#pragma命令赋予程序员控制编译器的能力,由于#prama的实现依赖于编译器,使用方法因编译器而异。一个选项可能完全改变程序执行顺序。
预定义的宏名
__LINE__ __FILE__ __DATE__ __TIME__ __cplusplus __STDC__
-
__LINE__
和__FILE__
变量记录了编译器的当前处理行和当前处理文件。 -
__DATE__
变量包含当前文件被编译的日期,格式为:月/日/年。 -
__TIME__
变量包含当前文件被编译的时间,格式为:时:分:秒。 -
__cplusplus
变量只有在C++程序中才被定义;一些老编译器也可以为c_plusplus
。 -
__STDC__
变量在编译C程序的时候被定义,许多编译器在编译C++代码时也会定义此变量。
Reference:
- www.cppreference.com/wiki/cn/preprocessor/start
- en.wikipedia.org/wiki/C_preprocessor
- www.cplusplus.com/doc/tutorial/preprocessor/
[面试题]找规律
2
12
1112
3112
132112
——————————
请问下一行是什么并说说规律?
答案:
1113122112
这个是王小云在ccav上做节目时用到的,除第一行外,每一行都是在描诉上一行,12表示有1个2,1112表示1个1,1个2,依次类推。
Mathematica 计算显示“running”情况的解决
mathematica是个好东西,但是最近不知道什么地方出现了问题,老是无法正常工作。具体表现是:当你输入表达式计算的时候,老是显示“running”。其实那些表达式都是类似“1+1”的简单表达式,看到老是显示“running”感觉真是无话说了。
这个奇怪的问题一直困扰了好几天,今天晚上把软件重新安装一下,结果还是出现那讨厌的“running”,无奈只能搜索,找了一下大概知道问题所在了。有人说是Mathematica显示“running”是因为在后台启动他的内核程序,如果电脑配置比较低的话会比较慢,但是我的电脑配置也没那么低啊,等了好几分钟它还在算“1+1”简直让人哭笑不得。后来看到一个解决方法就是把MathKernel进程杀掉。打开任务管理器,杀掉Mathkernel进程,重新计算“1+1”,问题解决,测试其他的功能也都恢复正常。
windows下qt链接的问题
最近在windows玩qt。
晚上在google code下载了一个项目的源代码,编译没有什么问题,在qt creator下面运行也是没有什么问题,但是直接到代码目录底下运行就产生奇怪的问题了,无论是debug下面还是release下面,release还好程序能运行,不过有奇怪的问题产生。于是搜索了一下,在这里找到了答案,按照里面说的,把路径设置了一下之后就ok了,不过那几个动态链接库还真是有点大啊,总共有十几M,假如写一个小软件的话光那几个库文件就受不了,静态链接的时候不知道有多大呢。
另外,悼念一下谷歌中国。