程序设计基础——指针

一.地址与指针的概念

地址:计算机对内存单元中的数据进行操作,一般按“地址”存取的,也就是对内存单元进行标识编号

指针:它存储的是一个内存地址。这个地址指向的是另一个变量或数据的位置,也就是说,指针可以直接访问内存中的数据。     通过变量的地址进行操作,用指针访问内存和操作地址

使用变量p访问变量x的过程实现了对变量x的间接操作,C语言中把专门存放变量地址的变量称为“指针变量”。

二.定义指针变量

取地址运算符&:单目运算符&是用来取操作对象的地址。例:&i 为取变量 i 的地址。对于常量表达式、寄存器变量不能取地址(因为它们存储在存储器中,没有地址)。

指针运算符*(间接寻址符):与&为逆运算,作用是通过操作对象的地址,获取存储的内容。例:x = &i,x 为 i 的地址,*x 则为通过 i 的地址,获取 i 的内容。

指针声明符 * 在定义指针变量时被使用,说明定义的那个变量是指针。

通常格式:

数据类型 *指针变量名;

eg:        int  *p; // 定义一个数据类型为int型,变量名为p的指针

                char *cp;

                float *fp;

                double *dp1,*dp2;    

 注意:定义多个指针变量时,每一个变量都需要在变量前加上 指针声明符 * 

例:假设 int 型变量 a 内存地址(内存开始地址)为 0x1000 ,如果指针变量 p 指向 a ,那么 p 的内存单元中就存放了 a 的内存地址,即 0x1000 。
注意内存地址内存内容的区别:每一个内存单元有自己的地址同时内存单元里面存放着某些内容

三.指针的基本运算

1.取地址(对指针变量赋值)

int a=1,*p;

p=&a;         // “ & ”为取地址符,也就是指针p被看作成指向变量a或者存放变量a的地址

                                                        取a所在的地址

pa
变量a的地址1、(*p)

①取地址运算和使用指针访问变量

#include<stdlib.h>
#include<stdio.h>
int main()
{
    int a,*p; // 定义整型变量a,指针变量 p
    scanf("%d",&a);
    p=&a;       // 把a的地址赋给指针p,即p指向a  
    printf("a=%d *p=%d\n",a,*p);    //*p 表示指针p所指向变量的值 (*p==a)
    *p=a+1;
    printf("a=%d *p=%d\n",a,*p);
    ++*p; //*p++; *++p;
    printf("a=%d *p=%d\n",a,*p);
//    system("pause");
    return 0;
}

2.指针的算术运算 (右结合)

++*p;

*p++;*++p;         //  都是指针变量先加1,再取其地址对应的内容 *p++ == *(p++)

关于  *(p++)   运算后,p不再指向a,即 p 的内存单元不再是 a 的内存地址

3.指针的赋值

int a=2,*p1,*p2;

p1=&a;        //使指针p1指向整型变量a

p2=p1;         // 使指针p2指向p1

 此外指针的使用会影响到原变量的值  

下面来个例题(利用指针交换 a 和 b 的值)

①在主函数中交换的写法

#include<stdlib.h>
#include<stdio.h>
#include<string.h>
int *px,*py;
int a,b;
int main()
{
    scanf("%d%d",&a,&b);
    px=&a; py=&b;   // 指针取a,b的地址
    int t=*px;
    *px=*py; *py=t;       // 交换 *px *py的值  -->  交换 a b 的值
    printf("%d %d",a,b);    
    system("pause");
    return 0; 
}

②调用函数的写法 

#include<stdlib.h>
#include<stdio.h>
#include<string.h>
int *px,*py;
int a,b;
void  swap(int *a,int *b) // 定义指针类型变量 区别与 *px *py 
{
    int t=*a;
    *a=*b; *b=t;
}
int main()
{
    scanf("%d%d",&a,&b);
    px=&a; py=&b;
    swap(px,py);
    printf("%d %d",a,b);
    system("pause");
    return 0; 
}

4.指针的关系运算

① px>py   // 判断 px 存储的地址是否大于 py 存储的地址

② px==py  // px 与 py 是否对应同一个储存单元

③px==0 || px!=0 // 判断px是否为空指针

 四.指针与数组

定义数组与指针: 

int  a[6]={0,1,2,3,4,5},*p;

1.指向数组的指针:

一维数组:一个数组的首地址为数组名a,或者是数组的第一个元素的地址

p=a;                //  数组名为首地址 

p=&a[0];   // 取数组中第一个元素a[0]的地址

2.对指针数组的操作

例:以上述数组a的值为例

#include<stdlib.h>
#include<stdio.h>
#include<string.h>
int *px;
int num[5]={0,1,3,5,7};
int main()
{
    px=num;   // 取数组的地址操作(或者) px=&num[0];
    for(int i=0;i<=4;i++)
    {
        printf("%d ",*(px++));    //    (p+i) 为指针加整数操作 对应p指向下一个元素即a[i]
    }                     // 其中区别 (*px)++ 与 *(px++)
    system("pause");
    return 0; 
}

其中 (p+1) 对应 a[1]  (p+k) 对应 a[k] 

对上述两种 (*px)++*(px++) 操作的理解与区别 (指针在数组的应用)

① (*px)++ : *px 为px指向元素的值 然后再自加

②*(px++) :  px++ 表示为指针加整数操作 指向 a 的下一个元素 然后再通过 * 指向其元素值

注 : 考虑边界范围,不能超出数组长度

五.指针与字符串

1.格式

字符串指针和整型数组指针的使用差不多

#include<stdlib.h>
#include<stdio.h>
#include<string.h> 
char ch[1001];
char *str;
int main()
{ 
    scanf("%s",ch);
    str=ch;  // 或者 str=&ch[0];  都会取其第一个字符的地址
    printf("%c %c",*str,*(str+1));  // str++  指向下一个字符
    system("pause");
    return 0;
}

 2.关于字符串处理函数

①字符串的拼接  strcat

核心代码:

strcat(s1,s2); // 将 s2 拼接到字符数组 s1 的尾部 注: s1 的长度需要足够容纳两个字符串

 输入样例: woai   biancheng

拼接输出: woaibiancheng

②字符串的复制 strcpy

strcpy(s1,s2)  // 将 s2 的字符 赋给 s1  确保 s1 的长度

③ 字符串的比较 strcmp

printf("%d",strcmp(s1,s2));

// 比较字符串的大小(按字典序)

s1 > s2 返回数>0      返回字典序的差

s1 < s2 返回数<0

s1 == s2 返回 0  

 例如: s1[5]='hello'; 

             s2[5]='aello';    返回 7

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值