美文网首页
C/C++第二课~指针1、数组

C/C++第二课~指针1、数组

作者: XX杰 | 来源:发表于2022-10-31 00:39 被阅读0次

指针、函数

1、指针~ 搞清楚 是 值 还是 地址

指针是一个变量,其值为 地址 (内存地址)。
声明指针或者不再使用后都要将其置为0 (NULL)
野指针 未初始化的指针
悬空指针 指针最初指向的内存已经被释放了的一种指针
指针多少个字节?指向地址,存放的是地址
地址在 32位的系统中 指针占用4字节 64位的是8字节

定义:
int *a; 正规
int* a;
int * a;
//因为 其他写法看起来有歧义
int* a,b;
使用:

&i 表示 i 的 内存地址
*p 表示 解引用: 也就是 指针p 指向 的 地址 的 值
#x 占位符输出的是 内存地址

//声明一个整型变量
int i = 10;
//将i的地址使用取地址符给p指针
int *p = &i;
//输出 0xffff 16进制地址
printf("%#x\n", &i);
printf("%#x\n", p);  // 因为p是指针,所以p和&i 的地址是一样的
printf("%#x\n", &p);
printf("%d\n", *p);     // 输出 10

2、解引用

解析并返回 内存地址中 保存的
*p 就是 解引用

    int i = 10;
    int *p = &i;
    int pv = *p;    // pv 赋值 为 10 
    printf("%d\n", i);    // 此时 i 的值还是 10
    *p = 100;      // *p 赋值 为 100
    printf("%d\n", pv);
    printf("%d\n", *p);
    printf("%d\n", i);    // p 指向的是 i 的地址,*p是对 i 的地址的值进行修改,所以 i 是 100

3、指针的运算

根据 解引用 和 指针 进行运算 判断的

int ap[] = {11,22,33,44,55};
    int *p = ap;
    // 指针指向数组,指向的是 数组的 第一个 位置
    printf("%d p指向的地址 %#x\n", *p, p);
    // 指针偏移,指向下一块地址, *p++ 是有警告的
    p++;
    printf("%d p指向的地址 %#x\n", *p, p);
    // 偏移3个位置
    p+=3;
    printf("%d p指向的地址 %#x\n", *p, p);
    p++;
    printf("%d p指向的地址 %#x\n", *p, p);
上面代码的结果:

// 此 地址 是 16 进制,
11 p指向的地址 0xe5c34510
22 p指向的地址 0xe5c34514
// 11 和 22 的地址相差 4 说明 int 是4个字节。同时也说明数组的地址是连续的
55 p指向的地址 0xe5c34520
// 下一个内存地址存放的数据并不是数组中的数据,说明指针已经指向了一块我们 未知的地址
32766 p指向的地址 0xe5c34524

数组的定义: 一块内存连续的数据。
其中 ap 代表的就是 第一个元素 所在的地址,所以指针指向数组的时候 不需要使用 & 符号。
而int num = 10; 需要使用 & 符号 来赋值给 指针(因为num指代的就是数据 10)

指针指向地址,指针运算实际上就是移动指针指向的地址位置,移动的位数取决于*指针类型*(int就是32位,4字节,long 就是8字节 64位)
    long ap[] = {11,22,33,44,55};
// 偏移的就是 8 位
    long *p = ap;   

// p[2] 也是会得到 33  也会取出数组的值 。*说明指针可以 通过下标取值*
    printf("%d p指向的地址 %#x\n", p[2], p);
// *(p+=2) 也是可以的。 同样的如果 *(p+=2) = 1234 。那么 ap 对应的 位置 的值也可以修改
printf("%d p指向的地址 %#x\n", *(p+=2), p);

4、二维数组和指针数组

int array[2][3]:二维数组 的 内存分布 跟 array[6] 差不多

int (*p)[x]: 指向 二维数组 的 指针的表示形式,其中x 表示 列 的数量 注意与 指针数组 的区别。
int *array[5]; 表示的是 指针数组 (一个数组,里面放的是 指针)
int array[2][3] = { {11,22,33},{44,55,66} };
//也可以 int array[2][3] = {  11,22,33 ,44,55,66 };
int (*a)[3] = array;
printf("%d p指向的地址 %#x\n", (*a)[0], a);
printf("%d p指向的地址 %#x\n", (*(a+1))[1], a);
// printf("%d p指向的地址 %#x\n", (*(a+=1))[1], a);
printf("%d p指向的地址 %#x\n", (*(a++))[1], a);
printf("%d p指向的地址 %#x\n", (*a)[0], a);
结果:
11 p指向的地址 0xe75ce510
55 p指向的地址 0xe75ce510
22 p指向的地址 0xe75ce51c  //说明取值之后在移动的指针位置
44 p指向的地址 0xe75ce51c
上面的代码 操作 的是 数组。 (*p) 指向的都是 行的 首地址。

a 默认指向的是第一行的数据 也就是 array[0]。所以 (a)[0] 是 11. (a)[2] = 33
(a+1) 指向的是 array[1] 的数组。所以 ((a+1))[1] 是55
((a++))[1] 是先取数组的值,在把指针移位
(
(a+=1))[1] 是 先移动指针的位置,在取值。 所以在这两个操作之后,(*a)[0] 是 44

printf("%d p指向的地址 %#x\n", *(*(a + 1) + 1), a);
printf("%d p指向的地址 %#x\n", *(*a + 1), *a + 1);
分析一下上面的代码:操作的才是整个二维数组的地址

1、a 指向的是数组的第一行的首地址,所以 (a+1) 指向的是数组的第二行的首地址
2、根据 上面描述的 解引用 ((a + 1)) ,取的是 第二行的首地址中存的数据,也就是 44
3、所以
(
(a + 1) + 1) 取的是数组第二行 第二个地址的数据,也就是 55
4、同理,a 指向的是数组的第一行的首地址,a + 1就是数组第一行的第二个数据地址

5、指针数组

int *array[3] = {&i, &i1, &i2};
比较简单了,就是数组中的每一个元素都是一个指针

相关文章

网友评论

      本文标题:C/C++第二课~指针1、数组

      本文链接:https://www.haomeiwen.com/subject/upnctdtx.html