指针的概念
指针的基本概念
每个变量都被存放在从某个内存地址(以字节为单位)开始的若干个字节

“指针”,也称作“指针变量”,大小为4个字节(或8个字节)的变量,
其内容代表一个内存地址。
通过指针,能够对该指针指向的内存区域进行读写。
如果把内存的每个字节都想像成宾馆的一个房间,那么内存地址相当于就
是房间号,而指针里存放的,就是房间号。
5
指针的定义
类型名 * 指针变量名;
int * p; // p 是一个指针,变量 p的类型是 int *
char * pc; // pc 是一个指针, 变量 pc 的类型是 char *
float *pf; // pf 是一个指针,变量 pf 的类型是 float *
6
指针的内容
int * p = ( int * ) 40000;
p内容:
十进制 40000
十六进制 0x9C40
二进制每个比特 0000 0000 0000 0000 1001 1100 0100 0000
p指向地址40000,地址p就是地址40000
*p 就代表地址40000开始处的若干个字节的内容
7
通过指针访问其指向的内存空间
int * p = ( int * ) 40000;
//往地址40000处起始的若干个字节的内存空间里写入 5000
*p = 5000;
//将地址40000处起始的若干字节的内容赋值给 n
int n = *p;
“若干” = sizeof(int),因为 int * p;
8
指针定义总结
T * p ; // T 可以是任何类型的名字,比如 int, double ,char 等等。
p 的类型: T *
*p 的类型: T
通过表达式 * p,可以读写从地址p开始的 sizeof(T)个字节
*p 等价于存放在地址p处的一个 T 类型的变量

  • 间接引用运算符
    sizeof(T*) 4字节(64位计算机上可能8字节)
    9
    指针的用法
    指针用法
    char ch1 = ‘A’;
    char * pc = &ch1; //使得pc指向变量ch1
    & : 取地址运算符
    &x : 变量x的地址(即指向x的指针)
    对于类型为 T 的变量 x,&x 表示变量 x 的地址(即指向x的指针)
    &x 的类型是 T *。
    11
    指针用法
    char ch1 = ‘A’;
    char * pc = &ch1; // 使得pc 指向变量ch1
  • pc = ‘B’; // 使得ch1 = ‘B’
    char ch2 = * pc; // 使得ch2 = ch1
    pc = & ch2; // 使得pc 指向变量ch2
  • pc = ‘D’; // 使得ch2 = ‘D’
    12
    指针的作用
    有了指针,就有了自由访问内存空间的手段
    不需要通过变量,就能对内存直接进行操作。通过指针,程序能访
    问的内存区域就不仅限于变量所占据的数据区域
    在C++中,用指针p指向a的地址,然后对p进行加减操作,p就能指
    向a后面或前面的内存区域,通过p也就能访问这些内存区域
    13
    指针的互相赋值
    不同类型的指针,如果不经过强制类型转换,不能直接互相赋值
    int * pn, char * pc, char c = 0x65;
    pn = pc; //类型不匹配,编译出错
    pn = & c; //类型不匹配,编译出错
    pn = (int * ) & c;
    int n = * pn; //n值不确定
  • pn = 0x12345678; //编译能过但运行可能出错
    14
    指针的运算
    指针的运算
  1. 两个同类型的指针变量,可以比较大小
    地址p1<地址p2, p1< p2 值为真。
    地址p1=地址p2, p1== p2 值为真
    地址p1>地址p2, p1 > p2 值为真
    16
    指针的运算
  2. 两个同类型的指针变量,可以相减
    两个T * 类型的指针 p1和p2
    p1 – p2 = ( 地址p1 – 地址 p2 ) / sizeof(T)
    17
    指针的运算
  3. 两个同类型的指针变量,可以相减
    两个T * 类型的指针 p1和p2
    p1 – p2 = ( 地址p1 – 地址 p2 ) / sizeof(T)
    例:int * p1, * p2;
    若 p1 指向地址 1000,p2 指向地址 600, 则
    p1 – p2 = (1000 – 600)/sizeof(int) = (1000 – 600)/4 = 100
    18
    指针的运算
    3)指针变量加减一个整数的结果是指针
    p : T * 类型的指针
    n : 整数类型的变量或常量

    p+n : T * 类型的指针,指向地址:
    地址p + n × sizeof(T)
    n+p, p-n , *(p+n), *(p-n) 含义自明
    19
    指针的运算
  4. 指针变量可以自增、自减
    T* 类型的指针p指向地址n

    p++, ++p : p指向 n + sizeof(T)
    p–, --p : p指向 n - sizeof(T)
    20
    指针的运算
    5)指针可以用下标运算符“[ ]”进行运算
    p 是一个 T * 类型的指针,
    n 是整数类型的变量或常量

    p[n] 等价于 *(p+n)
    21
    通过指针实现自由内存访问
    如何访问int型变量 a 前面的那一个字节?
    int a;
    char * p = (char * ) &a; // &a是 int *类型
    –p;
    printf("%c", * p); //可能导致运行错误
  • p = ‘A’; //可能导致运行错误
    22
    指针运算示例
