c<8>指针

news/2025/2/28 2:44:18/

目录

2,指针的赋值

 2.1C语言允许指针赋值为0(初始化)

2.2指针赋值例

2.3输出指针的值

 3,用指针引用数组

3.1优先级问题 

3.2用数组名作为函数形参

3.4.多维数组

4.字符串

 4.1通过指针引用字符串

4.2字符串的复制

5.函数中对指针的应用

5.1将指针变量作为函数参数

5.1.1指针的定义

5.1.2指针的引用

5.2将数组传递至函数中

5.3.返回指针的函数

6. *指针数组和多重指针

6.1指针数组


1,指针本身是一个地址,以int的形式保存

(32位用四个字节储存,64位操作系统用八个字节储存)

2,指针的赋值

一般来说指针是无法直接赋值的

当然可以用这种形式来强制赋值

(int*) p = 101;

 2.1C语言允许指针赋值为0(初始化)

int* a = 0;

常用 :(防止未初始化指针破化内存

if ( p != 0 )*p+1=xxxx;

宏定义

#define NULL 0

在条件语句里初始化也不行,会报错,如


#include<stdio.h>
//输入a和b两个整数,按先大后小的顺序输出a和b
int main()
{int a, b;int* p_a, *p_b;scanf_s("%d %d", &a, &b);if (a < b){p_a = &b;p_b = &a;}if(a>=b){p_a = &a;p_b = &b;}printf("a=%d,b=%d", *p_a, *p_b);return 0;
}

 

 正确操作:

#define NULL 0
#include<stdio.h>//输入a和b两个整数,按先大后小的顺序输出a和b
int main()
{int a, b;int* p_a=NULL, *p_b=NULL;//初始化scanf_s("%d %d", &a, &b);if (a < b){p_a = &b;p_b = &a;}if(a>=b){p_a = &a;p_b = &b;}printf("a=%d,b=%d", *p_a, *p_b);return 0;
}

2.2指针赋值例

#include<stdio.h>
void main()
{char c = '9', * sp1, * sp2;sp1 = &c; sp2 = sp1;printf("%c", *sp2);
}

2.3输出指针的值

pointer_1=&a;	//把变量a的地址赋给指针变量pointer_1pointer_2=&b;	//把变量b的地址赋给指针变量pointer_2 printf("a=%d,b=%d\n",a,b);	//输出变量a和b的值printf("*pointer_1=%d,*pointer_2=%d\n",*pointer_1,*pointer_2);//输出变量a和b的值

 3,用指针引用数组

当我们定义一个数组时

int a[100]={};

 a是数组的首地址,且是以常量指针的形式保存(不能通过a++等来更改

所以当我们针对数组进行一些操作时,通常将之复制到变量指针(P)上。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{//输入int a[10] = {};int* p = a;for (int i = 0; i < 10; i++){scanf("%d", p++);//恢复指针p = a;//输出for (int i = 0; i < 10; i++){printf("%d\n", *p++);}return 0;
}

 注意经过一系列 的p++会使得p指向数组的末位。需要读取数组需要重新使指针指向数组的首地址

3.1优先级问题 

++和*为同优先级

从左到右依次执行

3.2用数组名作为函数形参

int main()
{	void fun(int arr[], int n);	//对fun函数的声明int array[10];			//定义array数组⋮fun(array,10); 			//用数组名作函数的参数return 0;
} 
void fun(int arr[], int n) 		//定义fun函数
{⋮
}

3.4.多维数组

#include <stdio.h>
int main()
{	int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};printf("%d,%d\n",a,*a);				//0行起始地址和0行0列元素地址printf("%d,%d\n",a[0],*(a+0));			//0行0列元素地址printf("%d,%d\n",&a[0],&a[0][0]);		//0行起始地址和0行0列元素地址printf("%d,%d\n",a[1],a+1);			//1行0列元素地址和1行起始地址printf("%d,%d\n",&a[1][0],*(a+1)+0);	//1行0列元素地址printf("%d,%d\n",a[2],*(a+2));			//2行0列元素地址printf("%d,%d\n",&a[2],a+2);			//2行起始地址printf("%d,%d\n",a[1][0],*(*(a+1)+0));	//1行0列元素的值printf("%d,%d\n",*a[2],*(*(a+2)+0));	//2行0列元素的值return 0;
}
//有一个3×4的二维数组,要求用指向元素的指针变量输出二维数组各元素的值。#include <stdio.h>
int main()
{	int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};int *p;							//p是int *型指针变量for(p=a[0];p<a[0]+12;p++)			//使p依次指向下一个元素{	if((p-a[0])%4==0) printf("\n");	//p移动4次后换行printf("%4d",*p);				//输出p指向的元素的值 }printf("\n");return 0;
}
//输出二维数组任一行任一列元素的值。
#include <stdio.h>
int main()
{	int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};		//定义二维数组a并初始化int (*p)[4],i,j;			//指针变量p指向包含4个整型元素的一维数组p=a;					//p指向二维数组的0行printf("please enter row and colum:");scanf("%d,%d",&i,&j);	//输入要求输出的元素的行列号printf("a[%d,%d]=%d\n",i,j,*(*(p+i)+j));			//输出a[i][j]的值return 0;
}

