其实吧,断断续续学了一点C++,但是其实以前学的时候就迷迷糊糊的。也没怎么搞懂数组和指针的意思。后来才知道元原来数组名就是数组首地址指针。这文章是对以前未明知识点的一点总结。其实写的还是比较乱的。
输入的一些东西
#include<stdio.h>
int main()
{
int input,ret;
printf("输入一个数:\n");
ret = scanf("%d",&input); //返回输入正确的值的个数。
while(ret!=1)
{
/*
比如输入"594icna哈哈哈"。最后输出"594"
*/
while(getchar()!='\n'); //剔除乱七八糟的字符
printf("输入一个数:\n");
ret = scanf("%d",input);
}
printf("%d\n",input);
}
C字符串
C字符串是一个字符数组,以’\0’结尾,如:char city[] = “Harbin”,等价于char city[] = {‘H’,’a’,’r’,’b’,’i’,’n’,’\0’}
cin是默认以’\0’为结束标志的,但是如果要输入的city是“New York”,则就要用cin.getline(city,30,’\n’); 这表示当读入29个或遇到换行符时就停止读入,最后一个字符被’\0’替代。可以简写成cin.getline(city,30);
c字符串函数
常见的是strlen。
unsigned int strlen(char s[])
{
int i = 0;
for( ; s[i] != '\0'; i++);
return i;
}
可知strlen函数将c字符串末尾的’\0’给去掉了。
此外还有一些常见的函数,比如strcpy(char s1[], const char s2[]),
strcat(char s1[], const char s2[])。
c字符串与其他类型相互转换函数
这个有时候还是很用的。主要是 int atoi/atof/atol(char s[]),将字符串转换成对应的int/float/long值。
对应的有 void itoa(int value, char s[], int radix)将数字转换为字符串
char s1[] = "65";
char s2[] = "4";
cout<<atoi(s1)+atoi(s2)<<endl; //显示69
char s3[15];
itoa(100,s3,16); //显示64,即6x16+4 = 100
c++中的字符串
string类型,常见的string的成员函数有.at, .clear(), .erase(int index, int n),此外.length(), .size()是一样的。length()是size()的别名
c_str()返回一个c字符串。(就是将string类型的字符串变成以’\0’结尾的字符数组呗)。
有用的数组函数
在中有sort,random_shuffle分别可以对数组进行排序和随机洗牌。而 min_element和max_element分别返回数组中的最小和最大元素的指针。
int *min = min_element(list,list+6);
cout<<"The min value is"<<*min<<endl;
内存泄漏
堆区申请的内存用new,销毁时用delete,delete只能释放new申请的内存空间,当然如果是new分配给数组的空间释放就用delete[]list;
eg:
int x = 10;
int *p = &x;
delete p; //这是错误的,因为x没有用new申请空间
内存泄漏的一种情况是给一个已指向初始化数的指针再重新指向一个新的空间。
eg:
int *p = new int;
*p = 45;
p = new int;
此时存“45”的空间将无法再访问,即所谓的内存泄漏。
通过指针访问指向对象的成员函数有2中方法。显然第一种是通过指针前面加”*”得到该对象,再用”.”访问其成员呗~
第二种直接用”->”
eg:
string *p = new string("abcdefg");
cout<<(*p).substr(0,3)<<endl;
cout<<p->substr(0,3)<<endl;
传参时的字符串或数组
1.在函数参数中,char s1[]和char *s1都是一样的,都表示c字符串,即以’\0’结尾的字符数组。有时候在前面会加个const表示在函数中无法改变。因为这是传入指针啊,如果误操作改变了传入的c字符串咋办。因此在前面加上const,这是一种防御性编程。
strcat(char *s1, const char *s2)//将s2的字符串拼接到s1上,因此s2肯定是不能改变的,但是s1会变,因此这样的书写方式有助于程序的更好理解,同时也增加了安全性。
2 . 那为什么有时候我们看到 const int&a,这样声明参数的呢?这个其实是类似的。就是说,如果写成 const int*a, 那么传入参数是一个指向int型的指针,并且这个指针所指向的内容不能在函数中改变。a是一个指针。在调用该函数时要传入一个指针。
但当写成 const int&a时,此处的a就是一个int的值。并且这个a不能改变。
3 . c/c++不能返回数组,所以一般情况下是多设置一个参数作为返回的数组就可以了。说实话这有点麻烦啊。。其他很多语言都可以返回数组。。比如:C#
函数模板
template <typename T1, typename T2,...> //模板前缀
T maxValue(const T1&value1, const T2&value2);
模板类
模板类就是
在Stack.h中
template<typename T>
class Stack
{
public:
T peek()const;
bool empty()const;
private:
...
};
在Stack.cpp中
template<typename T>
T Stack<T>::peek()const
{
return elements[size-1];
}//这里的const表示此函数中不改变数据域的值。
根据模板类,可以创建不同的对象,通过给T指定具体类型即成为不同的类。
创建int 型的Stack
StackintStack;
for( int i =0; i < 10; i++)
intStack.push(i);
c++向量类
其实就是长度可变的数组
一维数组的向量表示
vectordeck(52);
二维向量表示
vector
文件输入输出
简单的说就是定义输入/输入流对象,通过“对象.方法()”来进行操作。
注意:ofstream是输出,就是通过控制台输出到文本上,而 ifstream是输入,对于控制台来说是输入,那不就是通过文本输入到控制台中吗?(可能讲的不准确,但是这是一个比较有效的记忆方法)
//从控制台输出到文本。
#include<fstream>
ofstream output;
output.open("score.txt"); //这两距等价于ofstream output("score.txt");
output<<"John"<<" "<<95<<endl;
output.close();
删除数据
#include<fstream>
int main()
{
ifstream input("score.txt");
double sum = 0.0;
double number;
while(!input.eof())
{
input>>number;
cout<<number<<" ";
sum+=number;
}
}
这种写法有一个缺陷就是如果最后一个number后面有空格,则最后一个数字会加2遍,解决办法是写成
while(input>>number)
{
cout<<number<<" ";
sum += number;
}
检验文件是否存在
input.fail()
让用户输入文件名
string filename;
cin>>filename;
ifstream input(filename.c_str());//值得注意的是,标注c++中,传入的必须是c字符串,而不是string对象。
getline get和put
getline就是用来读入包含空格的字符串,get/put读写单个字符
这里的getline是fstream里面的。
原型是:getline(ifstream& input, string s, char delimitChar)
而在cin中的getline原型是getline(char array[], int size, char delimitChar)
eg:
while(!input.eof())
{
getline(input, city, '#');
cout<<city<<endl;
}
input.close();
复制文件内容
...
ifstream input(inputFileName.c_str());
ofstream output(outFileName.c_str());
if(input.fail()){...}
//以下是核心部分
char ch = input.get();
while(!input.eof())
{
output.put(ch);
ch = input.get();
}
input.close();
output.close();
fstream
如果一个文件既要输入又要输出,则用fstream。相应的,其具有一个文件模式。
如:ios::in; ios::app等
fstream inout;
inout.open(“city.txt”,ios::out);
二进制输入输出用read和write
ios::binary
I . 文件分为文本文件和二进制文件,前者可被编辑器处理,后者必须由计算机陈故乡读取。
II. 用”<<”和put写入文本文件,”>>” ,get和getline读取文本文件。但二进制文件的读写,必须用read和write
fstream binaryio("city.dat",ios::out | ios:binary);
string s = "Beijing";
binaryio.write(s.c_str(), size());
binaryio.close();
read的语法:
streamObject.read(char *address, int size)