#include <iostream>
using namespace std;
int main() {int * p1, * p2; int n = 4;
char * pc1, * pc2;
p1 = (int *) 100; //地址p1为100
p2 = (int *) 200; //地址p2为200
cout<< "1) " << p2 - p1 << endl;
//输出 1) 25, 因(200-100)/sizeof(int) = 100/4 = 25
pc1 = (char * ) p1; //地址pc1为100
pc2 = (char * ) p2; //地址pc2为200
cout<< "2) " << pc1 - pc2 << endl; //输出 2) -100
//输出 2) -100,因为(100-200)/sizeof(char) = -100
cout<< "3) " << (p2 + n) - p1 << endl; //输出 3) 29
int * p3 = p2 + n; // p2 + n 是一个指针,可以用它给 p3赋值
cout<< "4) " << p3 - p1 << endl; //输出 4) 29
cout<< "5) " << (pc2 - 10) - pc1 << endl; //输出 5) 90
return 0;
}

23
空指针
地址0不能访问。指向地址0的指针就是空指针
可以用“NULL”关键字对任何类型的指针进行赋值。NULL实际上
就是整数0,值为NULL的指针就是空指针:
int * pn = NULL; char * pc = NULL; int * p2 = 0;
指针可以作为条件表达式使用。如果指针的值为NULL,则相当于为
假,值不为NULL,就相当于为真
if§  if(p!=NULL) if(!p)  if( p==NULL )
24
指针作为函数参数

#include <iostream>
using namespace std;
void Swap( int *p1, int * p2)
{int tmp = *p1; // 将p1指向的变量的值,赋给tmp
*p1 = *p2; // 将p2指向的变量的值,赋给p1指向的变量
*p2 = tmp; // 将tmp 的值赋给p2指向的变量。
}
int main()
{int m = 3,n = 4;
Swap( &m, &n); //使得p1指向m,p2指向n
cout << m << " " << n << endl; //输出 4 3
return 0;
}

指针和数组
指针和数组
数组的名字是一个指针常量
指向数组的起始地址
T a[N];
 a的类型是 T *
 可以用a给一个T * 类型的指针赋值
 a是编译时其值就确定了的常量,不能够对a进行赋值
27
指针和数组
 作为函数形参时, T *p 和 T p[ ] 等价
void Func( int * p) { cout << sizeof§;}

void Func( int p[]) { cout << sizeof§;}
28
指针和数组

#include <iostream>
using namespace std;
int main() {int a[200]; int * p ;
p = a; // p指向数组a的起始地址,亦即p指向了a[0]
* p = 10; //使得a[0] = 10
*( p + 1 ) = 20; //使得 a[1] = 20
p[0] = 30; //p[i] 和 *(p+i) 是等效的,使得a[0] = 30
p[4] = 40; //使得 a[4] = 40
for( int i = 0;i < 10; ++i) //对数组a的前10个元素进行赋值
*( p + i) = i;
++p; // p指向 a[1]
cout << p[0] << endl; //输出1 p[0]等效于*p, p[0]即是a[1]
p = a + 6; // p指向a[6]
cout << * p << endl;// 输出 6
return 0;
}
//29

指针和数组

#include <iostream>
using namespace std;
void Reverse(int * p,int size) { //颠倒一个数组
for(int i = 0;i < size/2; ++i) {int tmp = p[i];
p[i]=p[size-1-i];
p[size-1-i]=tmp;
}
}
int main() {int a[5] = {1,2,3,4,5};
Reverse(a,sizeof(a)/sizeof(int));
for(int i = 0;i < 5; ++i) {cout << *(a+i) << "," ;
}
return 0;
}
// => 5,4,3,2,1, 30

