您的位置:首页 > 编程语言 > C语言/C++

iOSDay07之C语言指针

2016-03-14 20:58 323 查看
本次随笔主要是为了学习和理解C语言中的指针,指针树状图如下:



1、访问数据的两种方式

 1> 直接访问:定义变量后,直接访问变量

int a = 10;
printf("a = %d\n", a);


 2> 间接访问:先找到地址,根据地址访问变量的存储单元

图解



2、指针

 1> 定义指针变量

  类型修饰符 *指针变量名 = NULL;

  NULL 表示空指针,相当于0,用来给指针变量赋初始值

      int *p = NULL;

  p的类型: int *, p指向整数类型

  通常情况下,把指针变量称为指针

  p是指针,存储的内容是地址

 2> 赋值(地址)

  取址运算符: &

  int *p = NULL;
  int a = 10;
  p = &a;
  printf("p存放的地址是:%p\n", p);
  printf("变量a存放的地址是:%p\n", &a);


 3> 取值

  通过指针变量读取存储空间的数据

  取值运算符:*

  int *p = NULL;
  int a = 10;
  p = &a;
  printf("指针p指向的数据是:%d\n", *p);


 4> 存储空间

  指针的存储空间与操作系统有关

   32位的操作系统,指针的存储空间占4个字节

   64位的操作系统,指针的存储空间占8个字节

  int *p = NULL;
  int a = 10;
  p = &a;
  printf("指针所占的位数:%lu\n", sizeof(p));


 5> 区分指针中 * 的作用

  定义指针变量时,int *p = NULL; 这个 * 用来描述 p 是一个指针变量

  取值的时候, *p; 这个 * 是取值运算符

 6> 指针的运算

  指针只有加减运算,没有乘除运算

  定义指针类型,决定了指针在运算时偏移几个字节

  第一种: p + n

   从 p 指向的存储空间开始,向高位偏移n个数据类型的字节数

   p 的地址没有发生变化

    int *p = NULL;
    int a = 10;
    p = &a;
    printf("%p\n", p);
    printf("%p\n", p + 1);




   第二种: p - n

   从 p 指向的存储空间开始,向低位偏移n个数据类型的字节数

   p 的地址没有发生变化

    int *p = NULL;
    int a = 10;
    p = &a;
    printf("%p\n", p);
    printf("%p\n", p - 1);


      


  第三种: p++ (p = p + 1)

   p 的指向发生改变

    int *p = NULL;
    int a = 10;
    p = &a;
    printf("%p\n", p);
    p++;
    printf("%p\n", p);




  

  第四种: p-- (p = p - 1)

   p 的指向发生改变

    int *p = NULL;
    int a = 10;
    p = &a;
    printf("%p\n", p);
    p--;
    printf("%p\n", p)




3、指针与数组

int arr[] = {1,3,5,7,9};
int *p = NULL;
p = arr;


 数组名是数组元素的首地址,故第3行的代码不能加 &

 1> 通过指针访问数组元素

 下标法

for (int i = 0; i < sizeof(arr) / sizeof(int); i++) {
printf("arr[%d] = %d\n", i, p[i]);
}


   


 

 指针法

  通过指针偏移计算数组中的元素

  不修改指针指向:* (指针变量(数组名) + 下标)

        for (int i = 0; i < sizeof(arr) / sizeof(int); i++) {
        printf("指针变量\t + 下标\t: arr[%d] = %d\n", i, *(p + i));
        printf("数组名\t + 下标\t: arr[%d] = %d\n", i, *(arr + i));
        }



  

  

  修改指针指向:*(指针变量++)

        for (int i = 0; i < sizeof(arr) / sizeof(int); i++) {
      printf("指针变量\t + 下标\t: arr[%d] = %d\n", i, *(p++));
      //printf("数组名\t + 下标\t: arr[%d] = %d\n", i, *(arr++)); // arr是数组的首地址,它是一个常量,故必能改变
        }


  第3行代码会报错



   

  因为指针可以重定向,但是数组名是常量首地址,不可以修改

图解





 

 2> 指针变量和数组的区别

  1. 指针可以重定向,但是数组名是常量首地址,不可以修改

  2. 不能通过指针计算数组元素的个数

   指针的存储空间:4 或 8 个字节

   数组的存储空间 = 元素个数 * 每个元素所占的字节数

 3> 指针的类型一定要和数组元素的类型相匹配

short arr[4] = {3, 7, 9, 1};
int *p = arr;
char *q = arr;
printf("%d\n", p[0]);
printf("%d\n", q[0]);


  运行结果:

    


图解

      







4、指针与字符串

char str[] = "shangtian";
char *p = str;

printf("%s\n", str);
printf("%s\n", p);

*p = 'S';
printf("%s\n", p);

char *q = "xiadi"; // 常量字符串
printf("%s\n", q);

*q = 'X'; // 运行会出现内存崩溃现象,
printf("%s\n", q);


 第13行代码在运行时,会出现内存崩溃现象



 因为 q 指向的是一个常量字符串,常量字符串不能进行修改



 

  

  总结:指向常量的指针可以读取和修改数组元素,指向常量字符串的指针,只能读取,不能修改

5、指针数组

 存放指针元素的数组

char *strArray[3] = {"iPhone", "iPad", "iWatch"};// 指针数组:存放指针元素的数组
for (int i = 0; i < 3; i++) {
printf("%s\n", strArray[i]);
}
for (int i = 0; i < 3; i++) {
printf("%p\n", strArray[i]);
}


图解



6、指针与函数

// 指针与函数
void changeValue(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}

void printArray(int *p, int count) {
for (int i = 0; i < count; i++) {
printf("%d\n", p[i]);
}
}

int main(int argc, const char * argv[]) {

// 指针与函数
int a = 10;
int b = 20;

printf("a = %d, b = %d\n", a, b);

changeValue(&a, &b);

printf("a = %d, b = %d\n", a, b);

// 指针表示数组
int arr[4] = {2, 4, 3, 7};

printArray(arr, 4);


图解



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: