-
Beginning C(Ivor Horton)点滴 - [About C]
2008-08-04
1. 随机整数生成
int chosen=0;
srand(time(NULL));
chosen=rand();
注:用stdlib.h中的rand()函数可以生成伪随机数,范围是0到RAND_MAX(已在stdlib.h中定义)。而rand()对于相同种子生成的随机数是相同的,可以用srand()函数的参数向rand()提供种子(srand()在stdlib.h头文件中)。为了每次生成不同的种子,可以使用time.h头文件中的time()函数,此函数返回从1970年1月1日到现在的秒数,用整型表示,time()的参数为NULL。
若要限定随机数的范围:
0到limit:chosen=rand()%limit;
1到limit:chosen=1+rand()%limit;2. 转义字符\a输出铃声
3. 用%p可以输出变量的地址,用十六进制表示,例如,printf("%p",&a);&必不可少。
4. 计算累加可以用以下算法:
for(i=1;i<=count;sum+=i++);或者for(i=count;i>=1;sum+=i--);
而这些循环其实都不必要,直接用公式sum=n*(n+1)/2效率会高得多。5. sizeof()的参数可以是变量,数据类型,数组名,数组元素。
6. 确定边界:头文件limits.h定义了有符号整数类型的上下边界信息,如INT_MAX,对于无符号的,下界总是0。头文件float.h则定义了浮点类型的边界信息,如FLT_MAX。
7. 分数值或小数值通常没有确切的浮点形式表示法,因此依靠等式作为判断结束循环的条件不太明智:
double x=0.0;
for(;x!=2.0;x+=0.2)
printf("\nx=%.2lf",x);
由于0.2没有精确的二进制浮点值表示形式,所以x永远也不会等于2.0,此循环不会结束。8. 二维数组board[][]中,要用board来获取第一个元素的值,需要使用两个间接运算符,即**board。
void main()
{ char board[3][3]={{'1','2','3'},{'4','5','6'},{'7','8','9'}};
printf("value of board[0][0]:%c\n",board[0][0]);
printf("value of board[0] :%c\n",board*[0]);
printf("value of board :%c\n",**board);
}
结果:
value of board[0][0]:1
value of board[0] :1
value of board :19. 动态内存分配:malloc()函数的使用
首先需要加入头文件stdlib.h,函数返回所分配的第一个字节的地址,所以,最好用指针保存返回值。
int *pNumber=(int*)malloc(100);表示分配100个字节的内存,将其地址赋予pNumber,因为int类型占2字节,所以可以存50个int值。
int *pNumber=(int*)malloc(100*sizeof(int));直接申请100个int类型的空间。
由于malloc()是个通用函数,可以分配任何数据内型的数据,所以它的真正返回值是void型指针(void*),void没有明确类型可以执行任何类型的数据,而void型指针所指的值却不能被提取,所以必须加(int*)转换其类型。
如果malloc()由于某种原因分配内存失败,将返回NULL值,所以在使用函数后,用if(pNumber==NULL)来检验是个好习惯。10. getchar循环方式输入:
char buffer[100];
char* pBuffer=buffer;
while((*pBuffer++=getchar())!='\n');
*pBuffer='\0'; /* 用'\0'覆盖了'\n',表示字符串结束 */11. 可变参数的函数:
#include "stdio.h"
#include "stdarg.h"
double average(double a1,double a2,...)
{
va_list parg;
double sum=a1+a2;
double value=0;
int count=2;
va_start(parg,a2);
while((value=va_arg(parg,double))!=0.0)
{
sum+=value;
count++;
}
va_end(parg);
return sum/count;
}main()
{
printf("%lf",average(3.0,9.0,12.0,0.0));
getch();
}
解释:va_start()需要两个参数,第一个是va_list型指针parg,第二个是要编写的函数指定的最后一个固定形参的名字,函数作用是把变量parg设置为调用该函数时传递给它的第一个可变参数。
va_arg()第一个参数是通过调用va_start()初始化的变量parg,第二个变量是说明了希望找到的参数的类型。函数返回的是parg指定的当前参数的值,该值存在value中。它还会更新parg,根据函数调用中指定的参数类型,使它指向列表中的下一个参数。但指定类型不正确的话就不能正确获得下一参数。但得到的值未标示结束的值时(此处是0.0),循环将结束。
va_end()把parg重置为NULL,该函数不可缺少。变长参数列表的基本规则:
1。在接受参数个数可变的函数中,至少有一个固定参数。
2。必须调用va_start()函数初始化函数中的可变参数列表指针的值。还要把该指针声明为va_list型的。
3。需要有一种方法决定每个参数的类型。最好全部参数同一类型。
4。必须安排某种方式确定参数列表的结尾。
5。对于参数类型应有一定限制,如不要使用char,unsigned char或float。可以用int代替char,用double代替float。
6。退出参数可变函数时,一定要调用va_end()。
7。以上所有操作只适用ANSI C,UNIX的实现于这些有很大区别。注:在win-tc上运行正常,在visual studio2008上运行出错:找不到表示符va_list等,while((value=va_arg(parg,double))!=0.0)语句出错。
12. void main(int argc,char *argv[])的两个参数:
第一个参数是int型,表示在执行main()函数的命令行中要输入的实参的个数,其中包括程序名自身,argc值至少为1。第二个参数是一个字符串指针数组,第一个指针指向程序名,其后顺序指向main()命令行中要输入的实参。
main(int argc,char *argv[])
{ int i=0;
printf("%s\n",argv[0]);
for(i=1;i<argc;i++)
printf("%d: %s",i,argv[i]);
getch();
}13. 格式化输入:
double a;
char str[]="%lf";
scanf(str,&a);
printf("%lf",a);
与
double a;
scanf("%lf",&a);
printf("%lf",a);
效果一样。char a[10],b[10];
scanf("%[aeiou]%[^o]",a,b);
printf("%s,%s",a,b);
注:%[aeiou]表示只读入方括号内的值,输入中第一个不属于的值标志这个输入结束,%[^o]表示除了o以外字符都接受。14. scanf返回的是读入输入值的个数k=scanf("%s%s",a,b);k=2。
15. int siblings(struct family *member1,struct family *member2)
最原始形式,指针所指的内容可以被改变。
int siblings(struct family const *member1,struct family const *member2)
把形参声明为指向常量family结构的指针,即传递给函数的指针所指的结构在函数内部将被作为常量处理,起到保护数据的作用。
int siblings(struct family *const member1,struct family *const member2)
形参是指向family型结构的常量指针,所指的结构可以改变,指针本身不能改变,保护的是指针,而不是所指的内容。16. 预处理器指示必须是一个逻辑行,不过并不妨碍使用语句继续字符\,你可以编写以下代码:
#define min(x,y) \
((x)<(y)?(x):(y))
注意,\必须是一行的最后一个字符,紧接在按下Enter键之前。17. 想在一个宏中生成两个结果,把它们连接起来,中间没有空格
#define join(a,b) ab 这个宏不能实现此效果,宏扩展定义会把它解释成ab
我们可以通过分隔参数符##来实现
#define join(a,b) a##b
例如:
strlen(join(var,123));将生成下面语句strlen(var123);18. 宏__DATE__提供了日期字符串的表示,格式为mmm dd yyyy
printf("%s\n%s",__TIME__,__DATE__) ;
宏__TIME__存放的是时间值得字符串,格式是hh:mm:ss19. 关于assert()宏
assert()的参数是一个值为整数的表达式,如果表达式为0,它将用一条诊断消息中断程序。它定义在assert.h头文件中。
宏assert()的功能有开关控制,#undef NDEBUG时,宏起作用;想禁用断言时,可以#define NDEBUG。
如:
#undef NDEBUG
#include "stdio.h"
#include "assert.h"main()
{ int a=1,b=0;
assert(a==b);
printf("ok") ;
getch();
} -
Ubuntu的中文法 - [About Linux]
2008-08-03
首先要添加中文包,然后在语言支持中选中汉语,最后在SCIM输入法设置里添加中文的输入法,ok。不过安装超慢,我一于训教唔理,早上起身就装好了。以前遇网不淑,教人输入一大堆狗屎垃圾,结果得个橘,原来方法其实好简单。
中文包方法
sudo apt-get install language-support-zh language-pack-zh当然有时候会出现“无法找到软件包 language-support-zh”的情况,呢个大概系源的问题,如果是在已连接网络的情况下安装ubuntu,可能不会出现这个问题,解决方法是更新,不嫌麻烦的话可以换源之后再更新。
更新在终端输入:sudo apt-get update
完毕之后再装中文包应该就可以了。







