程序片段(01):01.指针数组.c+02.动态数组.c

内容概要:指针数组

///01.指针数组.c
#include <stdio.h>
#include <stdlib.h> //01.指针数组作为函数的形参:
// 会退化为一个二级指针!
//02.如何确定一个数组作为函数形参将会退化为什么样儿的指针?
// 关键在于形参数组当中的元素是什么类型!就是什么类型的指针
void show01(char * str[5])//char *str[5]
{
for (int i = 0; i < 5; ++i)
{
printf("%s \n", str[i]);//char **str
}
} //03.等价关系:
// 二级指针和指针数组的数组名所对应的解析方式都一样!
void show02(char ** str)
{//指针数组作为函数的形参进行传参的时候,指针数组的数组名将会退化为一个二级指针!
for (int i = 0; i < 5; ++i)
{
printf("%s \n", str[i]);
}
} //04.函数形参的拦截机制:
// 如果是数组,就没有副本机制,不是副本,就有拦截介质
//注:解除数组的副本机制依赖于数组名的退化机制!
//05.如何确定一个变量的数据类型?
// 在定义变量的基础情况之下,挖掉变量名,就是变量的数据类型
//注:字符指针数组开发过程当中比较常用!
int main01(void)
{
int * arr[10];//-->int * [10]-->一级指针数组类型!
//一级指针数组的数组名arr在作为函数形参的时候,该一级指针的数组名会自动退化以为一个二级指针
char * str[5] = { "calc", "notepad", "tasklist", "mspaint", "pause" };
//char * [N]:字符指针类型的一级指针数组在开发过程当中经常使用!
char **pp = str;//变量指针=常量指针(地址意义的数组赋值动作!)-->指针变量结果-->指针变量遍历!
printf("%p \n", str);//二级指针常量的数值
//show01(str); <= = > show02(str); system("pause");
}
///02.动态数组.c
#include <stdio.h>
#include <stdlib.h> //01.如何确定动态数组的数组名称?
// 1.开辟内存的时候所采用的指针变量名称就是动态数组名称!
// 2.通过指针变量名称的访问方式就如同标准数组的访问方式!
// 注:严格区分变量指针和常量指针之间的差别!
int main02(void)
{
//动态分配一个一维数组
int * const arr = malloc(30 * sizeof(int));
for (int i = 0; i < 30; ++i)
{
printf("%d \n", arr[i] = i);//arr[i]<=>*(arr+i)
} system("pause");
} //02.动态数组的分配要点:
// 1.动态内存开辟函数!
// 2.解析动态内存的指针类型!
// 注:所有数组都看做为一维数组!,指向该数组首元素的指针
// 指针可以使用:变量指针和常量指针(模拟栈内存数组!)
// 注:动态数组的尺寸在程序运行过程当中决定!
// 每个当前维度的数组都必须要求明确其维度-1的特点
int main03(void)
{
//动态分配一个二维数组
//int test = 5;
int(*p)[5] = malloc(30 * sizeof(int));
for (int i = 0, num = 0; i < 30; ++i, ++num)
{
printf("%3d", p[i / 5][i % 5] = num);//0->1->2->3...
if (0 == (i + 1) % 5)
putchar('\n');
} system("pause");
} //03.两种区别的数组:
// 二维数组:数组当中的每个相邻数组元素的内存地址必须连续
// (连续!+对齐!)
// 分块数组:针对于同一个数组当中的每个数组元素的内存地址必须连续
// 但是内部就整体而言的数组元素之间是可以不连续的
// (不连续+不对齐!)
// 注:动态内存开辟函数的返回值类型为("void *")类型,只是负责返回一个有效
// 地址,但是没有具备解析意义+堆内存动态开辟函数前面的赋值号只是用于
// 返回一个明确的地址而已!-->指针类型决定对动态内存的实际解析意义!
int main04(void)
{
//使用malloc函数在堆内存当中开辟一个指针数组!
int **pp = malloc(5 * sizeof(int *));//20个堆内存字节
int num = 0;
for (int i = 0; i < 5; ++i)
{
pp[i] = (int *)malloc((5 + i)*sizeof(int));
for (int j = 0; j < 5 + i; ++j)
{
pp[i][j] = num++;//赋值
}
}
for (int i = 0; i < 5; ++i)
{
for (int j = 0; j < 5 + i; ++j)
{
printf("%3d", pp[i][j]);
}
printf("\n");
} system("pause");
} //04.常见数据结构的特点:
// 数组:查找效率高+增加|删除效率低
// 链表:增加|删除效率高+查找效率低
// 分块:查找效率和数组一样+增加|删除效率比数组高(略低于链表,不过可以忽略!)
// 可以不用连续,可以不用对齐!
//05.如何分配一个N-1级指针数组?
// 需要一个N级的指针!
// N级指针,存储N-1级指针数组的地址
// N级指针分配一个数组,用于存放N-1级指针数组的首个元素的地址(区分变量指针|常量指针)
// 数据等同于0级指针

