控制组——指针笔记
一.指针
指针与取地址互为逆运算
- 指针的基本概念:到变量的地址去取值
- 变量要存储在内存里面,内存里面就根据变量的类型(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个字节
- 关系运算