一、常指针:

int *const p;    //指针不可改变,但是指针指向的数据可以改变。

指向常量的指针:

const int *p;    //指针可以改变,但是指针指向的数据不可以改变。

指向常量的常指针:

const int *const p;    //指针不可改变,且指针指向的数据也不可改变。

引用就是别名,定义引用的同时必须要对引用进行初始化。

二、利用引用返回多个值:

引用就是别名,引用必须要初始化。

#include "stdafx.h"
#include <iostream>
#include <cmath>
using namespace std;
void func(int &a,int &b,int &c);
int main()
{
int a=;
int b=;
int c=;
cout<<"主函数,计算前。。。"<<endl;
cout<<a<<"\t"<<b<<"\t"<<c<<endl;
func(a,b,c);
cout<<"主函数,计算后。。。"<<endl;
cout<<a<<"\t"<<b<<"\t"<<c<<endl;
return ;
}
void func(int &a,int &b,int &c)
{
cout<<"func函数,计算前。。。"<<endl;
cout<<a<<"\t"<<b<<"\t"<<c<<endl;
a=a+;
b=(b)*(b);
c=(c)*(c)*(c); //
cout<<"func函数,计算后。。。"<<endl;
cout<<a<<"\t"<<b<<"\t"<<c<<endl;
}

三、删除空指针是不会报错的。

int *p;
p=new int;

delete p;

p=0;        //将指针赋值为空,假如没有这句,程序将崩溃。

delete p;

四、删除堆中指针后,只是释放了指针所指向的内存单元,指针仍然存在,且依然指向删除前的内存地址

int *p=new int(11);

cout<<"删除指针p前其指向的内存地址:"<<p<<endl;

delete p;

cout<<"删除指针p后其指向的内存地址:"p<<endl;

程序输出结果:

所以,为了保证程序的安全可靠,需要在delete p后加上p=0

五、类的对象的this指针

对象的this指针存储该对象的内存地址。

#include "stdafx.h"
#include <iostream>
//#include <string>
//#include <limits>
using namespace std; class A
{
private:
int i;
public:
void set(int x){this->i=x;cout<<"this指针的指向的内存地址为:"<<this<<endl;}
//也可以直接写成i=x;
}; int _tmain(int argc, _TCHAR* argv[])
{
A a;
a.set();
cout<<"对象的内存地址为:"<<&a<<endl;
return ;
}

//运行结果如下图所示

六、使用引用时容易犯错的地方

临时变量生存期的问题

#include "stdafx.h"
#include <iostream>
using namespace std; class A
{
private:
int x;
public:
A(int i){x=i;}
void get(){cout<<x<<endl;}
~A(){}
}; A &func(); int _tmain(int argc, _TCHAR* argv[])
{
A &ra=func();
ra.get();
return ;
} A &func()
{
A a(); //a为临时对象,func函数一旦结束,其生存周期也结束,立即销毁
return a;
}

可以看到最后返回的是一个随机数,这就是临时变量被提前删除的缘故

若将func()函数前面的&去掉,则可正确返回a对象的成员变量的值。

此时函数按值返回,对象a的副本生命周期会一直持续到main()函数结束。

这是因为,作为引用的临时变量(即A &ra=func();),其生存周期不会短于该引用。

七、按值传递传递的是变量的副本,按址传递,顾名思义肯定是传送的地址了。

八、关于二维(数组)指针的一些理解问题

int ** Ptr <==> int Ptr[ x ][ y ];

   int *Ptr[ 5 ] <==> int Ptr[ 5 ][ x ];

int ( *Ptr )[ 5 ] <==> int Ptr[ x ][ 5 ];

这里 x 和 y 是表示若干的意思。(转)

测试代码:

#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
int (*p)[]=new int[][];
cout<<"指针数组的初始地址:"<<p<<endl;
int i,j;
int a[][]={,,,};
cout<<"二维数组的初始地址:"<<a<<endl<<endl;;
cout<<"自定义赋值初始化指针数组!!!"<<endl;
for (i=;i<;i++)
for (j=;j<;j++)
{ p[i][j]=i+j; }
//cout<<endl<<"使用二维数组初始化数组指针!!!"<<endl;
//p=a; //使用二维数组初始化数组指针
cout<<"赋值后指针数组的地址:"<<p<<endl;
for (i=;i<;i++)
{
for (j=;j<;j++)
cout<<p[i][j]<<"\t";
cout<<endl;
}
delete[] p;
p=;
return ;
}

程序输出:自定义赋值初始化指针数组!

下面对以上代码稍作修改,使用二维数组赋初值给指针数组。

