博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS学习07之C语言指针
阅读量:6333 次
发布时间:2019-06-22

本文共 3986 字,大约阅读时间需要 13 分钟。

本次随笔主要是为了学习和理解C语言中的指针,指针树状图如下:

1、访问数据的两种方式

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

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

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

图解

2、指针

 1> 定义指针变量

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

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

 1       int *p = NULL;                                    

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

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

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

 2> 赋值(地址)

  取址运算符: &

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

 3> 取值

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

  取值运算符:*

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

 4> 存储空间

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

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

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

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

 5> 区分指针中 * 的作用

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

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

 6> 指针的运算

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

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

  第一种: p + n

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

   p 的地址没有发生变化

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

   第二种: p - n

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

   p 的地址没有发生变化

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

      

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

   p 的指向发生改变

1         int *p = NULL;2         int a = 10;3         p = &a;4         printf("%p\n", p);5         p++;6         printf("%p\n", p);

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

   p 的指向发生改变

1         int *p = NULL;2         int a = 10;3         p = &a;4         printf("%p\n", p);5         p--;6         printf("%p\n", p)

 3、指针与数组

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

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

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

 下标法

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

   

指针法

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

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

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

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

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

  第3行代码会报错

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

图解

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

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

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

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

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

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

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

  运行结果:

    

 

图解

      

 4、指针与字符串

1     char str[] = "shangtian"; 2     char *p = str; 3      4     printf("%s\n", str); 5     printf("%s\n", p); 6      7     *p = 'S'; 8     printf("%s\n", p); 9     10     char *q = "xiadi"; // 常量字符串11     printf("%s\n", q);12     13     *q = 'X'; // 运行会出现内存崩溃现象,14     printf("%s\n", q);

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

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

 

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

5、指针数组

  存放指针元素的数组

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

图解

6、指针与函数

1 // 指针与函数 2 void changeValue(int *a, int *b) { 3     int temp = *a; 4     *a = *b; 5     *b = temp; 6 } 7  8 void printArray(int *p, int count) { 9     for (int i = 0; i < count; i++) {10         printf("%d\n", p[i]);11     }12 }13 14 int main(int argc, const char * argv[]) {15     16     // 指针与函数17     int a = 10;18     int b = 20;19     20     printf("a = %d, b = %d\n", a, b);21     22     changeValue(&a, &b);23     24     printf("a = %d, b = %d\n", a, b);25     26     // 指针表示数组27     int arr[4] = {
2, 4, 3, 7};28 29 printArray(arr, 4);

图解

 

转载于:https://www.cnblogs.com/gfxxbk/p/5276120.html

你可能感兴趣的文章
ios ios7 取消控制拉升
查看>>
182在屏幕中实现网格化视图效果
查看>>
本文摘录 - FlumeJava
查看>>
Scala学习(三)----数组相关操作
查看>>
Matlab基于学习------------------函数微分学
查看>>
Dundas 系列
查看>>
Windows的命令行查看,修改,删除,添加环境变量
查看>>
iOS 图文混排
查看>>
64. Minimum Path Sum
查看>>
Windows Live Writer 使用指南
查看>>
分析iOS Crash文件,使用命令符号化iOS Crash文件
查看>>
R学习笔记 第五篇:字符串操作
查看>>
在Mac OS下配置PHP开发环境
查看>>
(转)介绍下Nuget在传统Asp.net项目中的使用
查看>>
C# ArcEngine 实现点击要素高亮并弹出其属性
查看>>
初识GO语言——安装Go语言
查看>>
SDK命令行操作
查看>>
基于Bootstrap的DropDownList的JQuery组件的完善版
查看>>
EXTJS学习系列提高篇:第二十四篇(转载)作者殷良胜,ext2.2打造全新功能grid系列--阅增删改篇...
查看>>
Hadoop MapReduce编程 API入门系列之分区和合并(十四)
查看>>