Day12 C基础(指针进阶)

文章目录

  • 指针修饰
    • 1.const 修饰
    • 2.void
  • 大小端
  • 二级指针
  • 指针和数组
    • 1.指针和一维数组
      • 直接访问:
      • 间接访问:
    • 2.指针和二维数组
      • 直接访问:
      • 间接访问:
  • 数组指针

指针修饰

1.const 修饰

1)const int num = 10;

const int num = 10;
   num = 3; 

int* p = #
*p = 3;  // 可以

2)const int *p; // 修饰 *p ,指针指向的内容不能更改,指针的指向可以修改
int const *p; // 也可以这样表示修饰 *p

int num = 10;
 const int *p = #
 *p = 20;  // 错误,因为 *p 被修饰

int sum = 20;
p = ∑  // 可以

3)int* const p; // 修饰 p ,指针的指向不能修改的,指针指向的内容可以修改
int num = 10;
int sum = 20;
int* const p = #

p = ∑  // 错误
*p = 20; // 可以

4)修饰函数参数

2.void

void num;  // 不允许修饰变量
void* p;   // p 是任意类型的指针

使用场景:函数参数或函数返回值

注意:通过 void 类型指针进行取内容,需要对地址进行强转
强转方式:void* p = NULL; 强转 (int *)p 取内容: *((int *)p)

大小端

在计算机进行超过1字节数据进行存储的时候,会出现存储数据顺序不同的情况即大小端存储

Big-Endian(大端字节序)大端:在低地址存放高字节数据,高地址存放低字节数据
Little-Endian(小端字节序)小端:在低地址存放低字节数据,高地址存放高字节数据

举例:存储数据 0x12345678,起始地址 0x4000

0x4000 0x4001 0x4002 0x4003

大端:0x12 34 56 78
小端:0x78 56 34 12
Day12 C基础(指针进阶)_第1张图片

查看电脑是大端还是小端,代码如下:

int a = 0x12345678;
char b;
b = (char)a;
printf(“%#x\n”, b);

// 电脑是小端,网络是大端
// 电脑向网络传输东西,数据要从小端变成大端,传出去
// 网络向电脑传输东西,数据要从大端转成小端,接收过来

二级指针

一级指针:存放变量地址
二级指针:存放的是一级指针的地址

格式: 存储类型 数据类型 **指针变量名

int num = 10;
int *p = #
int **q = &p;

访问 num 的值:
num *p **q

访问 num 的地址:
&num p *q

访问 p 的地址:
&p q

指针和数组

直接访问:按变量的地址存取变量的值(通过数组名访问)
间接访问:通过存放变量地址的变量去访问变量(通过指针访问)

1.指针和一维数组

int a[5] = {1, 2, 3, 4, 5};
int *p = arr;

直接访问:

Day12 C基础(指针进阶)_第2张图片

 int a[5] = {1, 2, 3, 4, 5};
    int *p = a;
    printf("%p %p %p\n", a, a+1, a+3);  // 直接访问元素的地址
    printf("%d %d\n", a[1], *(a+1));

间接访问:

Day12 C基础(指针进阶)_第3张图片

 int a[5] = {1, 2, 3, 4, 5};
    int *p = a;
    
    printf("%p %p %p\n", a, a+1, a+2);
    printf("%p %p %p\n", p, p+1, p+2);
    printf("%d %d %d\n", *p, *(p+1), *(p+2));
    printf("%d %d %d\n", p[0], p[1], p[2]);

a 和 p 本质上不同,a地址常量, p是变量,a不能执行 ++ 操作,但是 p 可以

访问数组元素a[i]的值:
直接访问:a[i] *(a+i)
间接访问:p[i] *(p+i)

访问数组元素a[i]的地址:
直接访问:&a[i] a+i
间接访问:&p[i] p+i

int a[3] = {3, 2, 1};
int *p = a;
printf(“%d\n”, *p++); // 3 在打印一次的话就是 2
printf(“%d\n”, *a++); // 错误,a地址常量

运算方法:
1)++ 和 * 都是单目运算符,优先级相同
2)单目运算符从右向左进行运算

int a[3] = {3, 2, 1};
int *p = a;
printf(“%d\n”, 下列打印);
*(p++) // 3 实际上指针指向到了第二个元素的地址
(*p)++ // 打印出来是 3,实际上第一个元素值变成 4
++*p // 打印出来 4,自加完之后的值
++(*p) // 同上
*++p; // 2,先将指针向高地址方向移动一个数据单位,然后取地址内容
*(++p); // 同上

2.指针和二维数组

int a[2][3] = {1, 2, 3, 4, 5, 6}; // a:数组名:表示第一行的首地址,a+1:第二行首地址

在a前面加*,表示将行地址降级为列地址
*a+0:第一行第一列的地址
*a+1:第一行第二列的地址
*(a+1):第二行第一列的地址
*(a+1)+1:第二行第二列的地址

a[0]:第一行第一列的地址
a[0]+1:第一行第二列的地址
a[1]:第二行第一列的地址
a[1]+1:第二行第二列的地址

直接访问:

Day12 C基础(指针进阶)_第4张图片

间接访问:

同上

数组指针

定义:本质是指针,指向的是数组(又称行指针)
格式:存储类型 数据类型 (*指针变量名)[列数];

int a[2][3] = {1, 2, 3, 4, 5, 6};
int (*p)[3] = a;

p:int (*)[3]; 运算三个三个运算
p可以代替a进行元素访问,但是本质不同

访问 a[i][j] 的地址:
*(p+i)+j &p[i][j] p[i]+j

访问a[i][j]的元素
((p+i)+j) *(p[i]+j) p[i][j]

大小
sizeof§ == 4

你可能感兴趣的:(华清远见培训,c语言)