指针与数组

指针:

程序中的变量实际是存储空间的别名。,通常以 *+ 变量名的形式组成。

  • 变量名: 存储参数的地址。
  • * :类似钥匙一样,作为打开存储内存的地址,并取出存储参数的值。
int i = 1;
int *p = &i;    // p---&i,   *p ----1

指针变量虽然是指向变量存储的空间地址,其本质还是变量,所以依然可以对其进行取地址,这就是后面我们所学到的双指针或多层数组。

传值调用和传址调用:

函数的参数也可为指针,如果函数内部需要修改实参,则需要指针的方式将实参以参数地址的方式传入函数。

// 传值调用
int swap(int a, int b){
    int c = a;
    a = b;
    b = c;  
}
// 上述方式只是简单的将参数值传入到了函数内部,并未修改参数所在地址的参数值,如果函数内部不需要修改实参,而是将其作为运算或逻辑判断的标志,则可用上述方法。

// 传址调用
int swap(int *a, int *b){
    int *c = *a;
    *a = *b;
    *a = *c;
}
// 上述的这种方法,是将实参的地址传入到了函数内,这种常用于对实参重新赋值

常量与指针:

前面提到的指针本质还是变量,而只要是变量就可以通过const修饰指针,将其变为常量。

const int *p;      // p指向内存空间的内容不可改变,地址可变
int const *p;      // p指向内存空间的内容不可改变,地址可变
int * const p;     // p指向内存空间不可改变,值可以改变
const int * const p;      // p指向内存空间和内容不可改变

数组:

 数组是相同类型变量的有序集合,且为连续的内存空间。

 

如何定义数组的大小与初始化:

int a[5] = {0};      // 全部参数均为0, 数组长度为5
int a[5] = {1,2};   // 数组长度为5,数组前两个值为1,2, 其他全为0
int a[] = {1,2};     // 数组长度为2

 数组名作为数组的首地址,数组的地址则通过&来获取,虽然两者的地址值相同,但是两个不同的概念。数组地址即数组的起始地址和数组长度。而数组首地址为数组第一个元素的地址以及元素的长度。

数组名可以看作常量地址,数组名不包含数组的长度信息,且只能作为右值使用。

int a[5] = {0};      // 全部参数均为0, 数组长度为5
int *p = a;
sizeof(a);              // 打印4*5 = 20字节
sizeof(p);              // 打印4字节

 指针与数组:

上面我们了解到,数组名本身是数组的首地址,所以可以看作指针。因此,数组名+1等价于指针+1(地址+类型_sizeof)<==>  a+n = a + n*sizeof(type)

指针是可以实现减法,前提是两个指针必须类型相同,且指向数组中的同一元素。减法的值为数组的下标差。

int a[5] = {0};
int *p1 = &a[0];
int *p2 = &a[3];
printf("p1-p2 = %d\n", p1-p2)   // 输出-3

 

posted @ 2023-04-05 23:55  嵌入式小白—  阅读(31)  评论(0编辑  收藏  举报