4.字符串

 4.1通过指针引用字符串

#include <stdio.h>
int main()
{	char string[]="I love China!";	//定义字符数组stingprintf("%s\n",string);		//用%s格式声明输出string,可以输出整个字符串printf("%c\n",string[7]);		//用%c格式输出一个字符数组元素 return 0;
}

 相当于

#include <stdio.h>
int main()
{	char *string="I love China!";	//定义字符指针变量string并初始化printf("%s\n",string);		//输出字符串return 0;

4.2字符串的复制

#include <stdio.h>
int main()
{	char a[]="I am a student.",b[20];	//定义字符数组int i;for(i=0;*(a+i)!='\0';i++)*(b+i)=*(a+i);		//将a[i]的值赋给b[i]*(b+i)='\0'; 			//在b数组的有效字符之后加'\0'printf("string a is:%s\n",a);//输出a数组中全部有效字符printf("string b is:");for(i=0;b[i]!='\0';i++)printf("%c",b[i]);	//逐个输出b数组中全部有效字符printf("\n");return 0;
}
#include <stdio.h>
int main()
{	char a[]="I am a boy.",b[20],*p1,*p2;p1=a;p2=b;//p1,p2分别指向a数组和b数组中的第一个元素for(;*p1!='\0';p1++,p2++) 	//p1,p2每次自加1*p2=*p1;//将p1所指向的元素的值赋给p2所指向的元素*p2='\0';			//在复制完全部有效字符后加'\0'printf("string a is:%s\n",a);	//输出a数组中的字符printf("string b is:%s\n",b);	//输出b数组中的字符return 0;
}

5.函数中对指针的应用

5.1将指针变量作为函数参数

5.1.1指针的定义

定义函数时需要同时定义指针变量

void swap(int *p1,int *p2)	
{
...
}

 值得注意的是:如下的*temp不指向变量而直接赋值,由于temp指向位置为随机,可能会覆盖原有数据,计算机并不允许此类操作

//错误示范
void swap(int *p1,int *p2)
{	int *temp;*temp=*p1;*p1=*p2;*p2=*temp;
}

5.1.2指针的引用

不需要加*

 swap(pointer_1,pointer_2);

5.2将数组传递至函数中

void inv(int x[],int n)		//形参x是数组名
{	int temp,i,j,m=(n-1)/2;for(i=0;i<=m;i++){	j=n-1-i;temp=x[i]; x[i]=x[j]; x[j]=temp;	//把x[i]和x[j]交换}return;
}
void inv(int *x,int n)			//形参x是指针变量
{	int *p,temp,*i,*j,m=(n-1)/2;i=x; j=x+n-1; p=x+m;for(;i<=p;i++,j--){	temp=*i; *i=*j; *j=temp;}	//*i与*j交换return;
}

5.3.返回指针的函数

int *a(int x,int y);

x和y是函数的形参,调用函数可以返回一个Int*型指针

we must return an adress  ##

float *search(float (*pointer)[4],int n)
//形参pointer是指向一维数组的指针变量
{	float *pt;pt=*(pointer+n);	//pt的值是&score[k][0]return(pt);
}
//将数组a中n个整数按相反顺序存放。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int arra[3];
int main()
{int a[] = { 9,8,7};int* p1;int *func(int arr[]);p1 = func(a);for (int i = 0; i < 3; i++){printf("%d\n",* p1++);}return 0;
}
int *func(int arr[])
{int* p=arr,*p2=arra;p = p + 2;for (int i = 0; i < 3; p--, p2++,i++){*p2 = *p;}p2 = arra;return p2;
}

6. *指针数组和多重指针

6.1指针数组

类型名 *数组名[数组长度];

int *p[4];

实例:将若干字符串按字母顺序(由小到大)输出。

//将若干字符串按字母顺序(由小到大)输出。#include <stdio.h>
#include <string.h>
int main()
{	void sort(char *name[],int n);		//函数声明void print(char *name[],int n);	//函数声明char *name[]={"Follow me","BASIC","Great Wall","FORTRAN","Computer design"}; //定义指针数组,它的元素分别指向5个字符串int n=5;sort(name,n); 	//调用sort函数,对字符串排序 print(name,n);	//调用print函数,输出字符串return 0;
}void sort(char *name[],int n)			//定义sort函数
{	char *temp;int i,j,k;for(i=0;i<n-1;i++)			//用选择法排序{	k=i;for(j=i+1;j<n;j++)if(strcmp(name[k],name[j])>0) k=j;if(k!=i){	temp=name[i]; name[i]=name[k]; name[k]=temp;}}
}void print(char *name[],int n)	//定义print函数
{	int i;for(i=0;i<n;i++)printf("%s\n",name[i]);//按指针数组元素的顺序输出它们所指向的字符串
}


http://www.ppmy.cn/news/404713.html

相关文章

第二章_基于redis实现分布式锁

基本实现 借助于redis中的命令setnx(key, value)&#xff0c;key不存在就新增&#xff0c;存在就什么都不做。同时有多个客户端发送setnx命令&#xff0c;只有一个客户端可以成功&#xff0c;返回1&#xff08;true&#xff09;&#xff1b;其他的客户端返回0&#xff08;false…

RocketMq 源码解读-Broker(1)

这边源码分支为release-4.2.0 处理拉取信息请求 通过broker模块下面的processor目录下, 我们找到org.apache.rocketmq.broker.processor.PullMessageProcessor这个类的processRequest方法.这边就不省略代码了, 只是在重要的部分加上注释, 供参阅 private RemotingCommand pr…

三菱电机公布造假问题整改计划

文章来源&#xff1a;日本言叶新闻 文章翻译&#xff1a;泰泽项目部 关注泰泽&#xff0c;实现高利润企业 三菱电机公布造假问题整改计划 日本三菱电机被曝长年存在检测造假&#xff0c;为改善被认为是造假原因的封闭的组织风气&#xff0c;三菱电机宣布提出一系列改进措施&…

怎么学习数据库的相关知识? - 易智编译EaseEditing

学习数据库的相关知识可以按照以下步骤进行&#xff1a; 确定学习目标&#xff1a; 了解数据库的基本概念、原理和常用术语&#xff0c;学习数据库管理系统&#xff08;DBMS&#xff09;的功能和特性&#xff0c;以及掌握数据库设计和查询语言等方面的知识。 学习数据库基础知…

4.2.2 基础指令的操作

显示日期与时间的指令&#xff1a; date 显示日历的指令&#xff1a; cal 简单好用的计算机&#xff1a; bc 1. 显示日期的指令&#xff1a; date 如果在命令行中想要知道目前Linux系统的时间&#xff0c;那么就直接在命令行界面输入date即可显示&#xff1a; [dmtsaistud…

关于电商API接口系列(详情页详情,产品列表,按图搜索,店铺所有产品等数据采集)

一、什么是电商API ​​​​​​​程接口&#xff08;Application Programming Interface&#xff09;&#xff0c;是一组用于访问某个软件或硬件的协议、规则和工具集合。电商API就是各大电商平台提供给开发者访问平台数据的接口。目前&#xff0c;主流电商平台如淘宝、天猫、…

列表添加编辑

列表 <!-- 操作列 --><el-table-column label"操作"><template slot-scope"scope"><el-button size"mini" click"clickEdit(scope.row)">编辑</el-button><el-popconfirm title"这是一段内容确…

oai核心网启动多切片自动生成方法

简介 启动一个切片需要&#xff1a; 核心网侧&#xff1a; 启动核心网yaml文件及相关配置文件&#xff08;datebase conf healthscripts&#xff09; 对应业务的sever &#xff08;如&#xff09;基站侧&#xff1a; 虚拟机 启动ueransim的yaml文件及相关配置 代理程序&#…