程序片段(02):01.Array.c

内容概要:数组的三种形态

#include <stdio.h>
#include <stdlib.h> //01.C语言版本标准:
// 第一版:C89
// 第二版:C99
//02.(VC2013以上+GCC4.7以上)支持C99语法
// VC2013+GCC4.7
//03.C99新语法分配数组模式!
// 1.位于栈内存的静态数组
// 2.可以进行指明初始化!
// 指明初始化的最大索引可以推导数组总元素个数
// 3.指明初始化方式的特点:可以明确长度!
// 纯大括号初始化:只能同时指明数组长度,并且给数组最后一个元素初始化赋值
// 其余数组元素统统采用默认初始化方式!
// 非纯大括号初始化:可以同时指明数组长度,并且给多个数组元素初始化赋值
// 其余数组元素统统采用默认初始化方式!
int main01(void)
{
int arr[] = { [10] = 10 };//默认不操作的数组元素被赋值为0,[10]-->arr[10]=0->11个元素
for (int i = 0; i < 11; ++i)
{
printf("%d \n", arr[i]);
} system("pause");
} int main02(void)
{
int n = 4;
int * pC99 = (int[]) { [2] = 1, [4] = 10 };//静态数组
//默认不指明初始化的数组元素所对应的值为0
for (int i = 0; i < 5; ++i)
{
printf("%d \n", pC99[i]);
} system("pause");
} //04.静态数组与动态数组:
// 静态数组:
// 1.存储于栈内存
// 2.编译时期决定数组元素个数
// 3.(自动开辟+自动回收)
// 动态数组:
// 1.存储于堆内存
// 2.运行时期决定数组元素个数
// 3.(手动开辟+手动释放)
// 注:严格区分(分配+释放)以及(开辟+回收)的区别
// 分配+释放:权限
// 开辟+回收:内存
void run()
{
//int arr[5] = { 1, 2, 3, 4, 5 };
int * p = malloc(10 * sizeof(int));
for (int i = 0; i < 10; ++i)
{
p[i] = i;//p[i]-->*(p+i)
}
free(p);
//基于C99语法的静态数组:处于栈内存当中,自动开辟回收,用于解决心脏起搏器问题!
//int * pC99 = (int []){ [4] = 10 };
//printf("%p \n", pc99);
printf("\n");
} int main03(void)
{
run();
printf("\n\n\n");//加速内存的回收动作!+防止Release模式!优化操作
run();
printf("\n\n\n"); system("pause");
} //05.指针变量可以指向任何内存地址:
// 无论是栈内存,堆内存,全局区,代码区
int main04(void)
{
int num = 30;
//int * pC99 = (int[30]) { 0 };
//pC99 = (int[10]) {0};//pC99是int*类型
//pc99 = 1;
int * pC99 = (int [30]) { [2] = 1, [4] = 10 };//静态数组
for (int i = 0; i < 30; ++i)
{
printf("%d \n", pC99[i]);
} system("pause");
} //06.区分静态分配和动态分配区别:
// int num=30;//静态分配:必须在编译时期,决定静态数组的元素个数
// int a[num];//栈上的静态分配-->可变长度的数组只有在GCC编译器当中实现,VC编译器当中不能进行实现
// 注:VC不支持位于栈内存的静态数组+GCC支持位于栈内存的静态数组!

