《C语言程序设计》指针

记录学习过程中的知识点

一、指针引用数组

1.1 数组与指针

数组名a代表数组首元素的地址,是一个指针型常量,其值在程序运行期间固定不变

1.2 多维数组与指针

1.2.1 多维数组元素的地址

请添加图片描述

1.2.2 指向多维数组元素的指针变量

1、指向数组元素的指针变量

也就是把而为二维数组扯开,看做一个一维数组,计算目标元素的相对位置

a[i][j]的相对位移: i*m + j
2、指向由m个元素组成的一维数组的指针变量
int (*p)[4]; 指针变量p的基类型为包含4个元素的一维数组,长度为16字节
printf("%d",*(*(p+i)+j));  输出a[i][j]的值
3、指向数组的指针作为函数参数
float score[3][4]={{65,50,66,70},{80,56,99,100},{56,77,55,36}};
average(*score,12); // 求12个分数的总平均数
search(score,2);  //求序号为2的学生的成绩
void average(float *p,int n)
{
    float *p_end;
    float sum=0,aver;
    p_end=p+n-1;
    for(;p<=p_end;p++)
   		sum=sum+(*p);
   	aver=sum/n;
   	printf("%d",aver);
}
void search(float(*p)[4],int n)
{
    int i;
    for(i=0;i<4;i++)
    	printf("%5.2f",*(*(p+n)+i));
}

二、指针引用字符串

2.1 引用字符串的两种方式

2.1.1 字符数组

使用字符数组存放一个字符串,通过数组名否则下标引用字符串中的一个字符,也可以通过数组名和格式申明“%s”输出该字符串。

char string[]="I love China!";
printf("%s\n",string);
printf("%c\n",string[3]);

字符数组初始化时,长度是确定的,长度因为14,其中13个字节存放“I love China!”,第14个字节存放 ‘\0’

'\0’的ASCII码为0

2.1.2 字符指针变量

使用字符指针变量指向一个字符串常量并应用

char *string = "I love China";
printf("%s",string);

等价于

char *string;
string = "I love China!";

C语言只有字符变量,没有字符串变量

2.2 对字符串中字符的存取

2.2.1 下标法

char a[]="I am a student", b[20];
for(int i=0;*(a+i)!='\0',i++)
	*(b+i)=*(a+i);
*(b+i)='\0';

2.2.2 指针变量法

char a[]="I am a student", b[20],*p1,*p2;
p1=a;
p2=b;
for(;*p1!='\0';p1++,p2++)
	*p2=*p1;
*p2='\0';

2.3 字符指针做函数参数

char a[]="I am a teacher";
char b[]="I am a student";
void copy_string(char from[],char to[])

2.3.1 字符数组名做函数参数

copy_string(a,b);

2.3.2 字符型指针变量做实参

char *from=a,*to=b;
copy_string(from,to);

2.3.3 字符型指针变量做形参和实参

void copy_string(char *from,char *to)

tips
字符数组中各元素的值是可以被改变的,可以再对它们进行赋值
字符指针变量指向的字符串常量中的内容是不可以被取代的,不可以再对其赋值

正确:

char str[]="I love China";
a[2]='*';

错误:

char *b="I love China";
b[2]='*';

三、指向函数的指针

3.1 函数与指针

函数名代表函数的起始位置

指向函数的指针变量——存放某一函数的起始地址

int (*p)(int,int);

p是一个指向函数的指针变量,它可以指向函数类型为整型且只有两个整型参数的函数

3.2 指针变量调用函数

int a=1,b=2,c;
int (*p)(int,int);
p=max;
c=(*p)(a,b);
printf("%d",c);
int max(int x,int y)
{
	return z=x>y?x:y;
}

此时 指向函数的指针p 和 函数名max 同时指向函数的起始地址

