c语言利器-指针

在c&c++里面指针是很重要的,也是较难理解的。指针的用法非常灵活 ,下面通过具体的例子来说说指针的常见的用法。

指针介绍: 

     百度介绍: 在计算机科学中,指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向(points to)存在电脑存储器中另一个地方的值。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。因此,将地址形象化的称为“指针”。意思是通过它能找到以它为地址的内存单元[1] 高级语言中,指针有效地取代了在低级语言,如汇编语言与机器码,直接使用通用暂存器的地方,但它可能只适用于合法地址之中。指针参考了存储器中某个地址,通过被称为反参考指针的动作,可以取出在那个地址中存储的值。

     还是通俗点,打个比喻 :假如你有一把钥匙,但你不知道该钥匙对应的是哪一户人家?你自然有他也做不了什么。但是当有个人高数你说,这钥匙是李四家的 。你按照指引路线找到李四家后。你想想可以干什么呢 ?我是不是只要打开了门 ,李四家的东西我是不是可以随意拿取(危险性也明了吧)。指针就类似指引,指引有了接下来的就只是用钥匙打开门取用罢了。

 指针常用分析:

1、指针指向变量:

代码块:

/**
   @指针用法
   @author lfb
*/
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#define NUM_SIZE 50
using namespace std;
void swap(int x,int y)
{
       int tmp;
       tmp = x;
       x = y;
       y = tmp;
}
int main(){
      int a = 2;
      int b = 3;
      printf("a=%d,b=%d\n",a,b);
}

最后输出的结果还是a = 2,b =3。因为在函数调用时,实参和形参之间只是值传递。但我们使用指针结果就不一样了。

void swap(int *x,int *y)
{
    int tmp;
    tmp = *x;
    *x = *y;
    *y = tmp;
}
int main()
{
   int a = 2,b = 3;
   test(&a,&b);
   printf("a=%d,b=%d\n",a,b);
   return 0;
}

输出结果a=3,b=2。变量a和b的值发生了交换。这是因为我们利用指针访问变量的存储单元,间接修改变量的值。

2、指针指向数组:

定义一个数组并初始化,int array[4]={1,2,3, 4},定义一个指针变量并把数组的地址赋给它,int *p=array,注意数组名就是数组的地址,而且数组的地址就是首元素的地址。因此我们的指针变量就指向了数组的首元素,*p = 1。如果把*(p+1),那么指针变量就指向了数组的下一个元素2,注意p+1与*(p+1)不同, p+1表示第一个元素值加1。因此我们可以利用指针来遍历数组的各个元素:

void print()
{
   int array[4]={1,6,3,4};
   int *p = array;
   for(int i = 0;i<4;i++)
   {
      printf("array[%d] = %d\n",i,*(p+i));    //*(p+i)与p[i]等效
   }
   return 0;
}

 3、指针指向字符串:

我们都知道用数组存储字符串,如char name[20]="abc",上面已经简单讲述了指针指向数组,所以我们可以这样做,char *name="abc",指针变量指向字符串的首个字符并可以依次访问字符串的各个字符。

void print()
{
   char *array = "abc";
   for(int i = 0;i<strlen(array);i++){
       printf("%c ",*(array+i));
   }
   return 0;
}

4,指针指向函数:

我们需要知道怎样表示一个指针指向函数,其实就是语法要正确,用代码来说明一下:

int sum(int x,int y)
{
    return x+y;
}
int main()
{
    int a = 2,b = 3;
    int (*p)(int,int);          //定义一个指针函数
    p = sum;                   //指向sum函数
    int result = (*p)(a,b);
    printf("结果为:%d\n",result);
    return 0;
}

上面代码块里语句(*p)(a,b)可以用p(a,b)来代替,因为p和sum就是一样的,只是用前者可能更容易理解一点。而我们要知道怎样定义一个指针指向函数, int (*p)(int,int)这是固定写法。指针指向函数用起来确实有点抽象。

5,指针指向结构体:

我们首先首先定义一个结构类型,

typedef struct stu

{

     char *name;

      int  ages;

}stu,*Stu;

/**
   @指针用法
   @author lfb
*/
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#define NUM_SIZE 50
using namespace std;
typedef struct stu
{
     char *name;
     int  ages;
}stu,*Stu;
int main(){
    stu s = {"coder",10};
    cout<<s.name<<" "<<s.ages<<endl;
    Stu p;
    p = &s;
    cout<<(*p).name<<" "<<(*p).ages<<endl;
}
定义一个指针指向结构体类型s,struct student *p;把结构体变量s的地址赋给指针变量p,p=&s;我们可以有3种方式来访问结构体中的属性:

stu.ages=15; (*p).ages=15; p->ages=15;不过第三种方式在C语言中只能用来指向结构体。

6,还介绍下二级指针:二级指针又分为指向指针变量的指针和指向数组的指针。二维数组经常用。

代码 :

/**
   @二级指针的使用
   @author lfb
*/
#include<iostream>
#include<algorithm>
#include<cstdlib>
#define NUM_SIZE 50
using namespace std;
void printMatrix(int n,int m,int **a){
    for(int i = 0;i<n;i++){
       for(int j = 0;j<m;j++){
           cout<<a[i][j]<<" ";
       }
        cout<<endl;
    }
}
int main(){
        int n,m;
       //cout<<"输入二维数组行与列数:"<<endl;
        cin>>n>>m;
        int **p;
        //p = new int *[n];                       //分配n行
        p = (int **)malloc(n *sizeof(int *) ); //分配n行
        for(int i = 0;i<n;i++)
        {
            /*p[i] = new int[m];*/                 //为每行分配m个数据空间
            p[i] = (int *)malloc(m*sizeof(int) ); //为每行分配m个数据空间
        }
        for(int i = 0;i<n;i++){
           for(int j = 0;j<m;j++){
               cin>>(*(p+i))[j];   //(),[]是1级优先级,左结合,*是2级优先级,右结合
                                  //*(p+i)表示二维数组第i行
           }
        }
         //cout<<"打印二维数组为:"<<endl;
         printMatrix(n,m,p);
         /*释放申请的堆区动态资源*/
         free(p);      //p所指的内存被释放,但是p所指的地址仍然不变*
         p = NULL;    //一定要将p置空,否则为"野指针"
         return 0;
}

    PS:关于指针, 推荐这篇博客还不错,简单明了。https://blog.csdn.net/u010154760/article/details/44921067

 

最后:使用指针,如果仅指向某个变量,则无需分配内存。否则必须初始化,分配内存。当然分配了内存,最后记得释放内存。

 


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值