程序片段(03):01.内存.c

内容概要:四大分配堆内存的函数

#include <stdio.h>
#include <stdlib.h> //01.内存四大分配函数:
// malloc<->calloc:
// malloc:内存不清零(参数:内存字节数)
// calloc:内存清零(参数1:数组元素个数+参数2:单个元素尺寸)
// realloc<->_recalloc:
// realloc:内存不清零(参数1:内存首地址,总内存字节数)
// 1.如果原始内存地址足够拓展,就在原始内存地址进行拓展
// 2.如果原始内存地址不够拓展,就在新地址内存进行拓展:
// 拷贝原始内存地址所对应的有效数据+回收原始内存地址数据
// 3.拓展之后的内存如果没有数据进行覆盖,就不回执行内存清零操作!
// _recalloc:内存清零(参数1:内存首地址+参数2:数组元素个数+参数3:单个元素尺寸)
// 1.如果原始内存地址足够拓展,就在原始内存地址进行拓展
// 2.如果原始内存地址不够拓展,就在新地址内存进行拓展
// 拷贝原始内存地址所对应的有效数据+回收原始内存地址数据
// 3.拓展之后的内存如果没有进行手动初始化,系统将会执行自动初始化操作!
int main01(void)
{
//int * p = (int *)malloc(100);//malloc不会初始化参数,参数是整体所占用的内存尺寸(字节数)!
int * p = calloc(25, sizeof(int));//calloc存在初始化参数,参数解释:第一个参数是元素个数,第二个参数是元素内存尺寸
printf("%p \n", p);
//for (int i = 0; i < 25; ++i)
//{
// p[i] = i;
//} system("pause");
} int main02(void)
{
int * p = malloc(10 * sizeof(int));//指针能够操作这片儿堆内存!
//int * p_p = malloc(100);
for (int i = 0; i < 10; ++i)
{
printf("%d \n", p[i] = i);
}
printf("p = %p \n", p); int * px = realloc(p, 200);//拓展内存,内存不清零
//返回值是内存首地址,说明拓展成功,后续地址拓展,拓展不成功,重新开辟内存
//原来的内存就被回收了
printf("px = %p \n", px);
for (int i = 0; i < 50; ++i)
{
px[i] = i;
printf("%d \n", px[i]);
}
//p[120387] = 10; system("pause");
} int main03(void)
{
int * p = calloc(25, sizeof(int));//会初始化为0,参数:数组元素个数+内存字节大小
//scanf("123");
printf("%p \n", p);
for (int i = 0; i < 25; ++i)
{
p[i] = i;
}
p = _recalloc(p , 50, sizeof(int));//内存清零操作
for (int i = 25; i < 50; ++i)
{
p[i] = i;
}
system("pause");
}

程序片段(04):main.c

内容概要:GccArray

#include <stdio.h>
#include <stdlib.h> //01.VC不支持栈内存动态数组,GCC支持栈内存动态数组!
int main()
{
int num=30;
int a[num];//栈上的动态分配
//int *pc99 = (int[30]){0}; //printf("Hello world!\n");
return 0;
}

