A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

C语言核心知识点相关总结(二)


三、一级指针
1. 指针的使用: 32位系统下是 4 个字节,64位系统下是 8 个字节

           1在定义的时候用 * 号,代表这个变量那个是指针类型
                     int a = 10;            //定义一个整型变量,存储整数 10
                     int *p = &a;         //定义一个整型指针变量,存储a的地址

           2在配合表达式使用 * 号,代表取值运算符,可以取出这个地址里的值
                     printf("%d\n", *p);                          // 打印p指向的地址里的值
                      printf("%d\n",*(&a));                   // 打印a这个地址里的值
                     printf("%d\n", *p + 1);                   // 取出值,再加1打印出来


2. 指针的几种特殊定义方式:

           1) int * const p;
指针常量:p int*类型,那么const修饰的是p,所以p是常量,表示p指向的地址不可修改,
也就是说,p不能再指向别的地方了,但是可以修改p指向的这个地址里的值。
举例:
                     int a = 10;
                     int b = 20;
                     int * const p = &a;
                     p = &b;                 //错误
                     *p = 100;   //允许

           2)  const int *p;
                     int const *p;
常量指针:p int*类型,那么const修饰的是*p,所以*p是常量,表示p指向的地址里的值不可修改,
也就是说,p里的值不能再重新赋值了,但是可以修改p指向的地址。
                     int a = 10;
                     int b = 20;
                     const int *p = &a;
                     p = &b;                 //可以
                     *p = 100;   //错误

           3) const int * const p;
常量指针常量:p int*类型,那么const分别修饰了p *p所以p*p都是常量,表示p指向的地址不可修改,
同时p指向的地址里的值也不可修改。
                     int a = 10;
                     int b = 20;
                     const int *const p = &a;
                     p = &b;                 //错误
                     *p = 100;            //错误

C Primer Plus "自由的代价,是永远的警惕。"
你定义了一个指针,那就一定要知道这个指针指向的什么地方,而且你要保证这个指针是真实有效的,否则我就用程序崩溃来惩罚你。


四、多级指针

#include <stdio.h>
int main(void)
{
           int a = 10;
           int *p = &a;                   //定义一个一级指针变量,存储了整型变量a的地址
           int **pp = &p;              //定义一个二级指针变量,存储了整型一级指针变量p的地址
           int ***ppp = &pp;       //定义了一个三级指针变量,存储了整型二级指针变量pp的地址

           printf("%p, %p, %p, %p\n", &a, &p,&pp, &ppp);
           // 分别打印各个变量自身所在的内存地址

           printf("%p, %p, %p, %p\n", &a, p, pp, ppp);
           //printf("%d", a);         %d的形式打印a的值:整数
           //printf("%p", p);         %p的形式打印p的值:地址
           // &a : 打印 变量 a 的地址
           // p打印变量 a的地址
           // pp: 打印变量 p 的地址
           // PPP:打印变量 pp 的地址

           printf("%p, %p, %p, %p\n", &a, p, *pp,**ppp);
           // &a : 打印 变量 a 的地址
           // p打印变量 a 的地址
           // *pp:打印变量 a 的地址
           //**PPP: 打印变量 a 的地址

           printf("%d, %d, %d, %d\n", a, *p, **pp, ***ppp);
           // a: 打印 10
           // *P: 打印 10
           // **pp:打印 10
           // ***ppp: 打印 10
}

五、指针 数组的用法

           int num[5] = {10, 20, 30, 40, 50};
           int *p = num;

打印的值                   打印后*p的值是              数组里的原值
// 操作地址
*p++                      10                                      20                                           10      
*(p++)        
                     *++的优先级相同,根据结合性(从右往左),那么p先和后自增运算符++结合,
                     ++操作将在表达式完成后进行自增,也就取出p指向的值之后,p指向的下标后移一位(4个字节)

*++p                    20                                      20                                           10
*(++p)        
                     *++优先级相同,根据结合性(从右往左),那么p先和前自增运算符++结合,
                     ++操作将会立即完成,p指向的下标后移一位(4个字节),然后再取出p指向的值。


// 操作数值
(*p)++                   10                                                11                                     11
根据优先级()小括号优先级最高,p先和*相结合,然后再和后自增运算符++结合,
因为是后自增,所以先打印当前下标的值,然后在原值的基础上自增 1,此时原值已被改变


++*p                    11                                                11                                     11
++(*p)                             
根据结合性/优先级,*p先结合,然后再和前自增运算符++结合,
因为是前自增,所以先在原值的基础上自增1,然后在打印这个值,此时原值已被改变。


总结:如果一个表达式里有多个运算符,则先进行优先级比较,先执行优先级高的运算符;
如果优先级相同,那就看结合性,根据结合方向来做运算。


结合性:
从左往右:
小括号()、数组括号[]、成员选择 . ->,双目运算符,逗号运算符

从右往左:
单目运算符、三目运算符、赋值类运算符

/*
++a:  是直接从变量 a 所在的内存地址中取值,并进行加1操作,再执行表达式剩余部分。
a++ 先把变量的值保存在一个临时寄存器里,然后再执行整个表达式,执行完之后,再把a的值自增1,再返回内存里。

CPU - 寄存器 - 缓存(L1\L2\L3) -来自于内存
CPU只和寄存器做数据交换,对于重复操作的数据会放在缓存里。
但是不管寄存器还是缓存,他们的数据都来自于内存。
*/



未完待续,请看下一篇《C语言核心知识点相关总结(三)》




0 个回复

您需要登录后才可以回帖 登录 | 加入黑马