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

1、访问数据的两种方式

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

  1. int a = ;
  2. printf("a = %d\n", a);

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

图解

2、指针

 1> 定义指针变量

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

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

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

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

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

 2> 赋值(地址)

  取址运算符: &

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

 3> 取值

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

  取值运算符:*

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

 4> 存储空间

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

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

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

  1.   int *p = NULL;
  2.   int a = ;
  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 = ;
  3.     p = &a;
  4.     printf("%p\n", p);
  5.     printf("%p\n", p + );

   第二种: p - n

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

   p 的地址没有发生变化

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

      

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

   p 的指向发生改变

  1.     int *p = NULL;
  2.     int a = ;
  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 = ;
  3.     p = &a;
  4.     printf("%p\n", p);
  5.     p--;
  6.     printf("%p\n", p)

3、指针与数组

  1. int arr[] = {,,,,};
  2. int *p = NULL;
  3. p = arr;

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

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

 下标法

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

   

指针法

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

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

  1.         for (int i = ; 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 = ; 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 或 个字节

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

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

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

  运行结果:

    

图解

      

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[] = {"iPhone", "iPad", "iWatch"};// 指针数组:存放指针元素的数组
  2. for (int i = ; i < ; i++) {
  3. printf("%s\n", strArray[i]);
  4. }
  5. for (int i = ; i < ; 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 = ; 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 = ;
  18. int b = ;
  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[] = {, , , };
  28.  
  29. printArray(arr, );

图解

iOS学习07之C语言指针的更多相关文章

  1. iOS学习08之C语言内存管理

    本次主要学习和理解C语言中的内存管理 1.存储区划分 按照地址从高到低的顺序:栈区,堆区,静态区,常量区,代码区 1> 栈区:局部变量的存储区域 局部变量基本都在函数.循环.分支中定义 栈区的内 ...

  2. iOS: 学习笔记, Swift与C指针交互(译)

    Swift与C指针交互 Objective-C和C API经常需要使用指针. 在设计上, Swift数据类型可以自然的与基于指针的Cocoa API一起工作, Swift自动处理几种常用的指针参数. ...

  3. 【IOS学习】【Swift语言】

    基本语法: OS X playground 引入 import Cocoa IOS playground 引入 import UIKit 基本数据类型 let 定义常量 定义完成之后无法修改 var ...

  4. ios学习之旅---c语言函数

    1.函数的概述 C源程序是由函数组成的. 尽管在前面各章的程序中大都仅仅有一个主函数main(),但有用程序往往由多个 函数组成. 函数是C源程序的基本模块,通过对函数模块的调用实现特定的功能. C语 ...

  5. iOS 阶段学习第八天笔记(指针)

    iOS学习(C语言)知识点整理 一.指针 1)概念:存储变量的地址的一个变量. 2) 数据存储类型分析 1.text (代码段) :存储二进制的可执行代码 2.data(初始化的数据段) 存储初始化的 ...

  6. [转]C语言指针学习经验总结浅谈

    指针是C语言的难点和重点,但指针也是C语言的灵魂 . 这篇C语言指针学习经验总结主要是我入职以来学习C指针过程中的点滴记录.文档里面就不重复书上说得很清楚的概念性东西,只把一些说得不清楚或理解起来比较 ...

  7. C语言指针学习

    C语言学过好久了,对于其中的指针却没有非常明确的认识,趁着有机会来好好学习一下,总结一下学过的知识,知识来自C语言指针详解一文 一:指针的概念 指针是一个特殊的变量,里面存储的数值是内存里的一个地址. ...

  8. 李洪强iOS开发之零基础学习iOS开发】【02-C语言】01-概述

    前面已经给大家介绍了iOS开发相关的一些基础知识,其实iOS开发就是开发iPhone\iPad上的软件,而要想开发一款软件,首先要学习程序设计语言.iOS开发需要学习的主要程序设计语言有:C语言.C+ ...

  9. IOS学习笔记07---C语言函数-printf函数

    IOS学习笔记07---C语言函数-printf函数 0 7.C语言5-printf函数 ------------------------- ----------------------------- ...

随机推荐

  1. Java中常见数据结构:list与map -底层如何实现

    1:集合 2 Collection(单列集合) 3 List(有序,可重复) 4 ArrayList 5 底层数据结构是数组,查询快,增删慢 6 线程不安全,效率高 7 Vector 8 底层数据结构 ...

  2. 自己动手编译hadoop-2.5.2源码

    搭建环境:Centos x 6.5  64bit (后来:我才知道原来官网上发布的就是64位的,不过这个对我来说是个学习过程,对以后进行其他平台编译的时候有帮助!) 1.安装JDK 我这里用的是64位 ...

  3. 20145206《Java程序设计》第9周学习总结

    20145206 <Java程序设计>第9周学习总结 教材学习内容总结 第十六章 整合数据库 JDBC是用于执行SQL的解决方案,开发人员使用JDBC的标准接口,数据库厂商则对接口进行操作 ...

  4. Asp.Net - 7.AJAX

    AJAX简介 没有AJAX会怎么样?普通的ASP.Net每次执行服务端方法的时候都要刷新当前页面,比如实现显示服务器的时间.每次都要刷新面的坏处:页面刷新打断用户操作.速度慢.增加服务器的流量压力.如 ...

  5. EasyUi – 2.布局Layout + 3.登录界面

    1.页面布局 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="index.a ...

  6. SQLServer事务

    指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)由多个sql语句组成,必须作为一个整体执行这些sql语句作为一个整体一起向系统提交,要么都执行.要么都不执行 语法步骤:开始事务:BEG ...

  7. Linux下Vi/Vim使用笔记

    启动和关闭vim vi 打开 Vi/Vim 打开 Vi/Vim 并加载文件 <file> vi <file> vim编辑器的三种模式:一般模式.编辑模式和命令行模式在一般模式中 ...

  8. 【Python】 用python实现定时数据解析服务(前言)

    一.Why do it? 背景:项目里上传上来的数据都是未解析的数据,而且数据量还算挺庞大的,每天上传的数据有5kw左右,如果用数据库自带的作业来解析的话,数据库会造成严重的阻塞.因此打算把数据读到外 ...

  9. select count(*)和select count(1)哪个性能高

    select count(*).count(数字).count(字段名)在相同的条件下是没有性能差别的,一般我们在统计行数的时候都会把NULL值统计在内的,所以这样的话,最好就是使用COUNT(*) ...

  10. Android - 控件android:ems属性

    Android - 控件android:ems属性http://blog.csdn.net/caroline_wendy/article/details/41684255?utm_source=tui ...