tips:

  • 再给函数指针变量赋值时,只需给出函数名不必给出参数
  • 用函数指针变量调用函数时,只需将(*p)代替函数名即可
  • 对指向函数的指针变量不能进行算数运算

3.3 指向函数的指针作函数参数

指向函数的指针变量的一个重要用途就是把函数的入口作为参数传递到其他函数

void fun(int (*x1)(int),int(*x2)(int,int)) // f1,f2
{
	int a,b,i=3,j=5;
	a=(*x1)(i);		//调用f1函数,i是实参
	b=(*x2)(i,j);	//调用f2函数,i,j是实参
}

应用案例:

int fun(int x,int y,int(*p)(int,int));
int max(int,int);
int min(int.int);
int i;
scanf("%d",&i);
if(n==1) printf("max:%d\n",fun(a,b,max));
else printf("min:%d\n",fun(a,b,min));
int fun(int x,int y,int(*p)(int,int))
{
	return (*p)(x,y);
}

还可求定积分的通用函数

四、返回值指针值的函数

案例:输出第k个学生的所有成绩

float *search(float(* pointer)[4],int n)
{
	float *pt;
	pt=*(pointer+n);
	return pt;
}
void main()
{
	float score[3][4]={{65,50,66,70},{80,56,99,100},{56,77,55,36}};
	float p;
	int k;
	scanf("%d",&k);
	p=search(score,k);
	for(int i=0;i<4;i++)
		printf("%5.2f\t",p+i);
	printf("\n");
}

案例:输出所有不及格学生4门课程的成绩

float *search(float(*pointer)[4])
{
	float *pt;
	pt=NULL;
	for(int i=0;i<4;i++)
		if(*(*pointer+i)<60)
			pt=*pointer;
	return pt;
}
int main()
{
	float score[3][4]={{65,50,66,70},{80,56,99,100},{56,77,55,36}};
	float *p;
	for(int i=0;i<3;i++)
	{
		p=search(score);
		if(p)
		{
			for(int j=0;j<4;j++)
				printf("%5.2f\t",*(p+j));
		}
		printf("\n");
	}
	return 0;
}

五、指针数组

一个数组,其元素均为指针类型数据
指针数组中的每一个元素都存放一个地址,相当于一个指针变量

int *p[4];

5.1 案例

案例:将若干字符串按照字母顺序排序

选择法排序:

void sort(char *name[],int n)
{
	char *temp;
	for(int i=0;i<n-1;i++)
	{
		for(int 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;
		}
	}
}
int main()
{
	char *name[]={"Hello Jack","BASIC","Great Wall","Java","Computer Sience"};
	int n=5;
	sort(name,n);
	for(int i=0;i<n;i++)
		printf("%s\n",name[i]);
	return 0;
}

5.2 指针数组做main函数形参

int main(int argc, char *argv[])
  • argc:int型变量,表示接受形参的个数
  • argv[]:字符指针数组,用来接收从操作系统命令行中传来的字符串中首字符的地址

假设命令行中输入:
// 程序文件名为file1.exe
// 命令行中的参数都是字符串

file1 China Beijing

则向main函数中传入的参数个数为3,参数分别为file1,China,Beijng
但是我们在写程序处理时,一般没有用文件名,所以要注意跳过第一个参数(文件名file1)

六、多重指针(指向指针数据的指针)

char **p;

char *(*p)  // 表示p指向的是char*型的数据,p指向一个字符指针变量

如果引用*p,就得到p所指向的字符指针变量的值

char *name[]={"Hello Jack","BASIC","Great Wall","Java","Computer Sience"};
char **p;
for(i=0;i<5;i++)
{
	p=name+i;
	printf("%s\n",*p);
}
return 0;

七、动态内存分配与指向它指针变量

7.1 内存的动态内存分配

全局变量分配在诶村长的静态存储区
局部变量分配在内存中的动态存储区——栈

