目录
指针:一种数据类型:存放其它数据类型变量的地址,本身分配8字节(64位系统)空间。
先赋值,再使用:
int * iPtr; //定义整型变量指针
int iCount = 18; //定义整型变量
iPtr = &iCount; //取iCount的地址存放到iPtr中
* —— 间接访问运算符:获取指针所指向的变量的内容。
int main() { int* iPtr; //此处*表示定义指针 int iCount=18; iPtr=&iCount; //指针iPtr指向变量iCount cout<<*iPtr<<endl; //此处*表示取指针iPtr指向的变量的内容 *iPtr=20; //给指针指向的变量赋值 cout<<*iPtr<<endl; return 1; }
int a[10];
int *p=&a[0]; //指针指向数组起始地址
或
int *p=a; //数组名本身是数组的起始地址,指向第一个元素的地址
把数组起始地址赋值给指针,通过指针运算(移动指针)从而对数组元素进行操作。
指针运算:加减( 表示内存中移动指针),比较(同一数组)
堆内存 :存放程序动态数据的内存空间,允许程序根据需要申请一定大小的空间,使用完毕可以释放该空间。
堆内存的分配关键字:new
堆内存的释放关键字:delete
eg:
1)分配一个数据单元 int *p = new int; *p=1; 或者 int *p = new int(1);
delete p;
2)分配多个连续的数据单元(动态数组) char *a = new char[10];
delete [] a;
int a[10] ①与 int *a=new int[10] ②的区别https://blog.csdn.net/weixin_38345919/article/details/82469749
①:系统会自动实现内存的分配和回收 内存是存放在栈上(栈的实际内存是连续内存,可分配空 间较小,内存大小需用常量指定)
②:需要判断内存是否分配成功,以及在不用时需要使用delete[] a进行内存释放
内存放在堆上(堆可以是非连续内存,因此可以分配较大内存)
②优势更大
字符指针:可以不定义字符数组,而定义一个字符指针。用字符指针指向字符串常量。
字符指针的比较:== 和 strcmp()
#include<iostream>
using namespace std;
#include<cstring> //字符串函数文件头
int main()
{ char buffer1[10]="hello";
char buffer2[10]="hello";
if(strcmp(buffer1,buffer2)==0)
cout<<"They are same."<<endl;
else
cout<<"They are different."<<endl;
if(buffer1==buffer2)
cout<<"They have the same address."<<endl;
else
cout<<"They have the different address."<<endl;
}
字符串赋值
char buffer[10]=“hello”; //初始化,ok
char buffer[10]; buffer=“hello”; //数组名赋值,error ("hello"给字符数组作初始化时,"hello",并非一个字符串常量,而是相当于一个初始化列表{'h','e','l','l','o','\0'}。在其他任何时候,它都表示一个字符串常量。而数组名也是一个指针常量,不能对常量赋值。)
const char* pc; pc="hello"; //字符指针赋值,ok (字符串常量首地址 赋给 指针)
可以将字符串复制到字符数组,但不可以复制到不指向实际空间的字符指针
空指针
1.逻辑上表示不指向任何内存,一般可用于超越现有值域的表示;
2.若函数返回值被误解算出一个合法值,如果返回一个指针,除了指向有效值外还可以指向空指针
3.作为一个过度的容器,两个要换位置总还要一个用来临时存放
4.定义一个指针,如果先不用就要把它赋给NULL,不然有可能会随意指向内存造成程序崩溃
原文链接:https://blog.csdn.net/Moon_K_H/article/details/42467421
数组指针:指向一个数组的指针,初始化时通常指向数组首地址。
指针数组:数组元素的内容为指针
指针数组和数组指针 int * p [n]:p表示一个 包含n个内容为 指向整型数组的 指针元素 的数组。
int (*p)[n]:*p指向包含n个元素的一维整形数组
(阅读规则:从右向左,括号“()”优先)
//数组指针演示
#include<iostream>
#include<string.h>
using namespace std;
int main()
{
int a[2][4]={{2,5,6,8},{22,55,66,88}}, c[4]={5,8,9,4}, d[3]={23,12,443};
int (*q)[4];// 指针 指向int[4]的数组
q=a;
for(int i=0;i<2;i++)
for(int j=0;j<4;j++)
cout<<q<<" "<<q+i<<" "<<*(q+i)<<" "<<*(q+i)+j<<" "<<*(*(q+i)+j)<<endl;
return 0;
}
输出结果:
0x61fdf0 0x61fdf0 0x61fdf0 0x61fdf0 2
0x61fdf0 0x61fdf0 0x61fdf0 0x61fdf4 5
0x61fdf0 0x61fdf0 0x61fdf0 0x61fdf8 6
0x61fdf0 0x61fdf0 0x61fdf0 0x61fdfc 8
0x61fdf0 0x61fe00 0x61fe00 0x61fe00 22
0x61fdf0 0x61fe00 0x61fe00 0x61fe04 55
0x61fdf0 0x61fe00 0x61fe00 0x61fe08 66
0x61fdf0 0x61fe00 0x61fe00 0x61fe0c 88
//指针数组演示
#include<iostream>
#include<string.h>
using namespace std;
int main()
{
int a[2][4]={{2,5,6,8},{22,55,66,88}}; c[4]={5,8,9,4}; d[3]={23,12,443};
int *p[2];// 数组 元素为两个整形指针
*p=c;
*(p+1)=d;
for(int i=0;i<2;i++)
for(int j=0;j<4;j++)
cout<<p<<" "<<p+i<<" "<<*(p+i)<<" "<<*(p+i)+j<<" "<<*(*(p+i)+j)<<endl;
return 0;
}
输出结果:
0x61fdc0 0x61fdc0 0x61fde0 0x61fde0 5
0x61fdc0 0x61fdc0 0x61fde0 0x61fde4 8
0x61fdc0 0x61fdc0 0x61fde0 0x61fde8 9
0x61fdc0 0x61fdc0 0x61fde0 0x61fdec 4
0x61fdc0 0x61fdc8 0x61fdd4 0x61fdd4 23
0x61fdc0 0x61fdc8 0x61fdd4 0x61fdd8 12
0x61fdc0 0x61fdc8 0x61fdd4 0x61fddc 443
0x61fdc0 0x61fdc8 0x61fdd4 0x61fde0 5
二维动态数组的内存分配与释放
分配不一定连续。逐个释放,先建立后释放,后建立先释放。
//建立
double **a=new double*[m];
for(int i=0;i<m;i++)
a[i]=new double[n];
//释放
for(i=0;i<m;i++)
delete [] a[i];
delete [] a;
常量指针:表示指针指向的对象是常量,而指针指向的对象可以改变。
const <类型说明符> * <指针名> = &<常量名>;
eg:const int a=89,b=60; const int *p=&a; *p=&b;
指针常量:指针指向的地址固定,所在地址存储的内容可以改变。
函数指针:指向函数首地址,可以用来调用函数。
数据类型 (*指针名) (参数表);
void (*pfun) (int *a, int n);
eg:
//实现sigma函数,计算以0.1为步长,特定范围内的三角函数之和
#include <iostream>
#include <math.h>
using namespace std;
double sigma(double (*f)(double),double a,double b)
{
double sum=0;
for(double i=a; i<b; i+=0.1)
sum+=f(i);
return sum;
}
int main()
{
string s;
double a,b;
while(cin>>s>>a>>b)
{
if(s=="sin")
cout<<sigma(sin,a,b)<<endl;
else if(s=="cos")
cout<<sigma(cos,a,b)<<endl;
else
cout<<sigma(tan,a,b)<<endl;
}
}