AutoLeaders控制组——C语言指针学习笔记

一.指针

指针与取地址互为逆运算

  • 指针的基本概念:到变量的地址去取值 在这里插入图片描述
    在这里插入图片描述
  • 变量要存储在内存里面,内存里面就根据变量的类型(int,char,float等)随机分配相应的地址去存储变量

在这里插入图片描述
由此处可知为什么*p=变量的值,实际上是一种省略的写法
*p相当于用了可逆运算,所以最后得到的还是变量本身
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

二.指针与数组

有一题求平均成绩,普通方法解法如下
在这里插入图片描述
利用指针解法如下:

#include <stdio.h>
int main()
{
	int score[8]={75,86,70,88,62,87,69,77};
	int sum=0,avg=0,max=0,min=100,i;
	int *p;
	for(p=&(score[0]);p<=&(score[7]);p++)
	{
		sum=sum+*p;
		if(*p>max)
		{
			max=*p;
		}
		if(*p<min)
		{
			min=*p;
		}
	
		
	 } 
	 printf("sum=%d avg=%f\n",sum,sum/8.0);
	 printf("max=%d min=%d",max,min);
	return 0;
}


在这里插入图片描述

  • 由于字符串其实就是字符数组,所以有如下结果

在这里插入图片描述

在这里插入图片描述
数组名=变量地址
在这里插入图片描述
在这里插入图片描述
所以在数组名称后面【数字】表示对应的地址,再加上*,就表示了对应地址上的值。
代码示例如下:

#include <stdio.h>
int main()
{
	int i=10;
	int score[8]={75,86,78,88,62,87,69,77};
	printf("%d\n",*score) ;
	printf("%d\n",*(score+1));
	printf("%d\n",*(score+2)    )  ;
	      
	return 0;
 } 
 

在*()这个形式中,()中的东西说是地址或者说是数组,不要把它想成其他的


```c
#include <stdio.h>
int main()
{
	printf("%d",*("hello,world"));
	printf("%d",*("hello,world"+1));
	      
	return 0;
 } 

三.指针——记录地址的变量

1.取地址符&

  • 只能读取变量的地址,地址大小和int是否相同取决于编译器
  • 数组的地址 int a[10]; &a=a=&a[0];

2.指针——保存地址的变量

  • 形式: int *p=&i(p是指针,指向int,把i的地址交给p)
    称p指向i

  • 指针变量:是具有实际值的变量的地址

  • 作为参数的指针:void f(int *p);
    在函数调用的过程中的到了某个变量的地址
    int i=0;
    f(&i);

  • 代码实现如下

#include <stdio.h>
void f(int *p); 
int main(void)
{
	int i=6;
	printf("&i=%p\n",&i);
	f(&i);
	return 0;
	
}
void f(int *p)
{
	printf("p=%p\n",p);
}

在这里插入图片描述

3.访问地址上的变量(取值)

  • *是一个单目运算符,用来访问指针所指向的变量

  • 对于*p:int *p=a;

    p=变量的值
    &p是p的地址
    p是变量的地址

4.作为参数的指针

参数:void f(int *p)
调用:int i;f(&i);

四.指针的应用——指针有什么用呢?

1.交换两个变量的值:

#include <stdio.h>
void swap(int *pa,int *pb);
int main()
{
	int a=5;
	int b=6;
	swap(&a,&b);
	printf("a=%d,b=%d\n",a,b);
	return 0;
}
void swap(int *pa,int *pb)
{
	int t=*pa;
	*pa=*pb;
	*pb=t;
}

在这里插入图片描述
在这里插入图片描述
返回值不止一个,swap两个变量
在这里插入图片描述

2.函数返回运算状态,结果通过指针返回

  • 常用的套路是让函数返回特殊的不属于有效范围内的表示出错:-1或0, 但当任何数值都是有效的可能结果时(-1或0),就要分开返回 ,用指针来返回值
  • 返回运算状态用return;
  • 注:由于地址不同,所以在调用时要在需要有返回值的的参数前写&

两数相除:

#include <stdio.h>
/**如果除法成功返回1;否则返回0 
*/
int divide(int a,int b,int *result);
int main(void)
{
	int a=5;
	int b=2;
	int c;
	if(divide(a,b,&c)){
		printf("%d/%d=%d\n",a,b,c);
	}
	return 0;
	
}
int divide(int a,int b,int *result)
{
	int ret=1;
	if(b==0) ret=0;//不可以做除法,没有意义
	else{
		*result=a/b;//可以做除法,有意义
	}
	return ret;
}

	
 

常见的错误:定义了指针,没有指向任何变量就开始使用

int *p;

五.指针与数组

1.函数参数表中的数组实际上是指针

所以sizeof(a)=sizeof(int*)

2.数组参数

  • int sum*(int ar,int n);
    int sum(int ,int);
    int sum(int ar[ ],int n);
    int sum(int[ ],int);

    注:在函数定义是参数名称不可省,函数声明时参数名称可以省

3.数组变量是特殊的指针

数组变量是本身的地址,所以:
int a[10];
int *p=a;//无需用&来取地址

  • 由于数组的单元表达的是变量,需要用取地址符&,a==&a[0];
  • 如下是通过循环向数组中输入数字
#include <stdio.h>

#define SIZE 5

int main() {
    int arr[SIZE];
    
    printf("请输入 %d 个整数:\n", SIZE);
    for (int i = 0; i < SIZE; i++) {
        scanf("%d", &arr[i]);
    }
    
    printf("你输入的数组元素为:\n");
    for (int i = 0; i < SIZE; i++) {
        printf("%d ", arr[i]);
    }
    
    return 0;
}

[ ]可以对数组做也可以对指针做
p[0]<==>a[0]

#include <stdio.h>
int main()
{
int min=2;
 int *p=&min;
 printf("*p=%d\n",*p);
 printf("p[0]=%d\n",p[0]);//p[0]指如果p指的是数组,求的是该数组的第一个单元
 return 0;//*p表示所指变量的值,p[0]是把所指的地方当作数组(把变量看作长度为1的数组), 即 int min[0];
 
 	
 } 

*可以对指针做(来取出指针所指变量里的值),也可以对数组做:
如*a=25;
printf(“*a=%d\n”,*a);

六.指针与const,指针运算

1.指针与const

  • const分两种:
    (1)指针不可修改
    int * const q=&i;//q是const,指针变量q只能指向i
    *q=26;//0k 表示通过指针改变i的值是可以的,因为i并不是const
    q++;//error q是const,所以不可以对q进行加减运算

    (2)通过指针不可修改
    const int *p=&i;//表示不能通过p去修改i,
    *p=26;//error *p是const
    i=26;p=&j//ok

判断被const的量要看是const在*的前面还是后面
const *表示不可通过指针修改变量的值
*const指针不可以修改

  • 转换(把非const的值转换成const的)

2.指针的运算

  • 算术运算

只可加减,没有乘除。
指针的每一次递增(减),他其实会指向下(上)一个元素的存储单元。

指针在递增递减时的步长取决于所指向变量数据类型长度,比如int就是4个字节

  • 关系运算
  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值