好久没有看C语言的东西了,很多知识点都变得生疏了!在此梳理一下,将已经遗忘的东西记录下来!
1、关于浮点数的打印格式问题
%nf是打印浮点数,至少n位字宽。%n.mf是打印浮点数,至少n位字宽,小数点后有m位小数。
2、getchar()的参数是int类型,之所以声明成int类型,是考虑getchar应该能接受文件结束服EOF,EOF是定义在中的一个整数值,和所有的char类型值都不一样。它的值为-1。
3、由于在编程过程中,容易混淆==和=,所以在使用相等比较时尽量把常量方在前面,例如
if(4==a){……}这样如果误用的话,编译器会报错。
4、一个经典程序(统计行数,字符数和单词数)
#include
#define IN 1
#define OUT 0
int main(void)
{
int c,nc_row,nc_char,nc_word,state;
nc_row = nc_char = nc_word = 0;
while((c=getchar())!=EOF)
{
nc_char++;
if('\n' == c)
{
nc_row++;
}
if(' ' == c || '\n'== c || '\t' == c)
{
state = OUT;
}
else if(OUt == state)
{
state = IN;
nc_word++;
}
}
printf("%d %d %d\n",nc_row,nc_char,nc_word);
}
这个程序中有几点需要在以后的程序设计中借鉴:
state状态控制方法,if判断中考虑||从左到右的结合和前者为1后者不做判断的特性,将最常见的空格放在了第一位,还有就是用于state的幻数,没有直接使用0和1,而是采用了符号常量,便于修改!
5、经典函数strlen的实现:
int strlen(const s[])
{
int i = 0;
while(s[i] != '\0')
++i;
return 1;
}
strcpy的实现:
int strcpy(char *src,char *des)
{
while((*des=*src) != '\0')
;
}
strcpy的第二个参数应该是一个字符串常量。该函数就是利用判断第二个参数的结束符来得到是否拷贝完毕。
6、区分字符常量和只含有一个字符字符串:
‘x’表示一个整数,用于产生字符x在机器字符集中的数值,即内部表示值,而“x”是表示只含有字符x和‘\0’的字符数组。
7、关于变量初始化
非自动变量的初始化一般只初始化一次,而且应该在程序开始执行之前进行,此时要求初始化符必须为常量表达式,显式初始化的自动变量在每次进入其所在的函数或分程序时都会被初始化一次。其初始化符可以是任意表达式,外部变量和静态变量的默认初始值是0,未经显式初始化的自动变量的值为未定义。
8、运算符的优先级
&&的优先级高于||,但是二者的优先级都低于比较运算符,赋值运算符的优先级低于&&和||。如if((c=getchar())!=EOF){……} b=c>='0'&&c<='9'
9、类型转化中的问题
尽量不要对无符号数和有符号数进行比较,系统在自动进行类型升级时,有可能造成错误产生。例如:
-1L<1U 因为int的1U被提升为signed long的类型
-1L<1UL 因为long类型的-1L被提升为unsigned long类型,成了一个很大的正数。
10、初始化为非零值的静态分配数据和全局数据存在数据段中,运行相同程序的每个进程都有自己的数据段。
未初始化的全局或静态变量和初始化为零值的静态分配数据和全局数据存放在进程的BSS区域内。
可以用nm和readelf来测试一下。
从 C/C++ 语言的角度出发,对象的存储区分为静态存储(static storage)、自动存储(automatic storage)和动态分配存储(allocated or dynamic storage)就可以了。
如果和操作系统的概念结合起来,自动存储区对应着栈(stack),动态分配存储区对应着堆(heap),静态存储区又可细分为 .bss、.data、.rodata 等段(section)。
阅读(1453) | 评论(0) | 转发(0) |