重学c/c++之指针

指针概览

什么是指针

指针是用来存放变量地址的,可以直接访问操作内存。

指针的定义和使用

  • 指针变量 :数据类型* 变量名;
//存储整形
int a=3;
int *p=&a;
printf("%d"*p);//3
--------------------
//存储字符
char ch='w';
char *pc=&ch;  
printf("%c",*pc)//w
---------------------
//存储字符串
char *a="acbdef";
//或者调用数组的首地址
char arr[]="acbdef";
char *a=&arr;
printf("%s",a);//acbdef
  • 指针数组:用来存放指针的数组
//简单使用
int a=10;
int b=20;
int c=30;
int d=40;
int * arr[4]={&a,&b,&c,&d};
	for (int i = 0; i < 4; ++i) {
  	  printf("%d",*(arr[i]));
     }
//进阶使用
int arr1[]={1,2,3,};
int arr2[]={4,5,6,};
int arr3[]={7,8,9,};
int *parr[]={arr1,arr2,arr3};
  for (int i = 0; i < 3; ++i) {
      for (int j = 0; j <3 ; ++j) {
         printf("%d",*(parr[i]+j));
        }
    }     
  • 数组指针:指向数组的指针(二维指针以上方便)
int arr[10]={1,2,3,4,5,6,7,8,9,10};
int (*p)[10]=&arr;
for (int i = 0; i <10 ; ++i) {
   printf("%d",(*p)[i]);
    }
  • 函数指针:用来指向函数的指针
int Add(int x,int y){
    return x+y;
}
void Print(char *str){
    printf("%s\n",str);
}
int main() {
    //函数地址
    printf("%p\n",&Add);//00007ff72f6a1731
    int (*pa) (int,int)=Add; //定义函数指针
    printf("%p\n",pa);//00007ff6076d1731
    printf("%d\n",pa(3,4));//调用函数
    void (*str) (char *)=Print; //定义函数指针
    str("Hello,World");//Hello,World
}
  • 函数指针数组:用来指向函数的指针的数组
int Add(int x,int y){
    return x+y;
}
int Div(int x,int y){
    return x-y;
}
int Miu(int x,int y){
    return x/y;
}
int main() {
    int(* parr[3])(int,int)={Add, Div, Miu};//定义
    for (int i = 0; i < 3; ++i) {
        printf("%d",parr[i](2,3));5 -1 0
    }
    return 0;
    
}
  • 回调函数:将参数作为函数的参数传递
void print(char *str){
     printf("hello:%s",str);
}
void test(void (*p)(char *)){
    p("World");
}
int main(){
    test(print);
    return 0;
}
------------qsort的使用------------
struct Stu{
    char name[20];
    int age;
};
int cmp_stu_by_age(const void  *e1,const void  *e2){
    return ((struct Stu *)e1)->age-((struct Stu*)e2)->age;
}
int main(){
    struct Stu s[3]={
        {"zhangsan",26},
        {"lisi",16},
        {"wangwu",20}
    };
    qsort(s, sizeof(s)/ sizeof(s[0]), sizeof(s[0]), cmp_stu_by_age);
    /*
    第一个参数:待排序数组的首元素地址
    第二个参数:待排序数组的元素个数
    第三个参数:待排序数组的元素的大小
    第四个参数:函数指针(排序规则,自己实现)
    */
    for (int i = 0; i < 3; ++i) {
        printf("%d",s[i].age);
    }
    return 0;
  • 指针所占的内存空间
//64位
  cout <<sizeof(int *)<<endl;             //8
  cout <<sizeof(double *)<<endl;		  //8
  cout <<sizeof(float *)<<endl;           //8
  cout <<sizeof(bool *)<<endl;            //8
  cout <<sizeof(char *)<<endl;			  //8
//32位
  cout <<sizeof(int *)<<endl;             //4
  cout <<sizeof(double *)<<endl;		  //4
  cout <<sizeof(float *)<<endl;           //4
  cout <<sizeof(bool *)<<endl;            //4
  cout <<sizeof(char *)<<endl;			  //4

问题:为什么所占内存一样,要有这么多的类型呢?
指针类型决定了指针解引用操作的时候能有多大的权限(能限制几个字节),比如char *的解引用只能访问一个字节,而int *的指针解引用就能访问四个字节。

几种特别的指针

  • 万能指针(void *):可以接收任意类型的指针
int a=10;
void *p=&a;
*p=0;//error,不能进行解引用
p++;//error 不能进行运算
  • 空指针

指针变量指向内存中编号为0的空间,空指针指向的内存是不可访问的。

0~255的内存编号是系统占用的,不可访问。

  • 野指针

定义:指针变量指向非法的内存空间
内存地址没有申请是不可以访问的!!!

int * p = (int *)0x1100;
cout << *p << endl;
  • const修饰指针

const修饰指针有三种情况:
1,常量指针(const int * p = &a)

指针的指向可以修改,但是指针指向的值不可以修改

int a = 10;
int b = 20;
const int * p = &a;
*p = 20;//错误,指针的值不可以改
p = &b;//正确,指针指向可以改

2,const修饰常量——指针常量(int * const p = &a)

值可以改,但是指向不可以改

int a = 10;
int b = 20;
const int * p = &a;
*p = 20;//正确,指针的值可以改
p = &b;//错误,指针的指向不可以改

3,const既修饰指针,又修饰常量

指针的指向和值都不可以修改

int a = 10;
int b = 20;
const int * p = &a;
*p = 20;//错误,指针的值不可以改
p = &b;//错误,指针的指向不可以改

指针的快捷写法

写法意义
*(p++),*p++值还是*p,但p指向了后一位
(*p)++p指向的元素加1
*++p, *(++p)先p++,此时p指针已经移动至下一个位置;然后再*,表示p指针移动之后所指向的值
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值