《跟着星仔学C语言》第五章 指针与数组
05_0000 5.0 星仔为指针作序
内存的本质是什么?
小明为什么要保存一部分内存供自己使用?
什么是虚拟地址?
https://www.bilibili.com/video/BV12L4y1Y76R?p=37
05_0100 5.1 指针与地址
指针是什么?
指针是一个变量,用来告诉编译器预留多少空间给他, 和char short long long long 并没有本质区别.(这也是定义变量的本质)
指针的sizeof大小由它能访问的内存空间大小决定
你应该在指针里存放地址信息,但,实际上,你存放什么都无所谓, 只是*p可能会掉进坑里
地址是什么?
地址就是线性内存的每一个单元的编号.
指针在计算机的内存里,地址在人的脑海里.
指针的类型有什么用?
1.确定p++或者p--一次跳的格子数(由编译器完成)
2.确定*p访问的内容大小
3.和指针自身的大小没有关系
指向指针的指针?
这只是一个理解问题,只有理解了,才知道这么绕口到底说的什么玩意
代码:http://q1024.com/p/item.php?u=krc
视频:https://www.bilibili.com/video/BV12L4y1Y76R?p=38
05_0200 5.2 指针与函数参数 传参数本质
什么是传值的方式传递参数
int swap(int* px, int* py)是传值方式传递参数吗?
代码:http://q1024.com/p/item.php?u=krc
视频:https://www.bilibili.com/video/BV12L4y1Y76R?p=39
05_0201 5.2 指针与函数参数
讲解getint与getfloat
代码:http://q1024.com/p/item.php?u=krc
视频:https://www.bilibili.com/video/BV12L4y1Y76R?p=40
05_0300 5.3 指针与数组
数组与指针的区别
1.指针是一个变量, 而数组标号是一个常量
a). 指针可以用&符号取地址,而数组标号是不能用&符号
b).指针可以被赋值,而数组标号不能被赋值
2.sizeof的值不同,对于指定的编译环境,sizeof(指针)是定值, sizeof(数组)取决您, 您告诉它有多长,它就认为有多长
数组的长度
1.数组的长度取决于您, 您告诉它有多长,它就认为有多长
2.当函数参数是数组时, 数组退化成指针 (附证明)
exe的生成的过程
1.C语言预处理(比如宏替换)
2.单独编译每一个文件,生成.obj(linux下是.o)文件 (sizeof是在这个阶段计算的)
3.把所有的.obj文件link成一个exe
扩展
只要您确定访问的内存有效,数组就能越界
代码:http://q1024.com/p/item.php?u=krc
视频:https://www.bilibili.com/video/BV12L4y1Y76R?p=41
05_0400 5.4 地址算术运算
既然sizeof(char*)/sizeof(short*)/sizeof(int*)/sizeof(long long*)....的值都一样,那还要指针类型做什么?
举例:
学生* p; p++表示访问下一个学生
班级* p; p++表示访问下一个班级
年级* p; p++表示访问下一个年级
学校* p; p++表示访问下一个学校
这些操作是由编译器完成的
C语言保证, 0永远不是有效的数据地址
指针与整数之前不能直接转换,但0(NULL)是个例外
指针的运算,说直白点,就是地址值的运算,只要有道理,你怎么操作都行
内存对齐与非常有用的ptrdiff_t
用于兼容32位和64位cpu
1字节对齐的方法
方法一:
#pragma pack (n) 作用:C编译器将按照n个字节对齐。
#pragma pack () 作用:取消自定义字节对齐方式。
方法二:
#pragma pack (push,1) 作用:是指把原来对齐方式设置压栈,并设新的对齐方式设置为一个字节对齐
#pragma pack(pop) 作用:恢复对齐状态
代码:http://q1024.com/p/item.php?u=krc
视频:https://www.bilibili.com/video/BV12L4y1Y76R?p=42
05_0500 5.5 字符指针与函数
char amsg[]与char*pmsg的区别
1.amsg指向的地址位于堆栈之内
2.pmsg指向的地址位于堆栈之外
3.字符串常量可读,是否可写是未定义的
4.字符串常量可用于函数返回值,但局部变量字符串数组就不可以了(事实证明)
s与*(s+i)的效率之差
*s++与*--p的意思
用执行结果来查看其意思,如果考试需要,请记住
代码:http://q1024.com/p/item.php?u=krc
视频:https://www.bilibili.com/video/BV12L4y1Y76R?p=43
05_0600 5.6 指针数组以及指向指针的指针
指针是变量
指针在计算机的内存里,地址在人的脑海里.
何为指针: 指针是变量,使用的时候会加载到内存里,可以对其求地址
何为地址: 地址是客观存在的,学习C语言,脑海中要有地址的概念
代码:http://q1024.com/p/item.php?u=krc
视频:https://www.bilibili.com/video/BV12L4y1Y76R?p=44
05_0700 5.7 多维数组
多维数组在内存中的表现形式
定义数组的方法 变量名[行][列]
char arr[2][3] = {'a','b','c','1','2','3'}; //2表示行,3表示列
多维数组作为函数参数
f(int daytab[2][13]) //OK
f(int daytab[][13]) //OK
f(int (*daytab)[13]) //OK
int *daytab[13] //ERROR
代码:https://q1024.com/p/item.php?u=krc
视频:http://www.bilibili.com/video/BV12L4y1Y76R?p=45
05_0800 C程序内存布局
环境变量PATH举例
windows下修改环境变量: 高级系统设计->高级->环境变量
linux下修改环境变量: export PATH=/home/uxingzaicpp/tmp4del/123PATH
参数arg
C程序内存布局
代码:http://q1024.com/p/item.php?u=krc
视频:https://www.bilibili.com/video/BV12L4y1Y76R?p=46
05_0801 5.8 指针数组的初始化 5.9 指针与多维数组
5.8 指针数组的初始化
5.9 指针与多维数组
矩阵下标的计算公式: 列宽*row + col
代码:http://q1024.com/p/item.php?u=krc
视频:https://www.bilibili.com/video/BV12L4y1Y76R?p=47
05_0900 5.10 命令行参数
char **argv 与 char* argv[] 作为函数参数等价,正如char* s与char s[]一样
int main(int argc, char* argv[])
{
char* v[] =
{
"myecho.exe",
"hello,",
"world",
NULL,
};
char** q = v;
//对比q讲解argv
}
解释 *++argv (*++argv)[0] *++argv[0]
[]与操作数结合的优先级比*和++高
代码:http://q1024.com/p/item.php?u=krc
视频:https://www.bilibili.com/video/BV12L4y1Y76R?p=48
05_0901 5.10 命令行参数 - 练习
编写程序expr
编写程序tail
代码:http://q1024.com/p/item.php?u=krc
视频:https://www.bilibili.com/video/BV12L4y1Y76R?p=49
05_1000 5.11指向函数的指针
函数指针里存放的值不是函数地址,而一个跳转指令
这个跳转指令,最终会跳到函数地址
E9就是jmp:相对跳转指令
计算公式:E9后面的地址 = 目标地址 - 当前地址 - 5
从指针说起
1.定义一个指针变量,比如说int* a; 那么*a就可以改变指针a指向的地址的内容
2.定义一个函数变量,比如说func f; 那么(*f)就可以调用f指向的内容的函数, *可以省略
编写程序tail
函数指针类型和int a没什么分别
普通函数秒变函数指针类型
代码:http://q1024.com/p/item.php?u=krc
视频:https://www.bilibili.com/video/BV12L4y1Y76R?p=50
05_1001 5.11指向函数的指针 - 练习 5.12复杂声明的前5个例子
逆序排序
不区分大小写排序
指向二维数组的指针
代码:http://q1024.com/p/item.php?u=krc
视频:https://www.bilibili.com/video/BV12L4y1Y76R?p=51
本文来自博客园,作者:xingzaicpp,转载请注明原文链接:https://www.cnblogs.com/xingzaicpp/p/16663409.html