[置顶] C++ 学习拾遗 —— 点滴记录C++学习过程中遇到的问题以及整理

时间:2022-12-25 22:00:31

2013.5.28  delete []str;


 

  今天在看老师课件的时候,看到析构函数里有一条语句: 

  delete []str;

  有印象,但一时想不起来。遂查询了一下。

  解释:

  delete str1;  //释放指针变量的内存
  delete [] str1; //释放指针数组的内存(说是指针数组,也不是很准确)

  指针数组:

  在C语言和C++语言中,数组元素全为指针的数组称为指针数组。
  一维指针数组的定义形式为:“类型名  *数组标识符[数组长度]”。
  例如,一个一维指针数组的定义:int  *ptrarray[10]

  也可以:

  char *str;  //定义一个字符指针

  str=new char[20];  //以数组的形式赋给str一片内存

  delete []str;  //释放字符指针数组的内存

 

2013.5.29  返回引用 string&


 

  今天查 string& ,看到个帖子不错。

  上面的解释:

  “string& 是返回引用,这个是C++的特有语法,返回引用的好处和指针类似,就是为了避免返回对象(构造函数等额外开销),提高程序效率。而且,引用和指针又不完全一样,它有其特殊的优点,可以参看C++Primmer中引用和指针的区别相关阐述。”

  下面接着有人提问:

  string& trim_string(string &s, const char *chars)

  main()
  {
      trim_string("1234", '5');
  }

  这样调用出了问题啊,是“1234”这里错了,那我应该怎么改呢?

  解释:

  “你传的是const值,函数接受的是非const值,不行
     要么把"1234"定义成std::string
     要么把原来函数里面的参数写成const的  ”

  当返回一个变量时,会产生拷贝。当返回一个引用时,不会发生拷贝。

 

2013.5.29  常成员函数


 

  常见形式:  

  const Time t1;  ||   
  Time const t1;  &&  
  void get_time() const;

  性质:

  1.常成员函数不能更新对象的数据成员
  2.当一个对象被声明为常对象,则不能通过该对象调用该类中的非const成员函数

 

2013.8.2  数组初始化总结


 

整型数组初始化:
char a[3][4]={0};

字符数组初始化:
int b[3][4]={0};

布尔型数组初始化:
bool c[5]={0};

结构体初始化:
struct instruction{ //定义结构体,存储指令
int head; //识别指令
int d;
int n; //指令附加内容
}pro[1000]={0}; //存储程序体,相当于RAM

初始化之后都会变成0。
(char数组变为\000,int数组变为0,bool数组变为false,这个例子里的结构体所有元素的每一个成员值都为0)

 

 2013.8.6  二维数组的引用作为函数参数传值


 

例1:

 1 #include <iostream>
2 #include <cstring>
3 using namespace std;
4
5 char words[1000][17]={0};
6 char ci[100][17]={0};
7
8 void decipher(char (&words)[17],char (&ci)[17])  //将二维数组作为一维数组传递进来
9 {
10 cout<<words<<endl;  //words[0]
11 cout<<(words+17)<<endl;  //words[1]
12 }
13
14 int main()
15 {
16 strcpy(words[0],"C++");
17 strcpy(words[1],"Java");
18 decipher(words[0],ci[0]);
19 return 0;
20 }

 

例2:

 1 #include <iostream>
2 #include <cstring>
3 using namespace std;
4
5 char words[1000][17]={0};
6 char ci[100][17]={0};
7
8 void decipher(char (&words)[1000][17],char (&ci)[100][17])//将二维数组的引用直接传递进来
9 {
10 cout<<*words<<endl; //words[0]
11 cout<<*(words+1)<<endl; //words[1]
12 }
13 int main()
14 {
15 strcpy(words[0],"C++");
16 strcpy(words[1],"Java");
17 decipher(words,ci);
18 return 0;
19 }

  注意利用两种方式输出的不同,还有给words[0]和words[1]赋值的方式。

  输出结果都是:

C++
Java

 

 

2013.8.6  C++错误提示


 

stray '\241' in program :该错误是指源程序中有非法字符,需要去掉非法字符。中文空格,中文引号, 中文各种标点符号,都会出现。

 

2013.8.7  C++ string 成员函数


 

assign() —— 赋值  

  C++ string类的成员函数,用于拷贝、赋值操作,它们允许我们顺次地把一个string 对象的部分内容拷贝到另一个string 对象上。

  有时候我们需要把一个字符串上的部分内容赋值给另一个字符串,而又觉得用for循环依次拷贝麻烦,这时候使用assign()函数就很方便了。个人认为是个很实用的string成员函数,记下来比较好。

  实例:   