#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
int (*p)[]=new int[][];
cout<<"指针数组的初始地址:"<<p<<endl;
int i,j;
int a[][]={,,,};
cout<<"二维数组的初始地址:"<<a<<endl<<endl;;
/*cout<<"自定义赋值初始化指针数组!!!"<<endl;
for (i=0;i<2;i++)
for (j=0;j<2;j++)
{ p[i][j]=i+j; }*/
cout<<endl<<"使用二维数组初始化数组指针!!!"<<endl;
p=a; //使用二维数组初始化数组指针
cout<<"赋值后指针数组的地址:"<<p<<endl;
for (i=;i<;i++)
{
for (j=;j<;j++)
cout<<p[i][j]<<"\t";
cout<<endl;
}
//delete[] p;
//p=0;
return ;
}

程序输出:(delete[] p必须注释掉否则程序会崩溃。)

九、复制构造函数

#include <stdafx.h>
#include<iostream>
using namespace std;
class A
{
private:
int m,n;
public:
A(int i,int j){m=i;n=j;} //构造函数
A(A&temp){m=temp.m;n=temp.n;} //复制构造函数
void print(){cout<<m<<"\t"<<n<<endl;}
};
int main()
{
A a(,);
a.print(); A b(a); //or A b=a;也可以
b.print();
return ;
}

浅复制:(被复制对象的变量与复制对象的变量享有同样的内存空间)

#include <stdafx.h>
#include<iostream>
using namespace std;
class A
{
private:
int *x;
public:
A(){x=new int;*x=;}
~A(){delete x;x=;}
A (const A&temp){x=temp.x;}
void display(){cout<<*x<<"\t"<<&x<<endl;}
void set(int i){*x=i;}
};
int main()
{
A *a=new A;
a->display(); A b(*a);
b.display(); a->set();
a->display();
b.display(); b.set();
a->display();
b.display(); //delete a; return ;
}

深复制:(被复制对象的变量与复制对象的变量拥有各自独有的内存空间)

#include <stdafx.h>
#include<iostream>
using namespace std;
class A
{
private:
int *x;
public:
A(){x=new int;*x=;}
~A(){delete x;x=;}
A (const A&temp){x=new int;*x=*(temp.x);}
void display(){cout<<*x<<"\t"<<&x<<endl;}
void set(int i){*x=i;}
};
int main()
{
A *a=new A;
a->display(); A b(*a);
b.display(); a->set();
a->display();
b.display(); b.set();
a->display();
b.display(); delete a; return ;
}

十、char型字符串(数组)与string型字符串

如:char man[100];//当使用cin来输入字符串时,遇到空格(即空字符0 or ‘\0’)的话,字符串输出时就从此截断。

比如输入hello world,那么输出只有hello。

C++提供了一种简单高效的方法来解决上述问题,char man[]={“hello world”},或者char man[]="hello world",此时再输出就正常了。

char型字符串时C语言时的风格,在C++时代产生了C++风格的字符串,string型字符串。使用时必须添加string头文件。

由于string是一个类,那么string str;//str就可以看成是string类的一个对象,该对象可以调用string类的各种成员函数。

1、char型字符串有以下3种形式

char c[12]="study"    //字符数组

“study”                    //未命名字符串

char *p="study"        //指向未命名字符串的指针

以上3种类型只有第一种所指向的字符串可以改变。

#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std; char *get(char *str); int main()
{
char name[];
char *name1;
cout<<"请输入您的名字:"<<endl;
cin>>name;
name1=get(name);
cout<<"您的名字是:"<<name1<<endl;
delete []name1;
name1=get("Jack");
cout<<"您的名字是:"<<name1<<endl;
delete []name1;
char *name2="Mike";
name1=get(name2);
cout<<"您的名字是:"<<name1<<endl;
delete []name1;
return ;
}
char *get(char *str)
{
char *p=new char[strlen(str)+]; //这里如果用sizeof函数,程序会崩溃
strcpy(p,str);
cout<<p<<endl;
return p;
}

2、C的结构体与C++的类的唯一区别在于前者的成员变量默认是公有的,而类的成员变量默认是私有的。

对于公有成员变量,我们可以像使用成员函数那样使用成员变量。

