一、常指针:

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. MAC上安装Homebrew、Nginx、PHP、MySQL

    准备工作 新版的 Mac OS 内置了Apache 和 PHP,可以通过以下命令查看Apache和PHP的版本号: # httpd -v # php -v 安装Homebrew Mac下的Homebr ...

  2. JMS简介

    任何一个系统从整体上来看,其实质就是由无数个小的服务或事件(我们可以称之为事务单元)有机地组合起来的.对于系统中任何一个比较复杂的功能,都是通过调用各个独立的事务单元以实现统一的协调运作而实现的.现在 ...

  3. Java多线程中的join()方法

    一.join()方法介绍 join() 定义在Thread.java中.join()方法把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程.比如在线程B中调用了线程A的join( ...

  4. Margin的垂直外边距问题

    做练习的时候遇到一个margin的问题,代码结构如下,给父元素body中的子元素div设置了margin:50px auto;本来我是想让子元素div距离父元素上边拉开50个像素,结果却是子元素div ...

  5. 很常见的一直旋转的loading效果

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  6. tlb,tlh,tli文件的关系

    tlb文件:com类型库文件.在需要使用对应com类的模块里,“#import ...*.tlb”使用之. tlh.tli文件:他们是vc++编译器解析tlb文件生成的标准c++文件.因为odl和tl ...

  7. android loadlibrary 更改libPath 路径,指定路径加载.so

    http://www.jianshu.com/p/f751be55d1fb 字数549 阅读177 评论0 喜欢0 需求很简单 ,就是加载指定文件夹下的.so. 原因:android在程序运行的状态下 ...

  8. Asp.net基础知识

    1.[项目结构] 1.1文件后缀: .cs         源文件(程序代码) .csproj      项目文件(管理文件项) .sln         解决方案文件(管理项目) .config   ...

  9. 关于四字节字符入库时错误的解决方案(Incorrect string value: '\xF0\x9F\x99\x8F' for column 'Reply_Content' at row 1)

    1. 将表字段字符集设置成utf8mb4 2. 执行插入前执行:SET NAMES utf8mb4; 如: SET NAMES utf8mb4; INSERT test(Content) VALUES ...

  10. asp.net 备份和恢复数据库

    观看了Insus的视频写下来的,代码可能有点冗长,如有好的想法的,可以多交流. 前台: <form id="form1" runat="server"&g ...