C 基本知识,注意点
2014-06-20 21:14
330 查看
自己在看学习C编程的过程中遇到过挺多问题,于是整理整理,一来分享自己的问题与解决方案,二来作为自己的备忘,以后回头看看。
先贴一张最基础的输入输出相关的
下面是一些需要注意的地方:
1、extern ,全局变量; static,静态变量,只初始化一次。
2、数组是静态实体,只有初始化至少一个数才能使得其余的数有默认时
数组作为参数传递给函数是以引用调用实现的,array,&array和&array[0] 都表示第一个元素的地址
3、指针,就是包含内存地址的变量
4、C中使用指针和间接运算符来引用调用:通过指针来运算就是一种间接运算
5、const限定符:告诉编译器一些变量的值是不能通过名字来修改的
const int* sPtr 表示sPtr是指向常量数值的指针,那么数值是不能被改变的
如*sPtr= 100 ; 这就错了,记住这里数字是不能修改的
int* const sPtr 表示sPtr是一个指向整数的常量指针,那么指针指向是不能被改变的
如*sPtr=100; 这是可以的,指向没变,改变了数值而已
sPtr = &y; 这就不行了,这改变了指针的方向
const int * const sPtr = &x; 则sPtr不能为左值,两者都不能改
----------------------------------------------------------------------------------------
关于指针,这里再讨论一种情况:《c++ primer plus》第八章 函数探幽中函数重载中的一句话:“非const值赋给const变量是合法的,反之则是非法的!”,是下面这样理解的:
ps: const int* aaa = &bbb; 这样赋值以后,如果直接修改bbb 的值,那aaa的值也变了,那是不是不符合const的讲法呢??在前面我也标明了,const限定符:告诉编译器一些变量的值是不能通过名字来修改的,如果是采用这种偷梁换柱的办法,const的值还是会被修改掉的。
6、double ,float 基本数据类型说明 ,下一张表是结论表
以float为例,如下表
+1.1111111111111111111111*2^127(小数点后面23个1,由于尾数的范围1~2,其最高位总为1,故只需存取小数部分,所以小数为是23位1),约等于2*2^127=3.4*10^38。为3.4*10^38负数亦然。
Double的计算与此类似,double的符号位为63位,指数为62~52位,共11位。表示的范围为-1024~1023。尾数为51~0。表示的范围为+1.1111111111111111..11111*2^1023(小数点后面52个1)为1.7*10^308。负数亦然。
有些说法:“对编程人员来说,double 和 float 的区别是double精度高,有效数字16位,float精度7位。但double消耗内存是float的两倍,double的运算速度比float慢得多,C语言中数学函数名称double 和 float不同,不要写错,能用单精度时不要用双精度(以省内存,加快运算速度)。” 上面能说明一些问题,但也不是绝对,比如嵌入式编程,或者在特定环境下,一般情况下在目前的硬件条件下还是推荐用double吧。
另外有些人用printf输出double时发现只有6位小数,不是16位精度吗??其实double的意思是可以有16位有效数字而在固定格式输出的时候,都默认的是6位,如果要输出特定位数可以这样:“ %10.5f 保留十位有效数字 五位是小数 ”
7、字符处理库(ctype)的函数说明
他是包含了一些对字符数据进行测试和处理的函数,每个函数接收一个字符,并且将字符作为整数来处理,下面是简单用法说明
8、实用程序库(stdlib)函数说明
这里先介绍将数字字符串转化为整数和浮点数值的一些函数
首先看下atof,字符串转换为double,不会丢失精度
strtol()函数也类似,加了一个参数,第三个参数表示要转换的基数,如8进制,10进制,基数可以规定为0或者2~36之间的任何数字,另外也是检测到第一个非法字符时,立即停止检测,其后的所有字符都会被当作非法字符处理
9、char* ,char[]
char *p="abc123ABC"; //char p[]="abc123ABC"
char* p是一个指针,根本没分配内存,他指向的"abc123ABC" 是只读的,不能改变,如果这个时候要用strcpy()函数把一个值赋值给char *p,肯定是错的
char p[]是一个数组,已经分配内存,是将"abc123ABC" 复制到该内存里面,这个内存是可读写的
在函数strcpy(char* s1, const char * s2)中,这里需要注意的是s1是数组,而不是自己定义的char* 字符串,不是说把const的值赋值给非const 的值(那是指针的赋值),这个函数指的是将s2字符串复制到s1指向的区域中,改变的是数据,而不是仅仅是指针.
如在下面的例子中赋值给a那就不行了,这里和b是不是const倒是没有关系。
先贴一张最基础的输入输出相关的
下面是一些需要注意的地方:
1、extern ,全局变量; static,静态变量,只初始化一次。
2、数组是静态实体,只有初始化至少一个数才能使得其余的数有默认时
数组作为参数传递给函数是以引用调用实现的,array,&array和&array[0] 都表示第一个元素的地址
int array[24]; 函数调用为: modify(array,24) 函数原型则希望第一个参数收到整数数组 void modify(int array[],int size)
3、指针,就是包含内存地址的变量
int y = 5; int *yPtr = &y; //*运算符是解参考指针
4、C中使用指针和间接运算符来引用调用:通过指针来运算就是一种间接运算
int array = 5; modify(&array,24) 函数原型表示为: void modify(int *array,int size){ //其中 *array 表示5 }
5、const限定符:告诉编译器一些变量的值是不能通过名字来修改的
const int* sPtr 表示sPtr是指向常量数值的指针,那么数值是不能被改变的
如*sPtr= 100 ; 这就错了,记住这里数字是不能修改的
int* const sPtr 表示sPtr是一个指向整数的常量指针,那么指针指向是不能被改变的
如*sPtr=100; 这是可以的,指向没变,改变了数值而已
sPtr = &y; 这就不行了,这改变了指针的方向
const int * const sPtr = &x; 则sPtr不能为左值,两者都不能改
----------------------------------------------------------------------------------------
关于指针,这里再讨论一种情况:《c++ primer plus》第八章 函数探幽中函数重载中的一句话:“非const值赋给const变量是合法的,反之则是非法的!”,是下面这样理解的:
//将非const值赋给const变量是合法的,反之则是非法的” int b =2; const int* a = &b; //赋给不是赋值 int bbb =2; const int* aaa = &bbb; int * c ; c = aaa; // 这样就不行了,报错 cout<<aaa<<" "<<bbb<<" "<<c<<endl; //将非const值赋给const变量是合法的,反之则是非法的”只限于指针和引用之间传递,值之间传递怎么都是合法的 int bb =2; const int aa = bb; cout<<aa<<endl; int c = aa; cout<<aa<<" "<<bb<<endl;平时常常遇到的const char* 给char* 赋值报错了,也就是这个原因了。
ps: const int* aaa = &bbb; 这样赋值以后,如果直接修改bbb 的值,那aaa的值也变了,那是不是不符合const的讲法呢??在前面我也标明了,const限定符:告诉编译器一些变量的值是不能通过名字来修改的,如果是采用这种偷梁换柱的办法,const的值还是会被修改掉的。
6、double ,float 基本数据类型说明 ,下一张表是结论表
类型 | 比特(位)数 | 有效数字 | 数值范围 |
float | 32 | 6~7 | -3.4*10^38~+3.4*10^38 |
double | 64 | 15~16 | -1.7*10^-308~1.7*10^308 |
long double | 128/ | 18~19 | -1.2*10^-4932~1.2*10^4932 |
符号 | 尾数 | 指数 |
1 | 23 | 8 |
数符(+-) | 小数部分(决定精度) | -127~128 指数(决定范围) |
Double的计算与此类似,double的符号位为63位,指数为62~52位,共11位。表示的范围为-1024~1023。尾数为51~0。表示的范围为+1.1111111111111111..11111*2^1023(小数点后面52个1)为1.7*10^308。负数亦然。
有些说法:“对编程人员来说,double 和 float 的区别是double精度高,有效数字16位,float精度7位。但double消耗内存是float的两倍,double的运算速度比float慢得多,C语言中数学函数名称double 和 float不同,不要写错,能用单精度时不要用双精度(以省内存,加快运算速度)。” 上面能说明一些问题,但也不是绝对,比如嵌入式编程,或者在特定环境下,一般情况下在目前的硬件条件下还是推荐用double吧。
另外有些人用printf输出double时发现只有6位小数,不是16位精度吗??其实double的意思是可以有16位有效数字而在固定格式输出的时候,都默认的是6位,如果要输出特定位数可以这样:“ %10.5f 保留十位有效数字 五位是小数 ”
7、字符处理库(ctype)的函数说明
他是包含了一些对字符数据进行测试和处理的函数,每个函数接收一个字符,并且将字符作为整数来处理,下面是简单用法说明
8、实用程序库(stdlib)函数说明
这里先介绍将数字字符串转化为整数和浮点数值的一些函数
首先看下atof,字符串转换为double,不会丢失精度
double a = 0; a = atof("120.34567890345678"); printf("%13.10f",a); //输出结果120.34567890345678未丢失精度然后看strtod函数,一个参数是字符串(char*),另一个是指向字符串的指针(char**),该函数时将字符串中的数字部分识别出来并转化,把后面的字符位置赋值给第二个参数(数字字串要在最前面吧)。
strtol()函数也类似,加了一个参数,第三个参数表示要转换的基数,如8进制,10进制,基数可以规定为0或者2~36之间的任何数字,另外也是检测到第一个非法字符时,立即停止检测,其后的所有字符都会被当作非法字符处理
9、char* ,char[]
char *p="abc123ABC"; //char p[]="abc123ABC"
char* p是一个指针,根本没分配内存,他指向的"abc123ABC" 是只读的,不能改变,如果这个时候要用strcpy()函数把一个值赋值给char *p,肯定是错的
char p[]是一个数组,已经分配内存,是将"abc123ABC" 复制到该内存里面,这个内存是可读写的
在函数strcpy(char* s1, const char * s2)中,这里需要注意的是s1是数组,而不是自己定义的char* 字符串,不是说把const的值赋值给非const 的值(那是指针的赋值),这个函数指的是将s2字符串复制到s1指向的区域中,改变的是数据,而不是仅仅是指针.
如在下面的例子中赋值给a那就不行了,这里和b是不是const倒是没有关系。
char * a = "a"; char aa[] = "aa"; const char * b = "b"; strcpy(a,b); //这样就不行了,因为a指向的区域是const的,不能改变的,试图改变则会报错 strcpy(aa,b); //复制到数组中是可以的
相关文章推荐
- java基本知识(2)----需要注意的小知识点
- (一)php的基本知识和一些注意点
- java程序员:开发系统要注意的基本知识
- java程序员:开发系统要注意的基本知识!
- (一)php的基本知识和一些注意点
- python3-基本知识和注意点
- CSS应注意的基本知识
- JS学习笔记-1--基本知识和注意事项
- 基本HTML知识和标签的注意事项(部分学习笔记)--Day1
- 开发Java系统程序员要注意的基本知识
- UIScrollView的基本使用方法和注意事项 - iOS - UI基础知识总结10
- spring jpa data使用的基本知识和注意事项
- [导入]Oracle 基本知识
- ASP.NET 中 Cookie 的基本知识
- Oracle入门基本知识一点通
- 转载:关于linux图形界面的基本知识
- 接口技术的基本知识
- ASP.NET 中 Cookie 的基本知识
- 在struts开发中使用validator验证时应该注意的基本问题
- Oracle 基本知识