北京大学C语言学习第4天相关推荐

  1. 北京大学C语言学习第6天

    结构的概念 现实需求 在现实问题中,常常需要用一组不同类型的数据来描述一个事物.比如一个 学生的学号.姓名和绩点.一个工人的姓名.性别.年龄.工资.电话- 如果编程时要用多个不同类型的变量来描述一 ...

  2. 北京大学C语言学习第三天

    字符串1 所占字节数为 字符数加1 ,结尾有个\0,字符串长度不包括 \0. 字符串3种形式: 1.双引号括起来的 2.存放于数组中的,以/0结尾 3.string对象 字符串常量: 空串(占据一个字 ...

  3. 北京大学C语言学习第8天

    STL 初步(一) STL概述 STL: (Standard Template Library) 标准模板库 包含一些常用的算法如排序查找,还有常用的数据结构如可变长数组.链表 .字典等. 使用 ...

  4. R语言学习手记 (1)

    R语言学习手记 (1) 经管的会计和财管都会学数据统计与分析R语言这门课,加上我也有点兴趣,就提前选了这门课,以下的笔记由老师上课的PPT.<R语言编程艺术>和<R语言数据科学> ...

  5. 当当网 R 语言学习资料统计分析

    当当网 R 语言学习资料统计分析 一.网络数据的抓取 二.数据清洗与保存 (一)工作目录的修改 (二)导入数据并修改列名 1. 交互式编辑器 2. names()函数 3. rename()函数 (三 ...

  6. C++语言学习(十二)——C++语言常见函数调用约定

    C++语言学习(十二)--C++语言常见函数调用约定 一.C++语言函数调用约定简介 C /C++开发中,程序编译没有问题,但链接的时候报告函数不存在,或程序编译和链接都没有错误,但只要调用库中的函数 ...

  7. 微软提出CLIPBERT:通过稀疏采样的视频语言学习

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 论文是学术研究的精华和未来发展的明灯.小白决心每天为大家带来经典或 ...

  8. c语言错误的等式,C语言学习中几个常见典型错误分析.docx

    C语言学习中几个常见典型错误分析 打开文本图片集 摘要:C语言是一门优秀,应用广泛的结构化程序设计语言,是中职计算机.机电和电子技术等专业一门理论和实践相结合的课程,教学实践中,学生常觉得c语言难学, ...

  9. 二级C语言学习宝典下载,二级C语言学习宝典

    二级C语言学习宝典app是一款专注于全国二级计算机等级C语言学习所开发的应用软件,它能够给你带来全新的功能板块,让你轻松掌握超多优质的考试训练,享受到手机端做题刷题的畅快体验,让你轻松备考,而且在该软 ...

最新文章

  1. geany配置python_Linux系统下搭建基于Geany+Python开发环境
  2. 基于深度学习的Person Re-ID(特征提取)
  3. kali 树莓派 android,【原】树莓派安装KALI LINUX的手记
  4. 为XPath自定义函数(因为XPath1.0的函数非常有限)[附源代码下载]
  5. Exception from HRESULT: 0x800A03EC
  6. python Unable to find vcvarsall.bat 错误
  7. mysql忘记root密码安装_MySql忘记root密码的解决方法
  8. python语言是 创造的_1.python简介
  9. JavaScript的DOM操作.
  10. python执行命令不阻塞_通过python 执行 nohup 不生效的解决
  11. namenode和datanode的功能分别是什么_海德堡印刷机电路板分别是什么功能
  12. 学习微积分60年有感(I)
  13. 分享110个ASP源码,有一款适合你
  14. 有关js获取屏幕宽度问题
  15. win10如何搜索计算机网络ip,win10怎样查看电脑IP地址?,看完就明白了
  16. mysql jdbc 水晶报表,水晶报表Crystal Report2008使用JDBC连接MySQL数据库-详细步骤
  17. SQL Server数据误删恢复
  18. 蓝桥杯pcf8591读和写
  19. FlyThings OS:基于Linux实现现代化人机交互体验的新嵌入式操作系统
  20. 米家和HomeKit等智能家居联动的重要性

热门文章

  1. ChunJunOceanBase联合方案首次发布:构建一体化数据集成方案
  2. 每个Java初学者都应该搞懂的六个问题
  3. 【考题·数学】矩阵游戏(数学推导)
  4. vue中改变v-html元素样式
  5. 横向扩展文件服务器,如何在 VMM 中创建横向扩展文件服务器
  6. 各种常用文件后缀名详解
  7. 网站提示HTTP503Service Unavailable的处理办法
  8. C++MYSQL:获取表结构:MYSQL_FEILD
  9. 人工智能AI学习路线01-AI概念
  10. 读取pdf图片并识别内容