iOSDay07之C语言指针
2016-03-14 20:58
323 查看
本次随笔主要是为了学习和理解C语言中的指针,指针树状图如下:
p的类型: int *, p指向整数类型
通常情况下,把指针变量称为指针
p是指针,存储的内容是地址
取值运算符:*
32位的操作系统,指针的存储空间占4个字节
64位的操作系统,指针的存储空间占8个字节
取值的时候, *p; 这个 * 是取值运算符
定义指针类型,决定了指针在运算时偏移几个字节
第一种: p + n
从 p 指向的存储空间开始,向高位偏移n个数据类型的字节数
p 的地址没有发生变化
第二种: p - n
从 p 指向的存储空间开始,向低位偏移n个数据类型的字节数
p 的地址没有发生变化
第三种: p++ (p = p + 1)
p 的指向发生改变
第四种: p-- (p = p - 1)
p 的指向发生改变
数组名是数组元素的首地址,故第3行的代码不能加 &
不修改指针指向:* (指针变量(数组名) + 下标)
修改指针指向:*(指针变量++)
第3行代码会报错
因为指针可以重定向,但是数组名是常量首地址,不可以修改
图解
2> 指针变量和数组的区别
1. 指针可以重定向,但是数组名是常量首地址,不可以修改
2. 不能通过指针计算数组元素的个数
指针的存储空间:4 或 8 个字节
数组的存储空间 = 元素个数 * 每个元素所占的字节数
运行结果:
图解
第13行代码在运行时,会出现内存崩溃现象
因为 q 指向的是一个常量字符串,常量字符串不能进行修改
总结:指向常量的指针可以读取和修改数组元素,指向常量字符串的指针,只能读取,不能修改
图解
图解
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);
图解
相关文章推荐
- C++11 现代C++风格的新元素--简介
- c++第二次实验
- c++析构函数为什么要为虚函数
- C++中关键字explicit的作用
- C++用模板实现顺序表和栈
- 八皇后 c++
- 广度优先搜索和深度优先搜索—N皇后问题
- C++中 容易忽视的const 修饰符
- 在什么情况下把析构函数定义为私有的?
- leetcode笔记:House Robber III
- c++第1次实验
- 从一个例子看现代C++的威力
- 关于k小的实现及优化(c)
- c++ 智能指针
- [C/C++]_[判断程序是32位还是64位]
- C++第一次实验上机-4
- C++第一次实验上机-3
- CRT (C RunTime)执行流程
- C++中string类详解
- [C++] 强制类型转换static_cast、dynamic_cast、reinterpret_cast和const_cast