char型字符串(数组)与string型字符串 指针与引用的更多相关文章

  1. C#中如何排除/过滤/清空/删除掉字符串数组中的空字符串

    C#中要如何才能删除一个字符串数组中的空字符串呢?随着微软对C#不断发展和更新,C#中对于数组操作的方式也变得越来越多样化.以往要实现过滤数组中的空字符串,都是需要实行循环的方式来排除和过滤.C#3. ...

  2. 使用C#删除一个字符串数组中的空字符串

    C#中要如何才能删除一个字符串数组中的空字符串呢?随着微软对C#不断发展和更新,C#中对于数组操作的方式也变得越来越多样化.以往要实现过滤数组中的空字符串,都是需要实行循环的方式来排除和过滤.C#3. ...

  3. 07.C#中如何排除/过滤/清空/删除掉字符串数组中的空字符串

    方式一:使用lambda表达式筛选过滤掉数组中空字符串         1 /// <summary> /// 使用lambda表达式排除/过滤/清空/删除掉字符串数组中的空字符串 /// ...

  4. 数组转集合、集合转数组、字符串数组与int型、long型数组等的转换

    在项目中经常会遇到数组转集合.集合转数组.数组之间类型转换等操作 1.数组转集合 为了实现把一个数组转换成一个ArrayList,很多Java程序员会使用如下的代码: String str[] = { ...

  5. JS怎么把字符串数组转换成整型数组

    今天在学习highcharts时,遇到了一个把字符串数组转换为整形数组的问题,拿在这里讨论一下: 比如有一个字符串: var dataStr="1,2,3,4,5"; 现在需要把它 ...

  6. 字符串数组 输入3个字符串,要求按由小到大的字母顺序输出; 输入n个学生的姓名和学号到字符串数组中,在输入一个姓名,如果班级有该生则返回其信息,否则返回本班无此人

    输入3个字符串,要求按由小到大的字母顺序输出 如 输入franch england china,输出结果是china england franch 三个数排序输出,比较三个数的大小怎么做? a=18 ...

  7. 数组类型与sizeof与指针的引用

    以char类型为例: char a[100];     //a类型为char[100]    &a类型为 char (*)[100]    *a类型为char char *p = a;     ...

  8. 动态创建二维vector数组 C和C++ 及指针与引用的区别

    二维vectorvector<vector <int> > ivec(m ,vector<int>(n));    //m*n的二维vector 动态创建m*n的二 ...

  9. [java变量] - 字符串数组转long型数组

    //定义字符串 String str = "1,3,6,9,4,2,1,6"; //截取字符串 String[] strArr = str.split(",") ...

  10. 在Python中,如何将一个字符串数组转换成整型数组

    https://blog.csdn.net/xiangchengguan/article/details/78987041 arr = ['] arr = list(map(int,arr)) pri ...

随机推荐

  1. 使用VS建立Web网站及IIS

    一:网站运行的一般原理: 1.所有WEB程序运行都需要一个东西:Web服务器软件. 2. 网站分为动态页面和静态页面 3. web服务器软件的作用:接收请求,响应请求. 被动——无请求则无响应. Ja ...

  2. React组件生命周期过程说明【转】

    实例化 首次实例化 getDefaultProps getInitialState componentWillMount render componentDidMount 实例化完成后的更新 getI ...

  3. 【高级JEE技术】JMX

    JMX即Java Manager Extentin(java 管理扩展)一种动态改变javabean属性值的技术,具体应用场景可以有很多.比如使用JMX作为线上应用的开关,在做一些新老系统改造的时候 ...

  4. arguments 函数内部属性

    1.arguments 是在function方法里面的,是实参数组,用法是挺多的,下面来记录一下 2.利用arguments实现方法的重载 //01.使用argument模拟方法重载 function ...

  5. 12天学好C语言——记录我的C语言学习之路(Day 11)

    12天学好C语言--记录我的C语言学习之路 Day 11: 因为指针部分比较的难,所以我们花费的时间也是最长的,希望大家耐的住性子,多多理解,多多打代码.好了,废话不多说,来看第11天的学习. //编 ...

  6. [MAXscript Tool]TimeSlider v1.3

    一个简单的小工具,方便在MAX里面快速的修改帧速率,像maya一样.具体看视频演示.

  7. 我的VIM.rc

    我的VIM.rc """""""""""""""& ...

  8. CICS定时

    F+14个0-----给CICS传参数FM CICSServer svr;        svr.GetRetCommData(&pMsgStr, &chMsgType); CICSS ...

  9. 存储占用:Memory Map 汉化去广告版

    转载说明 本篇文章可能已经更新,最新文章请转:http://www.sollyu.com/storage-occupancy-memory-map-localization-to-billboards ...

  10. Poj/OpenJudge 1000 A+b Problem C/C++/Java

    1.题意翻译:        输入两个整数a,b (0<=a,b<=10),计算a+b的值并输出.       其中还提到输出不能有多余的内容,即不能加多空格符号等内容,不然会报Wrong ...