您的位置:首页 > 其它

C 基本知识,注意点

2014-06-20 21:14 330 查看
自己在看学习C编程的过程中遇到过挺多问题,于是整理整理,一来分享自己的问题与解决方案,二来作为自己的备忘,以后回头看看。

先贴一张最基础的输入输出相关的



下面是一些需要注意的地方:

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
以float为例,如下表

符号
尾数
指数
1
23
8
数符(+-)
小数部分(决定精度)
-127~128 指数(决定范围)
+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,不会丢失精度

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);  //复制到数组中是可以的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: