当写C语言写多了,自然就喜欢C++了----小话C++(1)
[Mac 10.7.1 Lion x64 Intel-based gcc4.2.1 xcode4.2]
Q: 解释下标题吧。
A: 依稀记得,写一个数值绝对值的函数时,写到第三个,实在感觉很痛苦,重复了这么多遍,立刻体会了重载和STL的重要意义。
[cpp]
1. int abs(int n)
2. {
3. return n < 0 ? -n : n;
4. }
5.
6. long abs_long(long n)
7. {
8. return n < 0 ? -n : n;
9. }
10.
11. double abs_double(double n)
12. {
13. return n < 0 ? -n : n;
14. }
写到第三个函数的时候,感觉实在不爽,原来c++中的重载这么现实,很清楚c程序员的痛苦之处;对于基本类型,很多绝对值操作都是类似的,为什么还要写这么多函数?写代码不是比谁写的多,是比简洁易懂和稳定, STL更明白写上面代码的痛苦。
[cpp]
1. template<class T>
2. T abs(T a)
3. {
4. return a < 0 ? -a : a;
5. }
当然,也可以用宏来实现,不过不是很推荐:
[cpp]
1. #define ABS(a) ((a) < 0 ? (-a) : (a))
不小心就可能有问题:
[cpp]
1. std::cout << ABS(-12.4) << std::endl;
编译提示:
[cpp]
1. error C2105: '--' needs l-value
哦,原来ABS(-12.4)被宏替换成了--12.4.宏有的时候真得小心啊...
[cpp]
1. #define ABS(a) ((a) < 0 ? -(a) : (a))
这样编译就ok了。
另外,还有,用c语言的时候,经常会写到一个结构体以及对结构体的操作,必须申请空间来构造某个结构,写了N个malloc,直到每次写malloc都有种想吐的感觉,c++明白了这个痛苦之处,构造函数让写malloc到吐的程序员迅速爱上c++.
还有很多地方是c++对于c语言的一些改进,这里不一一介绍了。
Q: 在c++中,使用cstring头文件和string.h有什么区别?
A: 先来看两个例子:
[cpp]
1. #include <stdio.h>
2. #include <stdlib.h>
3. #include <string.h>
4.
5. #define PRINT_D(intValue) printf(#intValue" is %d\n", (intValue));
6. #define PRINT_STR(str) printf(#str" is %s\n", (str));
7. #define FOR_EVER() { while(1) ; }
8.
9. int main()
10. {
11. size_t len = ::strlen("hello");
12. return 0;
13. }
如上,保存为std_strlen.c, 编译:
[cpp]
1. error: expected expression [1]
2. size_t len = ::strlen("hello");
3. ^
4. 1 error generated.
可以看出,c语言中并没有作用域运算符,这里编译错误;
[cpp]
1. #include <iostream>
2. #include <cstring>
3.
4. int main()
5. {
6. size_t len = ::strlen("hello");
7. return 0;
8. }
保存为main.cpp,编译,没出现什么问题。
这里就体现了cstring和string.h的不同之处:c++支持了作用域运算符::, 原先c库中的函数被默认当成c++中全局作用域的函数,当然也是std作用域的函数。如下:
[cpp]
1. len = std::strlen("hello");
上面的代码依然可以编译通过。现在再看看cstring和string.h头文件里面的内容:
cstring头文件(部分):
[cpp]
1. _GLIBCXX_BEGIN_NAMESPACE(std)
2.
3. using ::memcpy;
4. using ::memmove;
5. using ::strcpy;
6. using ::strncpy;
7. using ::strcat;
8. using ::strncat;
9. using ::memcmp;
10. using ::strcmp;
11. using ::strcoll;
12. using ::strncmp;
13. using ::strxfrm;
14. using ::strcspn;
15. using ::strspn;
16. ......
17. ......
18.
19. _GLIBCXX_END_NAMESPACE
string.h头文件(部分):
[cpp]
1. __BEGIN_DECLS
2. void *memchr(const void *, int, size_t);
3. int memcmp(const void *, const void *, size_t);
4. void *memcpy(void *, const void *, size_t);
5. void *memmove(void *, const void *, size_t);
6. void *memset(void *, int, size_t);
7. char *strcat(char *, const char *);
8. char *strchr(const char *, int);
9. int strcmp(const char *, const char *);
10. int strcoll(const char *, const char *);
11. char *strcpy(char *, const char *);
12. size_t strcspn(const char *, const char *);
13. char *strerror(int) __DARWIN_ALIAS(strerror);
14. size_t strlen(const char *);
15. char *strncat(char *, const char *, size_t);
16. int strncmp(const char *, const char *, size_t);
17. char *strncpy(char *, const char *, size_t);
18. char *strpbrk(const char *, const char *);
19. char *strrchr(const char *, int);
20. size_t strspn(const char *, const char *);
21. char *strstr(const char *, const char *);
22. char *strtok(char *, const char *);
23. size_t strxfrm(char *, const char *, size_t);
24. __END_DECLS
Q: c++中的引用到底和类似功能的指针有什么不同?
A: 从本质上来说,基本没什么不同;从使用上来看,是有不同的。如下例子:
[cpp]
1. #include <iostream>
2. #include <cstring>
3.
4. #define COUT_ENDL(str) std::cout << #str << " is " << (str) << std::endl;
5.
6. void swap(int &a, int &b)
7. {
8. int temp = a;
9. a = b;
10. b = temp;
11. }
12.
13. void swap(int *pa, int *pb)
14. {
15. int temp = *pa;
16. *pa = *pb;
17. *pb = temp;
18. }
19.
20.
21. int main()
22. {
23. int a = 1, b = 2;
24. swap(a, b);
25. COUT_ENDL(a)
26. COUT_ENDL(b)
27.
28.
补充:软件开发 , C++ ,