1string s1( "Mississippi" ); string s3;
  
// 拷贝s1 的前4 个字符
  s3.assign( s1, 0, 4 );
  s3 现在的值为“Miss”。
2string str1, str2 = "War and Peace";
  str1.assign( str2,
4, 3 );
  cout
<< str1 << endl;
  显示
  and

 

2013.8.28  关于cin过滤

  cin会过滤掉治表符,回车和空格的输入,cin输入默认分隔符是空格或者回车,也可以设置分隔符。

  例如:

while(cin>>c){
  cout
<<' '<<c;
}

  与

while(c=getchar()){
  cout
<<' '<<c;
}

  同时输入“123”并回车。

123

  比较输出结果

  前者:  

 1 2 3

  后者为:

 1 2 3

  仔细观察会发现后者比前者多一行。这说明前者使用cin的从标准输入中读入数据的时候将回车过滤掉了,而后者使用getchar依次读取缓冲区中的字符然后输出,自然将回车也读入了。

  两者都是输入的时候在控制台中打上一行字符串“123”,然后回车。按下回车的时候,就将字符串包括后面的回车符都放入到了键盘缓冲区里面,区别就是从缓冲区里面向外读的时候,cin忽略掉了回车符,而getchar照常读入。

  这时候使用cin的要注意,缓冲区里面还残留着一个回车符,这在一些情况下,容易因为疏忽出现问题。

  例:

 1 #include <iostream>
2 #include <string>
3 using namespace std;
4
5 int main()
6 { //用getline()读入n行字符串,并输出
7 int n;
8 string s[100];
9 cin>>n; //读入n
10 cout<<"input:"<<endl;
11 for(int i=0;i<n;i++) //读入字符串
12 getline(cin,s[i]);
13 cout<<"output:"<<endl;
14 for(int i=0;i<n;i++) //依次输出字符串
15 cout<<s[i]<<endl;
16 return 0;
17 }

  结果会出现这种情况:

3
input:
123
456
output:

123
456

  第三行字符串还没输入的时候,结果就直接输出出来了,并且输出结果的开头还多出一空行。

  原因就是读入整数n之后缓冲区里,还残留着一个回车符。所以getline会先读取回车符作为第一行字符串。

  将代码改成这样就行了:

 1 #include <iostream>
2 #include <stdio.h>
3 #include <string>
4 using namespace std;
5
6 int main()
7 { //用getline()读入n行字符串
8 int n;
9 string s[100];
10 cin>>n; //读入n
11 getchar(); //将回车符消除
12 //注:C++中fflush(stdin)是清除文件缓冲区,文件以写方式打开时将缓冲区内容写入文件
13 cout<<"input:"<<endl;
14 for(int i=0;i<n;i++) //读入字符串
15 getline(cin,s[i]);
16 cout<<"output:"<<endl;
17 for(int i=0;i<n;i++) //依次输出字符串
18 cout<<s[i]<<endl;
19 return 0;
20 }

  正确输入结果:

3
input:
123
456
789
output:
123
456
789

 

 2013.9.8  char类型数据

  今天发现一个平时没注意的细节,char字符类型默认是有符号型,也就是要拿出一位来存储正负号,这样1个char型数据所代表的数据范围就是128。

  注意这个知识点,再看下面的例子。

#include <iostream>

using namespace std;

int main()
{
char c='z';

char t=c+10;
if(t>'z') //如果加10赋值后会再判断,t的值会超过127,转换成char就会砍掉一部分,输出就会出错
cout<<char(t-26)<<endl;
else
cout
<<char(t)<<endl;

/* 像这样直接+10再比较就不会自动转换,或者将上面的t改成 unsigned char 类型也可以
if(c+10 > 'z')
cout<<char(c-26)<<endl;
else
cout<<char(c)<<endl;
*/
return 0;
}

 2013.12.17  C++的输出格式控制 - float数小数点显示位数

 

 1 #include <iostream>
2 #include <iomanip> //C++的格式控制头文件
3 using namespace std;
4
5 int main()
6 {
7 float M;
8 int N;
9 cin>>M>>N;
10 float sum=0;
11 while(N--){
12 sum+=M/2+M;
13 M/=2;
14 }
15 cout<<setiosflags(ios::fixed); //带小数点的形式显示浮点数
16 cout<<setprecision(2); //和setiosflags(ios::fixed)合用就是控制浮点数显示的小数点位数
17 cout<<M<<' '<<sum-M<<endl;
18 return 0;
19 }

 

 

 

 

 Freecode : www.cnblogs.com/yym2013