指针详解(上)

指针是C语言重点之一,使用非常广泛,恰当的使用会使程序看起来更简单,当然,使用不恰当的话会使指针指错了地方。

指针:一种保存变量地址的变量。
1.声明形式化一般为 type(指针类型) *name;
2.在32位平台上地址用4个字节空间来存储,在64位平台上地址用8个字节空间来存储;
一级指针:即指针,存放内存地址。
二级指针:存放指针变量地址的指针。

#include <stdio.h>
int main()
{
    int a=30;//定义了一个整型变量a
    int *p=NULL;//指针变量的声明,NULL 指针是一个定义在标准库中的值为零的常量
    p=&a;//一级指针变量p存放了整型变量a的地址
    int **ptr=&p;//二级指针变量ptr存放了一级指针变量p的地址
    return 0;
}

这里写图片描述

指针类型
指针变量和普通变量一样都是具有类型的,指针变量的类型是type * 的格式。

int *p=NULL;      //int * 类型指针为了存放int类型变量的地址
char *str=NULL;   //char * 类型指针为了存放char类型变量的地址
float *tmp=NULL;  //float * 类型指针为了存放float类型变量的地址
double *ret=NULL; //double * 类型指针为了存放double类型变量的地址

……

指针类型的确定:把指针声明里的名字去掉,剩下的部分就是这个指针的类型。

int *p;//指针的类型是int *
float **f;//指针的类型是float **
int (*ptr)[3];//指针的类型是int (*)[3]

指针所指向的类型:把指针声明的名字和名字左边的 * 去掉,剩下的部分就是指针所指向的类型.

int *p;//指针所指向的类型是int
float **f;//指针所指向的类型是float *
int (*ptr)[3];//指针所指向的类型是int ()[3]

指针运算
1.指针的自增,自减运算
对指针进行自增,自减运算时,即值增减数据类型字节数。

#include <stdio.h>
#define MAX 4
int main()
{
   int arr[MAX]={2,4,6,8};
   int *ptr=NULL;
   int i=0;
   ptr=arr;
   for(i=0;i<MAX;i++)
   {
      printf("arr[%d]=%p\n",i,ptr);
      ptr++;
   }
   return 0;
 }

这里写图片描述

2.指针减指针运算
指针减指针运算前提是两个指针属同一份空间,结果是两个指针之间元素的个数

#include <stdio.h>
#include <assert.h>
int my_strlen(const char *str)
{
   const char *start=str;
   assert(str);
   while(*str!='\0')
   {
      str++;
    }
   return str-start;   
}
int main()
{
   const char *str="abcdef";
   int ret=my_strlen(str);
   printf("%d ",ret);
   return 0;
}

这里写图片描述

3.指针解引用
可以通过解引用操作符*来获取指针指向地址的内容.
指针的类型决定了对指针解引用时能操作几个字节。

int *的指针解引用能访问4个字节;
char *的指针解引用能访问1个字节。

#include <stdio.h>
int main()
{
   int p=10;
   int *pa=&p;
   *pa=0;
   char *pc=&p;
   *pc=0;
  return 0;
}

这里写图片描述

int *

char *

例:用指针形式进行冒泡排序

#include <stdio.h>
void Sort(int *arr, int sz)
{
    int i = 0;
    for (i = 0; i < sz - 1; i++)
    {
        int j = 0;
        for (j = 0; j < sz - 1 - i; j++)
        {
            if (*(arr + j) < *(arr + j + 1))
            {
              int ret = *(arr + j);//对指针解引用得到了数组中元素的值
              *(arr + j) = *(arr + j + 1);
              *(arr + j + 1) = ret;
            }
        }
    }
}
int main()
{
    int arr[] = { 1, 3, 5, 7, 9, 0, 8, 6, 4, 2 };
    int size = sizeof(arr) / sizeof(arr[0]);//sizeof求数组的长度
    int i = 0;
    Sort(arr, size);
    for (i = 0; i < size ; i++)
    {
        printf("%d ", arr[i]);
    }
    return 0;
}

4.指针加减整数
不同类型的指针加减整数,向前或向后移动的字节不同。

#include <stdio.h>
int main()
{
  int tmp=10;
  int *pa=&tmp;
  char *pc=(char *)&tmp;
  printf("%x\n",pa);
  printf("%x\n",pa+1);
  printf("%x\n",pc);
  printf("%x\n",pc+1);
  return 0;
}

这里写图片描述

const修饰指针
1.const 修饰一级指针

int main()
{
   int num=15;
   const int *p=&num;//不能改变指针变量p所指向的内容
   int * const p=&num;//不能改变指针变量p所指向的变量,但其内容可变

2.const 修饰二级指针

int main()
{
   int num=16;
   int *p=&num;
   int **ptr=&p;
   int const **ptr=&p;//不能通过ptr来改变p所指向地址存的变量所指向的空间内容(不能通过ptr来改变num)
   int ** const ptr=&p;//ptr不能改变指向
   int * const *ptr=&p;//不能通过ptr来改变其所指向的内容
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值