20160211.CCPP体系详解(0021天)的更多相关文章

  1. 20160129.CCPP体系详解(0008天)

    程序片段(01):函数.c+call.c+测试.cpp 内容概要:函数 ///函数.c #include <stdio.h> #include <stdlib.h> //01. ...

  2. 20160226.CCPP体系详解(0036天)

    程序片段(01):01.多线程.c+02.多线程操作.c 内容概要:多线程 ///01.多线程.c #include <stdio.h> #include <stdlib.h> ...

  3. 20160208.CCPP体系详解(0018天)

    程序片段(01):main.c 内容概要:PointWithOutInit #include <stdio.h> #include <stdlib.h> //01.野指针详解: ...

  4. 20160206.CCPP体系详解(0016天)

    代码片段(01):.指针.c+02.间接赋值.c 内容概要:内存 ///01.指针 #include <stdio.h> #include <stdlib.h> //01.取地 ...

  5. 20160205.CCPP体系详解(0015天)

    程序片段(01):01.杨辉三角.c 内容概要:杨辉三角 #include <stdio.h> #include <stdlib.h> #define N 10 //01.杨辉 ...

  6. 20160204.CCPP体系详解(0014天)

    程序片段(01):define.h+data.h&data.c+control.h&control.c+view.h&view.c+AI.h&AI.c+main.c 内 ...

  7. 20160203.CCPP体系详解(0013天)

    程序片段(01):数组.c+02.数组初始化语法.c 内容概要:数组 ///01.数组.c #include <stdio.h> #include <stdlib.h> //0 ...

  8. 20160128.CCPP体系详解(0007天)

    以下内容有所摘取,进行了某些整理和补充 论浮点数的存储原理:float浮点数与double浮点数的二进制存储原理–>阶码 浮点数转二进制 1.整数int类型和浮点数float类型都是占用4个字节 ...

  9. 20160127.CCPP体系详解(0006天)

    程序片段(01):msg.c 内容概要:线程概念 #include <stdio.h> #include <stdlib.h> #include <Windows.h&g ...

随机推荐

  1. JS面向对象特性和值类型与复合类型

      JS面向对象之特性已经值类型与复合类型 一些属性 空对象 空对象也是对象, 只是有存变量的变量名, 没有对象属性 var o ={}; 参数传递 值类型: 函数内外两个变量, 两个数据, 都不相同 ...

  2. spring boot / cloud (九) 使用rabbitmq消息中间件

    spring boot / cloud (九) 使用rabbitmq消息中间件 前言 rabbitmq介绍: RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统.它可以用于大型软件系统 ...

  3. Java内存回收机制.md

    1.java的内存 java的内存结构分为 堆 (是gc的主要区域) 线程共享,主要是用于分配实例对象和数组 栈 线程私有,它的生命周期和线程相同,又分成 虚拟机栈和本地方法栈,只有它会报 Stack ...

  4. 深入浅出理解 TCP/IP 协议 (一)

    文章转自:https://www.cnblogs.com/onepixel/p/7092302.html TCP/IP 协议栈是一系列网络协议的总和,是构成网络通信的核心骨架,它定义了电子设备如何连入 ...

  5. phantomjs 开发爬虫框架

    函数 page.childframescount page.childframesname page.close page.currentframename page.deletelater page ...

  6. [LeetCode] Max Chunks To Make Sorted II 可排序的最大块数之二

    This question is the same as "Max Chunks to Make Sorted" except the integers of the given ...

  7. Fetching data with Ajax小例子

    ajax获取数据示例: 示例1 通过ajax获取txt文件里面的内容示例: <html> <head> <title>Ajax at work</title& ...

  8. NOIP 2015运输计划

    题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n-1 条航道连通了 L 国的所有星球. 小 P 掌管一家 ...

  9. hdu 4638 树状数组 区间内连续区间的个数(尽可能长)

    Group Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Subm ...

  10. hdu 5493 (树状数组)

    题意:在一个队列中,你知道一个人在他左边或者右边比他高的人的个数,求字典序最小的答案 思路:先将人按  矮-->高 排序,然后算出在每个人前面需要预留的位置.树状数组(也可以线段树)解决时,先二 ...