c语言 amp 运算符的逆运算,C语言基础(二)指针

C语言存储类

1:suto,register,static ,extern

int *a;//正规写法

int* a;

int * a;

int* a,b;//其他写法看起来有歧义

//使用

int i=10;//声明一个整型变量

int *p=&i;//&取地址,*声明一个指针

printf(&i);//i的地址

printf(&p);//*p地址

在32位操作系统中,指针占4个字节,在64位操作系统中,指针占8个字节

printf(sizeof(p))==4;//32位操作系统

printf(sizeof(p))==8;//64位操作系统

解引用-解析地址并放回内存地址中保存的值

//声明一个整型变量

int i = 10;

//将i的地址使用取地址符给p指针

int *p = &i;

//输出 0xffff 16进制地址

printf("地址赋值前i=%d\n", i);//10

printf("地址赋值前p=%d\n", p);//地址

printf("地址赋值前*p=%d\n", *p);//&i的值

//修改地址的值,则i值也变成100

//为解引用的结果赋值也就是为指针所指的内存赋值

*p=100;

printf("地址赋值后i=%d\n", i);//100

printf("地址赋值后p=%d\n", p);//地址

printf("地址赋值后*p%d\n", *p);//100

2:作用域和生命周期是两码事

3:C语言头文件 include<>与include""两种方式 ,“”引号一般是自己写的头文件。<>一般是系统的头文件

4:指针 可以理解为数据类型类似于 int chart float....

指针是一种特殊变量(指针变量),它保存另一个变量的内存地址,32位操作系统占4个字节,64位操作系统占8个字节

概念:操作系统内存是8G,系统为了更好的管理我们的内存,就为内存区的每一个字节都分配一个唯一的编号,这就是地址,指针的实质,就是地址,就是这一个个比那好

5:悬空指针 和野指针 危险

一个指针所指向的内存被释放后,这个指针就被悬空了,访问悬空指针会导致程序不正常,崩溃等问题,如果影响到其他功能,问题很难定位,我们释放内存时,把指向这块内存的指针变量设置为NULL,访问指针变量前判断是否为NULL。

进阶:当有多个指针变量都指向同一块内存时,释放这块内存时,需要将所有指针变量的值都置为NULL,这需要维护所有指向这块内存的指针变量的信息,但是这种方式开销大,所以通常很少使用。使用频率不是非常高的对象,可以在使用前先根据id等索引查找,如果找不到,则不要使用。如果有使用者时,不能释放这块内存,我们可以使用引用计数,只有当引用计数为0时,才真正释放内存,否则,只是引用计数减1。

指向的地址是不确定的指针,为野指针

(1):指针定义后没有初始化,其值是不确定的

(2):被free后没有赋值NULL,后续又继续使用了该指针

(3):指针的操作,超过了变量的作用范围(不是指针越界)

(4):函数返回指向栈内存的指针(栈内存函数运行结束后会被释放)

6:运算符

&运算符 用于取一个对象的地址

*间接寻址符 用于访问指针所指向的地址的值

int *prt 定义一个指针

int b=*prt,b是指针所指向地址的值

&与*是互逆运算

7:通用指针

//通用指针

int n;

char c;

short s;

//指针类型 分别是 int chart short

int *ptr_n = &n;

chart *ptr_c = &c;

short *ptr_s =&s;

void* ptr_void =ptr_n;//整型指针转通用指针,地址不会改变,但是类型会丢失

8:指针的算术运算

(1):对于变量,不同的类型,占用的空间大小不一样

(2):对于不同类型的指针变量,他们占用的空间都是相同的

//指针运算

int arr[]={11,22,33,44,55};

int *p_arr=arr;

size_t j=0;

for ( j=0;j<5;j++){

//自增++ 运算符比 解引用* 高,但++在后为先用后加

//如果++在前则输出 22 33 44 55

printf("%d\n",*p_arr++);//11 22 33 44 55

}

//指针指向地址,指针运算实际上就是移动指针指向的地址位置,移动的位数取决于指针类型(int就

//是32位)*p_arr+1移动四个字节向下一个内存快(由11移动到22)

65a5cfdd1627

32位操作系统.png

指针是指向一个内存空间的变量

int arr[]={11,22,33,44,55};

//直接打印数组arr,arr地址指向数组首个元素

printf("arr=%p\n",arr);//arr=000000000061FD80

printf("*arr=%d\n",*arr);

int *pInt=arr;//把arr数组赋值给pInt指针,指针的地址也是数组首元素地址

printf("数组首元素地址=%p",&*pInt);//000000000061FD80

9:指针和二维数组

//一维数组,一维数组的值不能修改,二维数组的值可以修改,标注:?????????

int array[5]={0};//int *ptr_a

//二维数组,

int array[][3]={

{1,2,3},

{4,2,3},

{1,5,3},

{6,2,3}

}

int (*ptr_a)[3]=arr;

//遍历 数组

//

10:指针的指针

//为什么需要二级指针

11:函数指针

12:总结

//理解一下概念,表示学会了指针

int *p;

int *p[n];

int (*p)[n];

int *p();

int (*p)();

int **p;

//指针最重要的,用指针的时候,脑子一定要明白指针指向哪里!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值