指针的小知识

最开头先举个例子,后面会有指针的知识点。 

 以下代码提供运行:

#include<stdio.h>
int main()
{
  
int value = 10;  
int *ptr = &value; // ptr 存储 value 的地址  
printf("%d\n", *ptr); // 输出 10,因为 *ptr 解引用了 ptr,获取了 value 的值  
*ptr = 20; // 修改 value 的值为 20,因为 *ptr 解引用了 ptr
printf("%d\n", *ptr);
printf("%d\n", value);
printf("%d\n", ptr);
}

 *ptr等于某个地址(如&a)时,是将该地址(&a)存储在该指针(*ptr)内,当指针的值改变时该地址所指向的值也会随之改变。

就如以上代码所示当*ptr = 20时,value的值也变为20,而不是原先的10。

知识点

指针的基本概念

1.地址和指针

在c语言中地址称为指针

我们先举个例子

int num;
scanf("%d",&num);

‘&’为取地址运算符,用于取变量的地址,所以&num表示的是num的地址(指针),scanf()函数可以根据该地址,去访问num的存储空间,并且改变num的内容。

 又比如

#include<stdio.h>
#include<string.h>
int month(char *s);
int main()
{	
  int *p,num;
  num = 2;
  p = &num;
  printf("%d",*p);
}
//输出结果为:2

将num的地址赋值给p,则p指向的地址就是num的地址,可得出结果*p = 2,其中p是地址。

数据类型要和指针变量一致,如上 *p与num的类型必须一致才可被赋值。

2.指针运算符

#include<stdio.h>
#include<string.h>
int month(char *s);
int main()
{	
  int *p,num;
  p = &num;
  *p = 9 ;
  printf("%d %d",*p,num);
}

将9赋值给p所指向的内存空间,而其内存空间又是num的内存空间,故num和*p等价。

指针与数组

一维数组

&a[i](i = 0,1 ,2 ,3...... )表示数组a下标为i的数组元素地址。

下面我们来举个例子:

int a[5];
int *pa;
pa = a;//等价于pa = &a[0]

a表示数组首地址

其中a+1的值为&a[1],其他元素以此类推

可以采用pa[i]的方式表示a[i]

诺有如下定义语句

int a[5],i;
int *pa = a;

 则有

地址表达式:

&a[i] ==  a+i == pa+i == &pa[i]。

数组元素的值表达式:

a[i] == *(a+i) == *(pa+i) == pa[i]。

值得注意的是,a为指针常量其值不可变,pa为变量,可变

a++,a = pa都是不行的,但是换成pa就可以。

这里提供一种组合,大家可以根据上面的等价关系进行修改,验证结果


#include<stdio.h>
int main()
{	
  int a[10];
  int *pa = a;
  int i;
  for(i = 0; i<5;i++)
  scanf("%d",a+i);
  for(i = 0; i<5;i++)
  printf("%d",*(pa+i));
  
}

还可以等价于: 

#include<stdio.h>
int main()
{	
  int a[10];
  int *pa = a;
  for(pa = a ; pa < a+10 ; pa++)
  scanf("%d",pa);
  for(pa = a ; pa < a+10 ; pa++)
  printf("%d",*pa);
  
}

其中的pa代表地址,将a的地址赋值给pa,因此for里算的是地址的取值范围,a+10表示的是a[10]的地址,而不是简单的+1操作。

合并数组
#include <stdio.h>
#define M 5
#define N 7
void fun(int a[], int m, int b[], int n, int c[]);
int main()
{   
    int arra[M],arrb[N];
    int arrc[M+N],k;
    int i;
    for(i=0;i<M;i++)
        scanf("%d",&arra[i]);
    for(i=0;i<N;i++)
        scanf("%d",&arrb[i]);    
    fun(arra,M,arrb,N,arrc);    
    for(k=0;k<M+N;k++)
        printf("%d ",arrc[k]);
    printf("\n");
    return 0;
}
void fun(int a[], int m, int b[], int n, int c[])
{
    int i = 0, j = 0, k = 0;
    while (i < m && j < n)
    {
        if (a[i] < b[j])//a[i]等价于*(a+i)
            c[k++] = a[i++];
        else
            c[k++] = b[j++];
    }
    while (i < m)
        c[k++] = a[i++];
    while (j < n)
        c[k++] = b[j++];
}

上述函数fun()中a[ ]表示的是一个指针,指向函数的首地址及可表示为*a,但在函数内部,我们使用 a[i] 来访问数组中的元素,而不是直接使用 a。这是因为 a[i] 实际上是 *(a + i) 的简写,表示从起始地址开始偏移 i 个元素后的值。所以,在函数内部,我们比较的是数组中元素的值,而不是它们的地址。

最大最小数
#include <stdio.h>
void max_min(int x[],int n,int *pmax,int *pmin);
int main()
{
    int a[10];
    int amax,amin;
    int i;
    for(i=0;i<10;i++)
    {
        scanf("%d",&a[i]);
    }
    max_min(a,10,&amax,&amin);
    printf("%d %d\n",amax,amin);
    return  0;
}
void max_min(int x[],int n,int *pmax,int *pmin)
{
    int i ;
    *pmax = *pmin = x[0];
    for(i = 0 ; i < n ; i++)
    {
        if(x[i] > *pmax)
            *pmax = x[i];
    }
    for(i = 0 ; i < n ; i++)
    {
        if(x[i] < *pmin)
            *pmin = x[i];
    }
}

杂七杂八

while(*p)的意思

while (*p) 是一个条件语句,它的含义是“只要指针 p 所指向的值不为零”,就执行循环体中的代码。

在 C 语言中,指针 p 可以被用作条件表达式,如果指针 p 不为 NULL(或者说不指向数组或字符串的末尾),条件表达式 *p 就会被解释为真,循环就会继续执行。当指针 p 指向数组或字符串的末尾时,*p 的值将为 0,条件表达式将被解释为假,循环就会终止。

在上述例子中,当指针 p 指向数组的末尾时,*p 的值为 0 时,循环将终止,因为条件 while (*p) 不再满足。(来自chatgpt)

*p++和++*p的区别
int arr[] = {1, 2, 3};
int *p = arr;

// ++*p: 先递增 arr[0] 的值,再输出递增后的值
printf("%d\n", ++*p); // 输出 2

// *p++: 先输出 arr[0] 的值,再将指针 p 后移一个位置
printf("%d\n", *p++); // 输出 2

// 现在指针 p 指向了 arr[1]

int arr[] = {1, 2, 3};
int *p = arr;

printf("%d\n", ++*p); // 先递增 arr[0] 的值,arr[0] 变为 2,然后输出 2
printf("%d\n", *p++); // 输出 arr[0] 的值,即 2,然后将指针 p 后移一个位置
printf("%d\n", *p);   // p 指向了 arr[1],输出 arr[1] 的值,即 3

这三串代码有一定的关联,第一个先递增arr使其变为arr[1]然后输出

第二个是先输出*p,然后再递增到下一个地址,及第二个的值即为第一个的值,第二个值递增的下一个地址赋值到了第三个。

  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值