指针的深入
来源:互联网 发布:初中编程学哪个 编辑:程序博客网 时间:2024/06/05 14:12
指针2
* 开课小练习*
int num = 300;char *p1 = #*p1 = 100;
请问 num的值是多少?
答案: 300的二级制补码是:// 00000000 00000000 00000001 0010 1100char *p1 :编译器会警告 p1 存储了num的地址*p1 = 100: 二进制补码 ://00000000 00000000 00000001 0110 0100所以char类型 只会读取一个字节的空间 *p1 改变了第一个字节的补码 其他字节没有变化 所以输出后是 353
- 不管什么类型的指针,都是占用8个字节
- 分类型:
- 指针的类型如果不和指向的变量的类型相同的话,那么通过指针就无法确定操作指针的变量
- 通过指针操作变量时, 指针变量的类型决定了要操作多少个连续字节的空间
多级指针
一级指针:
首先是一个指针, 存储了一个普通变量的地址
int num = 10;
itn *p_num = #
二级指针:
首先是一个指针,存储了一个一级指针的地址
int num = 10;
itn *p_num = #
int** pp_num = &p_num;
- n级指针的使用
int num = 10;int *p_num = #// 一级int **pp_num = &p_num;// 二级int ***ppp_num = $pp_num; // 三级/*打印num的值%d用来输出num%d用来输出*p_num%d用来输出**pp_num%d用来输出***ppp_num*/
指针与整数之间的加减法
- 我们可以声明1 个指针变量指向数组的元素, 通过指针间接的操作数组的元素
- 数组名 就是一个地址, 他保存了数组的首地址,也就是数组第0个元素的地址
int arr[] = {10,20,30,40,50,60,70};int *p1 = &arr[0];int *p2 = arr;
遍历数组的三种方式
指针 + 1 ==>指针的值(地址) + sizrof (所有指向元素的数据类型)
int*类型的指针 0xffff001 + 1 实际上===> 0xfff005
使用指针遍历数组的第一种方式
int arr[7] = {10,20,30,40,50,60,70};int *p1 = &arr;for(int i = 0; i < 7; i++){printf("%d",*(p1+i));}
- 使用指针遍历数组的第二种方式
int arr[7] = {10,20,30,40,50,60,70};int *p1 = &arr;for(int i = 0; i < 7; i++){printf("%d",*(arr+i));}
- 使用指针遍历数组的第三种方式
int arr[7] = {10,20,30,40,50,60,70};int *p1 = &arr;for(int i = 0; i < 7; i++){printf("%d",*(p1++));}
使用指针遍历数组的元素的注意点
- 数组名不能给他重新复制
- 因为 数组名是一个地址, 这个地址是在定义数组的时候系统分配的
- 也就是说 数组一旦定义,那么他的地址就是固定的(常量)
- 所以不能对数组名进行重新复制
- 指针变量+1的本质
- 指针变量的值+ sizeof(指针应该指向的数据的类型)
- 指向的int类型就是地址加 4
- 指针-1:
- 指针-1 同等指针加1
数组作为函数参数的本质 中括弧的本质
- 如果我们为函数写了一个数组作为参数,其实 编译器在编译的时候, 已经把这个数组换成了指针
- 指针变量后面可以使用中括弧,在中括弧中写下标来访问数据
p1[n],前提是p1必须是一个指针
p1[n]<===> **(p1+n);式子*(p1+1) 表明
- 其实 *的后面还可以是一个结果为指针的表达式
- 只要这个表达式有一个地址值 就可以了
存储指针的数组
- 存储指针的数组: 简称 指针的数组(数组指针)
- 声明格式:
数据类型 *数组名[长度];int num1 = 10;int num2 = 100;int num3 = 1000;//定义一个数组 存储了三个变量int arr[] = {num1,num2,num3};//定义一个数组 存储了三个变量的地址int *p_arr[] = {&num1,&num2,&num3};//或者int *p_arr1[] = {arr,arr+1,arr+2};// 要访问 num1的值printf("num1 = %d\n",num1);printf("num1 = %d\n",arr[0]);printf("num1 = %d\n",*p_arr[0]);
* 指针与指针之间的减法运算*
* 指针相减的意义:
* 代表两个指针指向的变量之间相差多少个单位变量.
* 指针相减的前提 : 这两个指针 必须指向相同的一个数组中的元素
* 公式
* 指针1 - 指针2====> (指针1的值-指针2的值)/sizeof(指针类型)
* 两个指针之间只能做减法
* 指针与指针之间的比较运算*
* 他可以判断两个指针指向的变量的地址 , 谁在高字节 谁在低字节
* 可以判断使用 ==、!=、来判断两个指针指向的地址是不是为同一个地址
* 注意:
* 系统为变量分配地址的时候 是从高字节向低字节分配的
* 变量内部 存储的时候 是从低字节 ===> 高字节
存储字符串数据的两种方式
* C语言中的字符串如何存取
* 使用字符数组:
“`
char name[] = “jack”;
三个长度:
字符串可见长度: 4
字符串实际长度: 5
数组长度: 5
```
- 注意
char namr[] = {‘j’,’a’,’c’,’k’};
不能用%s输出。 因为 从指定的位置开始到‘\0’结束 - 使用字符指针
char ch = 'a';
char *p_ch = &ch;
char *p_nam = 'jack';
// 一定要明确:这里并不是把家新款赋值给 p_name
存储的“jack”这个字符串的首字母的地址
了解内存的5大区域
- 不同的区域使用来干什么的?为什么区分?
- 每一个区域都是用来存储数据的
- 不同区域存储数据 ,方便系统管理
- 内存中的五大区域
- 栈
- 用来存储 局部变量
- 堆
- 程序员手动申请内存的存储空间
- BSS段
- 未初始化的 全局变量 静态变量
- 常量区
- 已经初始化的 全局变量 静态变量 和常量
- 代码段
- 存储代码指令 (二进制)
- 栈
字符串存储的两种方式
* 当他们都是局部变量的时候
* char name1[] = “jack”;
* name1 存储在栈中,”jack“的每一个字符存在字符数组中,也就是栈去
* char *name2 = “rose”;
* name2 存储在栈中,但是rose是存在常量区
* 当他们作为全局变量的时候
* char1[] = “jack”;
* name1存储在存储在常量区 ,jack每一个字符都存储在数组中,也就是常量区
* char *name2 = “rose”;
* name2存储在常量区,”rose“也是常量区。name2这个指针 指向了rose这个字符串的首字母的地址
二者的区别
char name1[] = "jack"; name1[0] = 'u'; // 可以改 char *name2 = "rose"; name2[0] = 'r'; // 不允许,因为“rose“是一个常量
字符串的恒定性
- 以字符指针形式存储字符串
- 在常量区中 只有一份相同的字符串
- 难点
- 第一个
char *name = "jack"'
name[0] = 'U';// 这里不更改,想把字符串的额第一个字母改成U是不行的,
//因为字符串是一个常量 不能修改
name = "rose"; //这里改的不是jack这个字符串,而是在 name中存储地址,name本来只想的是jack的字符地址,现在只想了 rose - 第二个
char name[] = "jack";
name[0] = 'U'; //这个可以更改
name = "rose";
//这么更改也不行, 因为name是一个数组名存储的是一个地址常量 所以不能更改
- 第一个
字符串数组
- 字符串数组: 一个数组,每一个元素是一个字符串
如何存储字符串数组
二维的字符串数组
char name[] = "jack";char[][20] = {"jack","rose","lily","dianli"};
一维指针数组
char *name[4] = {"jack","rose","lily","dianli"};数组长度:sizeof(数组名) / sizeof(char*);
* 字符串数组的排序*
char * countries[] = { "Nepal", "Cambodia", "Afghanistan", "China", "Singapore", "Bangladesh", "India", }// 冒泡排序:for(int i = 0; i < len -1; i++){ for(int j = 0; j < len -1 -i, j++) { // 引入 string.h 头文件 int rel = strcmp(countries[j],countries[j+1]); if(len > 0) { //交换两个变量的 } }}//选择排序for(int i = 0 ; i < len -1; i++){ for(int j = i +1 ; j < len;j++) { int rel = strcmp(countries[i],countries[j]) if(rel > 0) { //交换的时候 char *temp =countries[i]; countries[i] = countries[j]; countries[j] = temp; } }}
- 深入理解指针的指针
- 指针的深入
- 深入理解指针以及二级指针(指针的指针)
- 指针的深入理解,深刻掌握指针
- 深入讨论指针的兼容性问题
- 指针数组的深入探讨
- 深入理解 [指针函数] 、[函数指针]、[指针的指针]、[指向指针数组的指针]
- 深入指针
- 深入指针
- 指针深入
- 深入理解C语言指针的奥秘- -- -
- 深入理解C语言指针的奥秘
- 深入理解C语言指针的奥秘
- 深入理解c语言指针的奥秘
- 深入理解C语言指针的奥秘
- 深入理解C指针的奥妙(转)
- 深入理解C语言指针的奥秘
- 深入理解C语言指针的奥秘
- 数组的应用深入
- POJ 1655 Balancing Act(简单树型dp)
- POJ2728 Desert King 最优比例生成树
- 指针的简单应用
- android2.6.1——知晓当前活动
- 指针的深入
- 结构体初识
- Java JDBC 之 PreparedStatement
- C#中的异常捕获机制(try catch finally)
- H2 DataBase简单使用
- 组合_____Game( hdu 5725 2016多校第一场)
- 大数据IMF传奇行动绝密课程第29课:Master HA彻底解密
- linux中apache和mysqld加入service系统服务中
- 结构体 枚举 typedef 应用