C++用法总结
1.C++的绝对值符号
如果是整形的,就是abs()
如果是浮点型的,是fabs()
这两个函数都从属于库函数math.h
#include <cmath> or #include<math.h> abs(int) fabs(float)
2.fscanf读取文件里的浮点数的问题
http://bbs.csdn.net/topics/310120431
#include <stdio.h> main() { FILE *fp; long double x; fp = fopen("1.txt", "r"); fscanf(fp,"%Lf",&x); printf("%Lf\n", x); printf("%.4Lf\n", x); fscanf(fp,"%Lf",&x); printf("%lf\n", x); printf("%.4Lf\n", x); }
3. vector中resize()和reserve()区别 http://blog.csdn.net/jocodeoe/article/details/9230879
先看看《C++ Primer》中对resize()函数两种用法的介绍:
1、resize(n)
调整容器的长度大小,使其能容纳n个元素。
如果n小于容器的当前的size,则删除多出来的元素。
否则,添加采用值初始化的元素。
2、 resize(n,t)
多一个参数t,将所有新添加的元素初始化为t。
而reserver()的用法只有一种
reserve(n)
预分配n个元素的存储空间。
了解这两个函数的区别,首先要搞清楚容器的capacity(容量)与size(长度)的区别。
size指容器当前拥有的元素个数;
而capacity则指容器在必须分配新存储空间之前可以存储的元素总数。
也可以说是预分配存储空间的大小。
resize()函数和容器的size息息相关。调用resize(n)后,容器的size即为n。
至于是否影响capacity,取决于调整后的容器的size是否大于capacity。
reserve()函数和容器的capacity息息相关。
调用reserve(n)后,若容器的capacity<n,则重新分配内存空间,从而使得capacity等于n。
如果capacity>=n呢?capacity无变化。
从两个函数的用途可以发现,容器调用resize()函数后,所有的空间都已经初始化了,所以可以直接访问。
而reserve()函数预分配出的空间没有被初始化,所以不可访问。
一个简单的测试用例:
vector<int> a; a.reserve(100); a.resize(50); cout<<a.size()<<" "<<a.capacity()<<endl; a.resize(150); cout<<a.size()<<" "<<a.capacity()<<endl; a.reserve(50); cout<<a.size()<<" "<<a.capacity()<<endl; a.resize(50); cout<<a.size()<<" "<<a.capacity()<<endl;
4.[c++]在C++中定义常量的两种方法的比较 http://www.cnblogs.com/huhu0013/archive/2010/09/13/1824987.html
常量是定以后,在程序运行中不能被改变的标识符。C++中定义常量可以用#define 、const 这两种方法。例如:
#define PRICE 10 //定义单价常量10
const int PRICE = 10; //定义单价常量10
其实用常量是有它的理由的,下面我们来看下面两段程序对比
#include <iostream> using namespace std; #define PI 3.14159 //const double PI = 3.14159; int main(int argc, char* argv[]) { double square = 0,volume =0, radius=0; cout<<"请输入半径长度"<<endl; cin>>radius; square = 3.14159 * radius * radius; cout<<"半径长度为:"<<radius<<"的圆面积是:"<<square<<endl; volume = 4 * 3.14159 * radius * radius * radius /3; cout<<"半径长度为:"<<radius<<"的球体积是:"<<volume<<endl; }
#include <iostream> using namespace std; #define PI 3.14159 //const double PI = 3.14159; int main(int argc, char* argv[]) { double square = 0,volume =0, radius=0; cout<<"请输入半径长度"<<endl; cin>>radius; square = PI * radius * radius; cout<<"半径长度为:"<<radius<<"的圆面积是:"<<square<<endl; volume = 4 * PI * radius * radius * radius /3; cout<<"半径长度为:"<<radius<<"的球体积是:"<<volume<<endl; }
显然如果我还要求球、圆柱体的面积等,用常量的好处就显而易见,用常量的有下面一些好处:
1:增强程序的可读性。用一个有意义的常量代理一串无意义的字符串,显然很多时候程序员忘了或是不理解这一串字符串代表什么意义。
2:如果很多地方用到像PI(3.14159)这样的常量,难保输入错误,尤其复杂的很长的字符串时,而用常量则能一改而全部改变、减少出错的几率。
其中#define是定义宏变量,它其实是在编译之前,由预处理指令把代码里面的宏变量用指定的字符串替换,它不做语法检查,而constant 则是定义含有变量类型的常量。一般说来推荐使用constant定义常量,它在编译时会做语法检查。Effective c++ 的条款1中:“尽量用编译器而不用预处理”,因为#define经常被认为好象不是语言本身的一部分。而且有时候用宏,会出现意想不到的输出结果。
#define 与 const 的比较
(1) const 常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误(边际效应) 。
(2) 有些集成化的调试工具可以对 const 常量进行调试, 但是不能对宏常量进行调试。
5.error C2057:expected constant expression
http://lylgxy0704wht.blog.163.com/blog/static/57048039200993192852623/
数组的大小可以在程序运行时定义吗?
不。在数组的定义中,数组的大小必须是编译时可知的,不能是在程序运行时才可知的。例如,假设i是一个变量,你就不能用i去定义一个数组的大小:
char array[i]; /*(notvalidc */
有些语言支持这种定义,但C语言不支持。如果C语言支持这种定义,栈就会变得更复杂,调用函数的开销就会更大,而程序的运行速度就会明显变慢。
如果数组的大小在编译时是可知的,即使它是一个非常复杂的表达式,只要它在编译时能被计算出来,你就可以定义它。
如果你要使用一个在程序运行时才知道其大小的数组,你可以说明一个指针,并且调用malloc()或calloc()函数从堆中为这个数组分配内存空间。以下是一个拷贝传给main()函数的argv数组的例子:
例 7.15 在动行时确定大小的数组,使用了指针和malloc()
/*
A silly program that copies the argv array and all the pointed-to
strings. Just for fun, it also deallocates all the copies.
*/
# include <stdlib. h>
# include <string. h>
int
main (int argc, char* * argv)
{
char* * new_argv;
int i;
/*
Since argv[0] through argv [argc] are all valid, the
program needs to allocate room for argc + 1 pointers.
*/
new_argv = (char* * ) calloc(argc + l, sizeof (char * ));
/ * or malloc ((argc +1) * sizeof (char * ) ) * /
printf ("allocated room for %d pointers starting at %P\n", argc + 1, new_argv);
/*
now copy all the strings themselves
(argv[0] through argv[argc-l])
*/
for (i = 0;i<argc; + +i)
{
/ * make room for '\0' at end, too * /
new_argv [i]= (char* ) malloc(strlen(argv[i]) + l);
strcpy(new_argv[i], argv[i]);
printf ("allocated %d bytes for new_argv[%d] at %P",
"copied\"%s\"\n",
strlen(argv[i]) + l, i, new_argv[i], new_argv[i]) ;
}
new_ argv [argc] = NULL:
/*
To deallocate everything, get rid of the strings (in any
order), then the array of pointers. If you free the array
of poiners first, you lose all reference to the copied
strings.
*/
for (i = 0;i<argc; ++i) {
free(new_argv[i]);
printf ("freed new_argv[%d] at %P\n" , i, new_argv[i]) ;
argv[i]=NULL; /* 习惯,见本例后面的注意 */
}
free(new_argv);
printf("freed new_argv itself at %P\n",new_argv);
return 0; /*请参见16.4 */
}
注意:为什么例7.5在释放了new_argv数组中的每个元素之后,还要将这些元素赋值为NULL呢?这是一种在长期实践的基础上形成的习惯。在释放了一个指针之后,你就无法再使用它原来所指向的数据了,或者说,该指针被“悬挂”起来了,它不再指向任何有用的数据。如果在释放一个指针之后立即将它赋值为NULL,那么,即使程序再次使用该指针,程序也不会出错。当然,程序可能会间接引用这个空指针,但这种错误在调试程序时就能及时被发现。此外,
程序中可能仍然有一些该指针原来的拷贝,它们仍然指向已被释放的那部分内存空间,这种情况在C程序中是很自然的。总之,尽管上述这种习惯并不能解决所有问题,但确实有作用。