定义

  • 如何定义指针变量 ```c / 数据类型 变量名称

数据类型:表示指针变量能够保存什么类型的变量地址;

  • : 没有任何特殊含义,仅仅为了表示这是一个指针变量 / int num = 10; int p; p = & num; //指针变量只能保存地址 //int p = # printf(“num = %d \n”,num);//num = 10 printf(“p = %p \n”, p);//p = 0x7ffeefbfef1c printf(“&num = %p \n”, &num);//&num = 0x7ffeefbfef1c printf(“p = %d \n”,p);//p = 10

//*p : 表示访问访问 p 指向的那块内存空间

  1. - `基本数据类型` 作为函数的参数是 `值传递` , 在函数中修改形参的值 `不会` 影响到外面实参的值
  2. - `数组` 作为函数的参数是 `地址传递` , 如果是 `地址传递` 在函数中修改形参的值 `会` 影响到外面实参的值
  3. <a name="31eXs"></a>
  4. ### 指针注意点
  5. - 指针只能保存地址
  6. - 同一个变量可以有多个指针指向它
  7. - 指针的指向可以修改
  8. - 不要访问野指针
  9. - 指针是什么类型,就只能访问什么类型的数据
  10. <a name="33L8t"></a>
  11. ### 指针与数组
  12. - 数组名就是数组的地址 == 数组首元素的地址
  13. ```c
  14. int ages[3] = {1, 3 , 5};
  15. printf("ages = %p\n", ages);//ages = 0x7ffeefbfef0c
  16. printf("&ages[0] = %p\n", &ages[0]);//&ages[0] = 0x7ffeefbfef0c

由于数组首元素地址即数组地址,所以定义一个指针指向数组,实际即定义一个指针指向数组的首元素,所以数组的首元素是什么类型,指向数组的指针就是什么类型

int * p1 = &ages[0];
int * p2 = ages;
printf("p1 = %p\n", p1);//p1 = 0x7ffeefbfef0c
printf("p2 = %p\n", p2);//p2 = 0x7ffeefbfef0c
  • 指针操作数组

    // 指针操作数组
    p1[2] = 90;
    // ages = {1, 3 , 90};
    
  • 通过指针 + 1 遍历数组

    • 指针+1, 并不是真实的+1, 而是+4(4个字节),
    • 指针的两个用途
      • 取值的时候, 会根据指针类型所占用的字节去取出对应字节的数据
      • 用于做加法运算, 指针+1, 其实是加上指针类型所占用的长度 , 如果当前指针类型是int, 那么+1本质上是加上4个字节
        printf("p1+0 = %d\n", *(p1 + 0));//1
        printf("p1+1 = %d\n", *(p1 + 1));//2
        printf("p1+2 = %d\n", *(p1 + 2));//90
        

指针与字符串

  • 数组保存字符串和指针保存字符串的区别
    • 数组保存的字符串,字符串是一个 变量 str 可以修改
    • 指针保存的字符串,字符串是一个 常量 str 不可修改
    • 数组保存的字符串,存储在 中;指针保存的字符串保存在 常量区
      • 存储在栈中的变量有一个特点, 当作用域结束系统会自动释放该变量
      • 存储在常量区中的值有一个特点, 不会被释放, 而且多个相同的值对应的地址相同 ```c // 保存字符串 char str[] = “wcl”; printf(“str = %s\n”, str);//wcl str[0] = ‘m’; printf(“str = %s\n”, str);//mcl //数组名就是数组的地址, 数组名保存的就是数组的第0个元素的地址,所以我们可以使用指针来保存字符串

//通过指针保存一个字符串, 其实就是保存的字符串第0个元素的地址 char * str1 = “wcl”; printf(“str1 == %p\n”,str1);//0x100003f50

// str1[1] = ‘j’;//Thread 1: EXC_BAD_ACCESS printf(“str1 = %c\n”, str1);//w printf(“str1 = %c\n”, (str1 + 1));//c printf(“str1 = %c\n”, (str1 + 2));//l

printf(“str1 + 0_p = %p\n”, &(str1));//0x100003f50 printf(“str1 + 1_p = %p\n”, &((str1 + 1)));//0x100003f51 printf(“str1 + 2_p = %p\n”, &((str1 + 2)));//0x100003f52

printf(“sizeof(str1) = %ld\n”, sizeof(str1));//1 printf(“sizeof(str1) = %ld\n”, sizeof(str1));//8

char * str2 = “wcl”; printf(“str2 == %p\n”,str2);//0x100003f50

练习:自定义方法计算字符串的长度
```c
int myStrlen(char *str) {
    int count = 0;
    while (*str != '\0') {
        printf("str_p == %p \n",str);
        /**
         str_p == 0x100003f9e
         str_p == 0x100003f9f
         str_p == 0x100003fa0
         str_p == 0x100003fa1
         str_p == 0x100003fa2
         str_p == 0x100003fa3 
         */
        str = str + 1;
        count ++ ;
    }
    /**
      \0 ascii 0 // 0代表假 1真
        while (*str++)count++;
     */
    return count;
}