C++基础-第8周

本文详细介绍了C++中的指针基础,包括指针的定义、用法和重要作用。指针用于直接访问内存空间,允许不通过变量进行操作,并能实现对内存的动态访问。内容涵盖指针的赋值、运算、空指针、作为函数参数使用、与数组和字符串的关系,以及void指针和函数指针的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、指针的基本概念

定义:

类型名 * 指针变量名

int * p //p是一个指针,变量p的类型是int *
char * pc; //pc是一个指针,变量pc的类型是char *
float *pf ;//pf是一个指针,变量pf的类型是float *

内容:

int * p = ( int * ) 40000

p内容:40000

p指向地址40000,地址p就是地址40000

通过指针访问其指向的内存空间

int * p=(int *)40000

//向地址40000处起始的若干个字节的内存空间里写入5000;

*p=5000;

//将地址40000处起始的若干字节的内容赋值给n

int n= *p;

用法

char ch1='a';
char * pc = &ch1; //是的pc指向变量ch1
* p=‘b'; //使得ch1='b';
char ch2 =* pc  //使得ch2=ch1
pc=&ch2; //使得pc指向ch2
* pc ='d';//使得pc等于d

&:取地址运算发
&x:变量x的地址

指针的作用:有了指针,就有了自由访问内存空间的手段

1)不需要通过变量,就能对内存直接进行操作。通过指针,程序能访问的内存区域就不仅限于变量所占据的数据区域

2)在C++中,用指针p指向a的地址,然后对p进行加减操作,p就能指向a后面或前面的内存区域,通过p也就能访问这些内存区域。

写非常底层的程序,需要用到指针。

指针的互相赋值

不同类型的指针,如果不经过强制类型转换,不能直接互相赋值

int * pn, char * pc,char c = 0x65;
pn=pc;  //类型不匹配,编译出错
pn=& c;  //类型不匹配,编译出错

指针的运算

1)两个同类型的指针变量,可以比较大小

2)两个同类型的指针变量,可以相减

两个T * 类型的指针 p1和p2

p1-p2=(地址p1-地址p2)/sizeof(T) 表示的是p1和p2之间可以存放多少个T的变量

空指针

*地址0不能访问。指向地址0的指针就是空指针

可以用“NULL"关键字对任何类型的指针进行赋值。NULL实际上就是整数0,值为NULL的指针就是空指针:

int * pn =NULL;char * pc=NULL;int * p2 =0;

pn、pc、p2都是空指针,都是指向地址0的指针

指针作为函数的参数使用

//交换两个整型变量的值
#include<iostream>
using namespace std;
void swap( int *p1,int * p2){
    int tmp =*p1;
    *p1=*p2;
    *p2=tmp;
}

int main(){
    int m=3,n=4;
    swap($m,$n); //使得p1指向m,p2指向n
    cout<<m<<" "<<n<<endl; //输出4 3
    return 0;
}

数组的名字就是一个指针常量,指向数组的起始地址

颠倒数组

指针和二维数组

定义二维数组 :T a[M][N]

a[i]的地址:a[0]的地址+i*N*sizeof(T)

#include <iostream>
using namespace std;
//颠倒元素
void Reverse(int * p,int size){ 
	for (int i=0;i<size/2;++i){
		int tmp=p[i];
		p[i]=p[size-1-i];
		p[size-1-i]=tmp;
	}
}


int main()
{
	int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
	
	Reverse(a[1],4);//{{1,2,3,4},{8,7,6,5},{9,10,11,12}}
	
	Reverse(a[1],6);//{{1,2,3,4},{10,9,8,7},{6,5,11,12}}
	
	return 0;
}

指向指针的指针

定义 :T * * p,此时p是指向指针的指针

#include <iostream>
using namespace std;

int main()
{
	int **pp;//指向int *类型的指针 
	int *p;
	int n=1234;
	p=&n; //p指向n 
	pp=&p; //pp指向p 
	cout<<*(*pp)<<endl; //*pp=p ,*p=n=1234
	
	return 0;
}

指针和字符串

1)字符串常量的类型也是char *

2)字符数组名的类型也是char *

#include <iostream>
using namespace std;

int main()
{
	char *p="please input your name:\n";
	printf(p) ;
	char name[20];
	char * pname=name;
	cin >> pname;
	cout << "your name is "<<pname;
	return 0;
}
//字符串数组名的类型也是char *,就是一个地址
char name[20];
int n;
scanf("%d %s",&n,name);
cin >> n >> name;

char * itoa(int value,char * string,int radix):将整型值value以radix进制表示法写入string

char szvalue[20];
itoa(27,szvalue,10);//使得szvalue的内容为“27”
itoa(27,szvalue,16);//使得szvalue的内容为“1b"
#include <iostream>
using namespace std;
#include <cstring>
int main()
{
	char s1[100]="12345";
	char s2[100]="abcdefg";
	char s3[100]="ABCED";
	strncat(s1,s2,3);//将s2的前3个字符加到s1后面 
	cout<<"1) "<<s1<<endl;//输出:1) 12345abc
	strncpy(s1,s3,3);//将s3的前3个字符拷贝到s1
	cout<<"2) "<< s1<<endl;//输出:2)ABC45abc
	strncpy(s2,s3,6);
	cout<<"3) "<<s2<<endl;//输出:3)ABCDE
	char * p=strchr(s1,'B');//在s1中找到B第一次出现的位置;
	if (p)
		cout<<"4) "<< p-s1<<","<<*p<<endl;//1 
	else 
		cout<<"4) not found"<<endl;
 
	return 0;
}
#include <iostream>
using namespace std;
#include <cstring>
int main()
{
	//以下演示strtok的用法,用特定的符号(如空格,逗号等等)分隔出子串
	char str[]="- This,a sample string,OK.";
	char *p;
	p=strtok(str," ,.-");
	while(p !=NULL){
		cout<< p << endl;
		p=strtok(NULL," ,.-"); //后续调用,第一个参数必须是NULL 
	} 
 
	return 0;
}

注意:后续调用,第一个参数必须是NULL

void 指针——void * p;

可以用任何类型的指针对void指针进行赋值或初始化

double d=1.54;
void * p=& d;
void * p1;
p1= & d;

void * memset (void * dest,int ch,int n);

将从dest开始的前n个字节,都设置成ch,返回值为dest

将szname的前10个字符,都设置成”a"
char szname[200]="";
memset(szname,'a',10);
cout<<szname<<endl;
==》aaaaaaaaaa

用memset函数将数组内容全部设置为0;

int a[100];
memset(a,0,sizeof(a));
//则数组a的每个元素变成0

函数指针:

定义形式:类型名(*指针变量名)(参数类型1,参数类型2)

int (*pf)(int,char);

实例:调用qsort库函数,将一个unsigned int 数组按照个位数从小到大进行排序。比如8,23,15三个数,按个位数从小到大排序,就应该是23,15,8。

#include <iostream>
using namespace std;
#include <cstring>
#include <stdlib.h>  //引入qsort快排,必须要加该头文件 
#define num 5 

int Mycompare(const void *elem1,const void * elem2){
	unsigned int *p1,*p2;
	p1=(unsigned int *)elem1;
	p2=(unsigned int *)elem2;
	return (*p1%10)-(*p2%10);
}

int main()
{
	unsigned int a[num]={8,123,11,10,4};
	qsort(a,num,sizeof(unsigned int),Mycompare); 
	for (int i=0;i<num;i++){
		printf("%d ",a[i]);
	}
	
 
	return 0;
}

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值