内存动态分配区域——堆
用于存放一些临时用的数据,需要时随时开辟,不需要时随时释放,根据需要向系统申请所需大小的空间,由于未在声明部分定义其类型,所以只能通过指针进行引用

7.2 建立内存的动态分配

#include <stdlib.h>

7.2.1 malloc()

  1. 函数原型
void *malloc(unsigned int size)
  1. 作用:
  • 在内存的动态存储区分配一个长度为size的连续空间,
  • 返回值是所分配区域的第一个字节的地址,
  • 指针基类型为void(不指向任何类型的数据,只是提供一个纯地址),如果内存空间不足,返回空指针NULL
  1. 使用
malloc(100);

7.2.2 calloc()

  1. 函数原型
void *calloc(unsiged n,unsigned size)
  1. 作用:
  • 在内存的动态存储区中分配n个长度为size的连续空间
  • 动态数组
  1. 使用
calloc(50,4); // 开辟50x4个字节的临时分配域,把首地址赋给指针变量p

7.2.3 realloc()

  1. 函数原型
void *realloc(void *p,unsigned int size)
  1. 作用
  • 使用realloc函数重新分配通过malloc或者calloc函数获得的动态空间大小
  1. 使用
realloc(p,50);

7.2.4 free()

  1. 函数原型
void free(void *p);
  1. 作用
  • 释放指针变量p所指向的动态空间,使这部分空间能够重新被其他变量使用
  1. 使用
free(p);

7.2.5 void型指针变量

void型指针变量——指向空类型不指向确定的类型,再将它的值赋给另一指针变量时,由系统对它进行类型转换,是指适合与被复制的变量的类型

地址应该包含基类型的信息,这样就知道存储单元大小,实现对数据的存取,这种无指向的地址所标志的存储单元中是不能储存任何数据的,故无法通过这种地址对内存存取数据,

在程序中它只是过渡性的,只有转化为有指向的地址,才能存取数据。

int *p;
p = (int *)malloc(5*sizeof(int)); //调用malloc返回的是void*型的,要将其赋给p,必须要进行类型转换

八、指针小结

  1. 地址,按照指针型数据的存储方式存储
  2. 一个地址型的数据包含
  • 表示内存编号的纯地址
  • 指针类型
  • 以它为标识的存储单元存放的数据类型——基类型
  1. 指针就是地址,指针变量用来存放地址
  2. 指针变量归纳比较
    请添加图片描述
  3. NULL 可以使p指向地址为0的单元
#define NULL 0
p=NULL;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
很抱歉,我无法提供PPT文件,但我可以向您提供一些关于C语言程序设计指针的基本信息。指针C语言中是非常重要的概念,它允许我们直接访问和操作内存地址。以下是一些关于指针的基本知识: 1. 指针的定义:指针是一个变量,其值为内存地址。我们可以使用指针来存储变量的地址,并通过解引用操作符(*)来访问或修改该地址上的值。 2. 指针的声明和初始化:指针变量的声明需要指定所指向的数据类型。例如,声明一个指向整数的指针可以这样写:int *ptr;,其中 * 表示指向整数的指针。 3. 取址运算符(&):取址运算符用于获取一个变量的地址。例如,如果有一个整数变量x,可以使用 &x 来获取它的地址。 4. 解引用运算符(*):解引用运算符用于访问指针所指向的内存地址上的值。例如,如果有一个指向整数的指针ptr,可以使用 *ptr 来获取该地址上存储的值。 5. 指针和数组:在C语言中,数组名本身就是一个指向数组首元素的指针。因此,我们可以使用指针来对数组进行操作。 6. 动态内存分配:C语言提供了几个函数(如malloc、calloc和realloc)来在运行时动态分配内存。这些函数返回一个指向分配内存的指针,我们可以使用该指针来访问和操作分配的内存。 这些是关于C语言程序设计指针的一些基本知识点。希望对你有所帮助!如果你有任何更具体的问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杰西啊杰西

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值