📄 c++语言程序设计超级简单了解.txt
字号:
scanf("%s",str); (检查你输入的,如果空,)
l = 0; (长度0,)
while(str[l] != '\0') (非空,)
l ++; (加加,数出来,)
printf("The length of this string is %d\n",l); (输出结果回车,)
}
七,指针与引用
指针就是在内存中的地址,它可能是变量的地址,也可能是函数的入口地址。
引用为变量提供了一个别名,变量通过引用访问与通过变量名访问是完全等价的。
引用提供了与指针相同的能力,但比指针更为直观,更易于理解。
int d =1;
int* const p =&d
(有const表示不可修改,p是一个常量指针,它指向一个整型变量。就是d,p本
身不能修改,但它所指向的内容却可以修改:*p =2;这个不大好说,请查阅相
严谨详细资料。关。)
例如:
#include <iostream.h>
#define SIZE 10
void main()
{
int array[SIZE]; (声明整数数组,)
int *p=array; (定义一个整型指针p,给他数组首地址,)
int i ; (定义变量i,)
for(i=0;i<SIZE;i++) (赋值,运算,)
array[i]=i;
for(i=0;i<SIZE;i++)
cout<<*p++<<endl; (*p++就是访问下一个数组元素,)
p=&array[8]; (给他array[8]的地址,)
cout<<"array[8]="<<*p<<endl; (输出*p,)
cout<<"array[8]="<<array[8]<<endl; (输出array[8],)
}
(两个值是一样的,因为从0开始,所以都是对数组第9个元素的访问。)
例子:折半查找函数
int BinSearch (char *item, char *table[], (就是在table中查找是否含有item的元素)
int n, int (*Compare)(const char*, const char*)) Compare是一个比较函数指针,)
{
int bot = 0; (底部0,)
int top = n - 1; (顶部n-1,)
int mid, cmp; (定义比较变量,比较,)
while (bot <= top) (比较当然需要循环,循环条件,意思就是不空,)
{ (以下循环内容)
mid = (bot + top) / 2; (mid等于,全部除以2,就是一半,)
if ((cmp = Compare(item,table[mid])) == 0) (如果恰好相等,)
return mid; ( 就是它,)
else if (cmp < 0) (不相等,)
top = mid - 1; ( 查找数组的下半部,)
else
bot = mid + 1; ( 查找数组的上半部,)
}
return -1; (上面循环之后,返回-1,没有找到,因为n就是0了。)
}
例如。
char *cities[] = {"Beijing", "Shanghai", "Tianjin", "Zhongqing"};
cout << BinSearch("Tianjin ", cities, 4, strcmp) << '\n'
输出结果2
(就是,给出一个数组,找找“Tianjin”在四个中的位置,2就是在第三个位置。)
八。结构 链表
结构(struct)数据类型,它能够识别一组相关的数据。
链表也是表示线性数据最有用的方法之一,用链表保存线性数据,可以克服数组的问题
举例
#include <iostream.h>
#include <string.h>
struct Person_Info { (个人信息表,下面是相关内容。)
char name[10];
int age;
long ssn;
};
void main (void)
{
Person_Info* p1; (给个指针,)
p1 = new Person_Info; (申请内存,)
p1->age = 27; ( 给age成员赋值,)
strcpy(p1->name,"jinzhou"); (给name成员赋值 ,)
cout << "Name: " << p1->name << endl; ( 打印name成员,)
cout << "Age: " << p1->age << endl; (打印age成员,)
delete p1; (释放申请的内存,)
}
简单例子学生结构的实例
struct stu
{
int num;
int score;
stu *next;
}
(明白这个意思就行了,)
九,编译预处理
C++提供的编译预处理功能主要有以下三种:(一) 宏定义(二) 文件包含(三) 条件编译
宏定义例子;
#include <iostream.h>, (一定要有,或者出错,)
#define CUBE_THREE 3*3* (用简单宏定义定义了一个符号常量"CUBE_THREE")
void main()
{
int a; (定义变量,)
a=CUBE_THREE; (赋予值,就是a=3*3*3,)
cout<<"a is"<<a<<endl; (输出,结果为27,)
}
(这个意思主要是说可以把常用的东西定义为宏。这个不带参数,带参数的略。)
文件包含类的略。
例子:条件编译命令的一个例子
#include <iostream.h>
#define TIME
void main()
{
#ifdef TIME (如果TIME被定义过,输出下面句话。)
cout<<"Now begin to work"<<endl;
#else (如果没有定义,输出下面的,)
cout<<"You can have a rest"<<endl;
#endif
}
(所谓条件,就是有条件的,。就是要选择。哈哈)
十。类与对象
略过,请找寻相关详细资料阅读,不好意思。
十一,继承与多态。(略过)
十二,输入输出流。
抽象流基类
ios 流基类
输入流类
istream 普通输入流类和用于其它输入流的基类
ifstream 输入文件流类
istream_withassign 用于cin的输入流类
istrstream 输入串流类
输出流类
ostream 普通输出流类和用于其它输出流类的基类
ofstream 输出文件流类
ostream_withassign 用于cout、cerr和clog的流类
ostrstream. 输出串流类
输入输出流类
iostream 普通输入输出流类和用于其它输入输出流的基类
fstream 输入输出文件流类
strstream 输入输出串流类
stdiostream 用于标准输入输出文件的输入输出类
缓冲流类
streambuf 抽象缓冲流基类
filebuf 用于磁盘文件的缓冲流类
strstreambuf. 用于串的缓冲流类
stdiobuf 用于标准输入输出文件的缓冲流类
预定义流初始化类
iostream_init 预定义流初始化的类
其中,ios、istream、ostream和streambuf类构成了C++中iostream输入输出功能的基础
定义常量也可以使用define、inline去实现
我建议大家用const和inline而不用#define
这个条款最好称为:“尽量用编译器而不用预处理”,因为#define经常被认为好象不是语言本身的一部分。这是问题之一。再看下面的语句:
#define ASPECT_RATIO 1.653
编译器会永远也看不到ASPECT_RATIO这个符号名,因为在源码进入编译器之前,它会被预处理程序去掉,于是ASPECT_RATIO不会加入到符号列表中。如果涉及到这个常量的代码在编译时报错,就会很令人费解,因为报错信息指的是1.653,而不是ASPECT_RATIO。如果ASPECT_RATIO不是在你自己写的头文件中定义的,你就会奇怪1.653是从哪里来的,甚至会花时间跟踪下去。这个问题也会出现在符号调试器中,因为同样地,你所写的符号名不会出现在符号列表中。
解决这个问题的方案很简单:不用预处理宏,定义一个常量:
const double ASPECT_RATIO = 1.653;
这种方法很有效。但有两个特殊情况要注意。
首先,定义指针常量时会有点不同。因为常量定义一般是放在头文件中(许多源文件会包含它),除了指针所指的类型要定义成const外,重要的是指针也经常要定义成const。例如,要在头文件中定义一个基于char*的字符串常量,你要写两次const:
const char * const authorName = "Scott Meyers";
关于const的含义和用法,特别是和指针相关联的问题,参见条款21。
另外,定义某个类(class)的常量一般也很方便,只有一点点不同。要把常量限制在类中,首先要使它成为类的成员;为了保证常量最多只有一份拷贝,还要把它定义为静态成员:
class GamePlayer {
private:
static const int NUM_TURNS = 5; // constant eclaration
int scores[NUM_TURNS]; // use of constant
...
};
还有一点,正如你看到的,上面的语句是NUM_TURNS的声明,而不是定义,所以你还必须在类的实现代码文件中定义类的静态成员:
const int GamePlayer::NUM_TURNS; // mandatory definition;
// goes in class impl.file
你不必过于担心这种小事。如果你忘了定义,链接器会提醒你。
旧一点的编译器会不接受这种语法,因为它认为类的静态成员在声明时定义初始值是非法的;而且,类内只允许初始化整数类型(如:int, bool, char 等),还只能是常量。
在上面的语法不能使用的情况下,可以在定义时赋初值:
class EngineeringConstants { // this goes in the class
private: // header file
static const double FUDGE_FACTOR;
...
};
// this goes in the class implementation file
const double EngineeringConstants::FUDGE_FACTOR = 1.35;
大多数情况下你只要做这么多。唯一例外的是当你的类在编译时需要用到这个类的常量的情况,例如上面GamePlayer::scores数组的声明(编译过程中编译器一定要知道数组的大小)。所以,为了弥补那些(不正确地)禁止类内进行整型类常量初始化的编译器的不足,可以采用称之为“借用enum”的方法来解决。这种技术很好地利用了当需要int类型时可以使用枚举类型的原则,所以GamePlayer也可以象这样来定义:
class GamePlayer {
private:
enum { NUM_TURNS = 5 } // "the enum hack" — makes
// NUM_TURNS a symbolic name
// for 5
int scores[NUM_TURNS];// fine
};
除非你正在用老的编译器(即写于1995年之前),你不必借用enum。当然,知道有这种方法还是值得的,因为这种可以追溯到很久以前的时代的代码可是不常见的哟。
回到预处理的话题上来。另一个普遍的#define指令的用法是用它来实现那些看起来象函数而又不会导致函数调用的宏。典型的例子是计算两个对象的最大值:
#define max(a,b) ((a) > (b) ? (a) : (b))
这个语句有很多缺陷,光想想都让人头疼,甚至比在高峰时间到高速公路去开车还让人痛苦。
无论什么时候你写了象这样的宏,你必须记住在写宏体时对每个参数都要加上括号;否则,别人调用你的宏时如果用了表达式就会造成很大的麻烦。但是即使你象这样做了,还会有象下面这样奇怪的事发生:
int a = 5, b = 0;
max(++a, b);// a 的值增加了2次
max(++a, b+10); // a 的值只增加了1次
这种情况下,max内部发生些什么取决于它比较的是什么值!
幸运的是你不必再忍受这样愚笨的语句了。你可以用普通函数实现宏的效率,再加上可预计的行为和类型安全,这就是内联函数(见条款33):
inline int max(int a, int b) { return a > b ? a : b; }
不过这和上面的宏不大一样,因为这个版本的max只能处理int类型。但模板可以很轻巧地解决这个问题:
template<class T>
inline const T& max(const T& a, const T& b)
{ return a > b ? a : b; }
这个模板产生了一整套函数,每个函数拿两个可以转换成同种类型的对象进行比较然后返回较大的(常量)对象的引用。因为不知道T的类型,返回时传递引用可以提高效率(见条款22)。
顺便说一句,在你打算用模板写象max这样有用的通用函数时,先检查一下标准库(见条款49),看看他们是不是已经存在。比如说上面说的max,你会惊喜地发现你可以后人乘凉:max是C++标准库的一部分。
有了const和inline,你对预处理的需要减少了,但也不能完全没有它。抛弃#include的日子还很远,#ifdef/#ifndef在控制编译的过程中还扮演重要角色。预处理还不能退休,但你一定要计划给它经常放长假。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -