c提高第四课
1、一维数组的初始化
int a[] = { , , }; //3个元素
int b[] = { , , }; //a[3], a[4]自动初始化为0
int c[] = { }; //全部元素初始化为0
memset(c, , sizeof(c)); //通过memset给数组每个元素赋值为0
2、数组类型
int a[] = { , , }; //3个元素
a: 数组首行首元素地址,一级指针
&a: 整个数组的首地址,二级指针
首行首元素地址和首行(整个一维数组)地址值虽然是一样,但是它们的步长不一样
a+: 跳过1元素,一元素为4字节,步长4个字节
&a+: 跳过整个数组,整个数组长度为 * = ,步长 * = sizeof(a): 传参为:数组首行首元素地址,测数组(int [])的长度, * =
sizeof(a[]): 传参为:数组首元素(不是地址),每个元素为int类, 4字节
sizeof(&a):传参为:一维数组整个数组的地址(首行地址),编译器当做指针类型,4字节
(重要)首行地址 --> 首行首元素地址(加*)
&a:首行地址
*&a -> a : 首行首元素地址
//数组也是一种数据类型,类型本质:固定大小内存块别名
//由元素类型和内存大小(元素个数)共同决定 int a[5] int[5]
//可以通过typedef定义数组类型
//有typedef:类型
//没有typedef:变量
typedef int ARRARY[5]; //定义了一个名字为ARRARY的数组类型,[5]表示步长
//等价于typedef int (ARRARY)[5];
//根据数组类型,定义变量
//ARRARY的位置替代为d,去掉typedef,int d[5]
ARRARY d; //相当于int d[5];
3、数组指针变量(它是指针变量,指向数组的指针)
//定义数组变量
int a[]; //有typedef:类型
//没有typedef:变量
1、根据数组类型,定义指针变量,数组指针变量
typedef int ARRARY[]; //定义了一个名字为ARRARY的数组类型
//等价于typedef int (ARRARY)[10]; ARRARY *p; //数组指针变量 //编译会有警告,但不会出错,因为 a 和 &a的值一样
//就算p = a这样赋值,编译器内部也会自动转换为 p = &a
//不建议这么做
p = a; //p 指向a数组,指向一维数组的指针
p = &a; //如何操作数组指针变量 p
int i = ;
for (i = ; i < ; i++)
{
(*p)[i] = i + ;
//p = &a
//*p -> *(&a) -> a
//(*p)[i] -> a[i]
}
2、直接定义数组指针变量(常用)
//()[]同级,从左往右看
//()有*,它是一个指针,[]代表数组
//指向数组的指针变量,[]中的数字代表指针+1的步长
int(*p)[10];
//p 指向a数组,指向一维数组的指针
p = &a;
3、先定义数组指针类型,再根据类型定义指针变量(常用)
//数组指针类型,加上typedef
typedef int(*Q)[10];
Q p; //根据类型定义变量,p是数组指针变量
p = &a; //p指向数组a
4、多维数组本质
1)二维数组初始化
int a1[][] = {
{, , , },
{, , , },
{, , , }
}; int a2[][] = { , , , , , , , , , , , }; int a3[][] = { , , , , , , , , , , , };
2)内存中并不存在多维数组,多维数组在内存中都是线性存储
int a[][] = { };
int *b = (int *)a;//转换成一维
int i = ;
for(i = ; i < ; i++){
printf("%d ", b[i]);
}
3)多维数组名
//学会类比
int b[5] = {0};
b: 首行首元素地址, +1,跳 4 个字节
&b:首行地址,+1,跳 4*5 = 20个字节
//二维数组实际上就是 N 个一维数组
//把二维数组第一个[]的值看做标志位,0 -> 2
//第0个一维数组a[5] -> 第2个一维数组a[5]
int a[3][5] = { 0 };
a:
二维数组首元素地址
代表首行地址,相当于一维数组整个数组的地址,相当于上面的 &b,本来就是一个二级指针
//(重要)首行地址 --> 首行首元素地址(加*)
*a:首行首元素地址,相当于一维数组首元素地址,相当于上面的 b
a + i -> &a[i]: 第i行地址
//(重要)某行地址 --> 某行首元素地址(加*)
*(a+i) -> *&a[i] -> a[i]: 第i行首元素地址
//第i行j列元素的地址,某行首元素地址 + 偏移量
*(a+i)+j -> a[i]+j -> &a[i][j]: 第i行j列元素的地址
//第i行j列元素的值,第i行j列元素的地址的基础上(加 *)
*(*(a+i)+j) -> a[i][j]: 第i行j列元素的值
int a[][] = { };
sizeof(a): 二维数组整个数组长度, * * = 60 //只要是数组名就是测整个数组长度
sizeof(a[]):a[]为第0行首元素地址,相当于测第0行一维数组的长度: * =
sizeof(a[][]):a[][]为第0第0列元素(是元素,不是地址),测某个元素长度:4字节
4)多维数组名,实际上是一个数组指针,指向数组的指针,步长为一行字节长度
int a[3][5] = { 0 };
//定义一个数组指针类型的变量
int(*p)[5];
//编译会有警告,但不会出错,因为 a 和 &a的值一样
//但是&a代表整个二维数组的首地址
//就算p = &a这样赋值,编译器内部也会自动转换为 p = a
//不建议这么做
p = &a;
//a 本来就是第0个一维数组整个数组的地址,所以,无需加&
p = a;
5)二维数组做形参的三种形式
//一维数组做函数参数退化为一级指针
//二维数组(多维数组)做函数参数,退化为数组指针
int a[3][5] = { 0 };
void print_array1(int a[3][5]);
//第一维的数组,可以不写
//第二维必须写,代表步长,确定指针+1的步长 5*4
void print_array2(int a[][5])
//形参为数组指针变量,[]的数字代表步长
void print_array3(int (*a)[5]);
//a+1和二维数组的步长不一样
//这里的步长为4
//上面二维数组的步长为 5 * 4 = 20
void print_array3(int **a); //err
5、指针数组(它是数组,每个元素都是指针)
1)指针数组的定义
//指针数组变量
//[]优先级比*高,它是数组,每个元素都是指针(char *)
char *str[] = { "111", "2222222" };
char **str = { "111", "2222222" }; //err
2)指针数组做形参
void fun(char *str[]);
void fun(char **str); //str[] -> *str
3)main函数的指针数组
//argc: 传参数的个数(包含可执行程序)
//argv:指针数组,指向输入的参数
int main(int argc, char *argv[]); : demo.exe a b test
int argc =
char *argv[] = {"demo.exe", "a", "b", "test"}
笔记
===================================================================================
1、
typedef int A[10];//A:数组类型
A b;//int b[10],数组类型变量,普通变量
A *p;//数组类型定义数组指针变量
typedef int (*p)[10];//数组指针类型
P p;//数组指针变量
int (*q)[10];//数组指针变量
2、
int a[][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
//a: 代表第0行首地址
//a+i :代表第i行首地址
//*(a+i) -> a[i]: 代表第i行首元素地址
//*(a+i)+j -> &a[i][j] :代表第i行第j列元素地址
//*(*(a+i)+j) ->a[i][j] =第i行第j列元素的值
二维数组数组名:第0行首地址
a+i:第i行首地址
要想把首地址转化首元素地址,加*:*(a+i)
要想得到某个元素地址,加偏移量: *(a+i)+0, *(a+i)+1, *(a+i)+j
->&a[i][0] &a[i]+1 &a[i][j]
要想得到某元素的值,是这个元素的地址基础上加*
*(*(a+i)+j) -> *&a[i][j] ->a[i][j]
int (*q)[10];//数组指针变量
c提高第四课的更多相关文章
- c提高第四次作业
1. 简述指针数组和数组指针的区别?答: 指针数组:是一个数组,每个元素都是指针 数组指针:是一个指针,指向数组的指针 2. 如何定义一个指向 int a[10] 类型的指针变量(数组指针)(使用3种 ...
- Kali Linux Web 渗透测试视频教程— 第四课 google hack 实战
Kali Linux Web 渗透测试— 第四课 google hack 实战 文/玄魂 目录 shellKali Linux Web 渗透测试— 第四课 google hack 实战 课程目录 Go ...
- Kali Linux Web 渗透测试视频教程—第十四课-arp欺骗、嗅探、dns欺骗、session劫持
Kali Linux Web 渗透测试视频教程—第十四课-arp欺骗.嗅探.dns欺骗.session劫持 文/玄魂 目录 Kali Linux Web 渗透测试—第十四课-arp欺骗.嗅探.dns欺 ...
- NeHe OpenGL教程 第四十四课:3D光晕
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- NeHe OpenGL教程 第三十四课:地形
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- NeHe OpenGL教程 第二十四课:扩展
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- NeHe OpenGL教程 第十四课:图形字体
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- NeHe OpenGL教程 第四课:旋转
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- 【C语言探险】 第四课的第二部分:串
内容简单介绍 1.课程大纲 2.第二部分第四课: 字符串 3.第二部分第五课预告: 预处理 课程大纲 我们的课程分为四大部分,每个部分结束后都会有练习题,并会发布答案.还会带大家用C语言编写三个游戏. ...
随机推荐
- 简简单单的Vue3(插件开发,路由系统,状态管理)
既然选择了远方,便只顾风雨兼程 __ HANS许 系列:零基础搭建前后端分离项目 系列:零基础搭建前后端分离项目 插件 路由(vue-router) 状态管理模式(Vuex) 那在上篇文章,我们讲了, ...
- 【学习笔记】分布式Tensorflow
目录 分布式原理 单机多卡 多机多卡(分布式) 分布式的架构 节点之间的关系 分布式的模式 数据并行 同步更新和异步更新 分布式API 分布式案例 Tensorflow的一个特色就是分布式计算.分布式 ...
- 设计模式系列13:模板方法模式(Template Method Pattern)
定义 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. --<设计模式GoF> UML类图 使用场景 有 ...
- Java 工厂模式(一)— 工厂方法(Factory Method)模式
一.工厂方法(Factory Method)模式: 1.什么是工厂方法模式? 工厂方法模式是类的创建型模式,又叫做虚拟构造子模式或者多态工厂模式.它的意义是创建产品对象的工厂接口,将实际创建工作推迟到 ...
- es6 字符串的扩展和数值的扩展
es6字符串的扩展 1. es6新增的一些方法 1.1 includes 判断是否包括在内,返回一个 true or false 1.2 statsWith 判断是否以什么开头,返回一个 true o ...
- CSS3 弹性盒子
理解: CSS3 弹性盒( Flexible Box 或 flexbox),是一种当页面需要适应不同的屏幕大小以及设备类型时确保元素拥有恰当的行为的布局方式. 设置弹性盒子: 弹性盒子由弹性容器(Fl ...
- Android为TV端助力 使用shared注意事项
不要存放大的key和value!我就不重复三遍了,会引起界面卡.频繁GC.占用内存等等,好自为之! 毫不相关的配置项就不要丢在一起了!文件越大读取越慢,不知不觉就被猪队友给坑了:蓝后,放进defalu ...
- Unity 协同程序
定义协同程序: IEnumerator test() { Debug.log("test 1"); yeild return WaitForSecond(3.0f); Debug. ...
- MySQL 关于性能的参数配置梳理
以下List是我们常见的MySQL参数配置,这个参数对提高实例的性能大有裨益. 其中 建议设置值,仅供参考,需要根据自己的业务场景和硬件资源仔细推敲. 参数 设置说明 建议设置值 lower_case ...
- vue框架构建项目流程
构建项目流程: 1.全局查询:node -v 2.全局初始化:npm install --global vue-cli 3.模块化工程:vue init webpack myapp--->y,n ...