(三)C语言基础(数组,内存分配,函数指针)
来源:互联网 发布:mac atom菜单栏不见了 编辑:程序博客网 时间:2024/04/28 16:58
六 数组
1. 数组基础
- 取数组地址:&cArray,与cArray相同,其为数组第一个元素地址
- 取数组对应索引元素的值:cArray[0] 或 *(cArray+0)(注意与 “*cArray+0” 的区别)
- 取数组对应索引元素地址:&cArray[0] 或 cArray+0
#include<stdio.h>#include<stdlib.h>/*数组:1.数组的取值2.数组的取地址(数组地址与元素地址)3.数组是一块连续的内存空间4.数组的设计 */ main(){ char cArray[] = {'H','E','L','L','O'}; int iArray[] = {2,0,1,6,5}; //取数组的值 printf("cArray[0] = %c\n",cArray[0]); //cArray[0] = H printf("iArray[0] = %d\n",iArray[0]); //iArray[0] = 1 //1.取地址 printf("&cArray = %#x\n",&cArray);//&cArray = 0x9ffe40 ,数组地址为首元素地址 //数组是一块连续的内存空间 printf("&cArray[0] = %#x\n",&cArray[0]);//&cArray[0] = 0x9ffe40,一个字母为1字节 printf("&cArray[1] = %#x\n",&cArray[1]);//&cArray[1] = 0x9ffe41 printf("&cArray[2] = %#x\n",&cArray[2]);//&cArray[2] = 0x9ffe42 printf("&cArray[3] = %#x\n",&cArray[3]);//&cArray[3] = 0x9ffe43 printf("cArray+0地址 = %#x\n",cArray+0); //cArray+0地址 = 0x9ffe40 printf("cArray+1地址 = %#x\n",cArray+1); //cArray+1地址 = 0x9ffe41 printf("cArray+2地址 = %#x\n",cArray+2); //cArray+2地址 = 0x9ffe42 printf("cArray+3地址 = %#x\n",cArray+3); //cArray+3地址 = 0x9ffe43 printf("&iArray = %#x\n",&iArray);//&iArray[0] = 0x9ffe20 printf("&iArray[0] = %#x\n",&iArray[0]);//&iArray[0] = 0x9ffe20,一个int为4字节 printf("&iArray[1] = %#x\n",&iArray[1]);//&iArray[1] = 0x9ffe24 printf("&iArray[2] = %#x\n",&iArray[2]);//&iArray[2] = 0x9ffe28 printf("&iArray[3] = %#x\n",&iArray[3]);//&iArray[3] = 0x9ffe2c //2.取值 //此种取法为取下一个字母(ASCII码?) printf("cArray = %c\n",*cArray); //cArray = H printf("cArray[0] = %c\n",*cArray+0);//cArray[0] = H printf("cArray[1] = %c\n",*cArray+1);//cArray[1] = I printf("cArray[2] = %c\n",*cArray+2);//cArray[2] = J printf("cArray[3] = %c\n",*cArray+3);//cArray[3] = K //此种取法为向下一个元素移动 printf("cArray[0] = %c\n",*(cArray+0));//cArray[0] = H printf("cArray[1] = %c\n",*(cArray+1));//cArray[1] = E printf("cArray[2] = %c\n",*(cArray+2));//cArray[2] = L printf("cArray[3] = %c\n",*(cArray+3));//cArray[3] = L printf("iArray = %d\n",*iArray); //iArray = 2 printf("iArray[0] = %d\n",*iArray+0);//iArray[0] = 2 printf("iArray[1] = %d\n",*iArray+1);//iArray[1] = 3 printf("iArray[2] = %d\n",*iArray+2);//iArray[2] = 4 printf("iArray[3] = %d\n",*iArray+3);//iArray[3] = 5 printf("iArray[0] = %d\n",*(iArray+0));//iArray[0] = 2 printf("iArray[1] = %d\n",*(iArray+1));//iArray[1] = 0 printf("iArray[2] = %d\n",*(iArray+2));//iArray[2] = 1 printf("iArray[3] = %d\n",*(iArray+3));//iArray[3] = 6 system("pause");}
2.1 例子 - 输入数组
#include<stdio.h>#include<stdlib.h>main(){ //1.用户输入数组长度 printf("请输入数组的长度:\n"); int length; scanf("%d",&length); printf("输入的长度为:%d\n",length); //2.根据长度创建数组 int aArray[length]; //3.用户输入数组的值 int i; for(i=0;i<length;i++){ printf("请输入第%d个值:\n",i+1); scanf("%d",&aArray[i]); } //4.把数组内容打印出来 for(i=0;i<length;i++){ printf("输出第%d个值:%d\n",i+1,aArray[i]); } system("pause");}
2.2 例子 - 指针的长度
#include<stdio.h>#include<stdlib.h>main(){ int* iPoint; char* cPoint; printf("iPoint的长度 = %d\n",sizeof(iPoint));//4 printf("cPoint的长度 = %d\n",sizeof(cPoint));//4 system("pause");}
3. 动态数组
- realloc函数
- malloc函数
#include<stdio.h>#include<stdlib.h>/*动态创建数组步骤:1.获取一个长度 2.根据长度分配内存空间3.数组元素依次赋值4.接收扩展长度5.根据长度重新分配内存空间6.扩展的长度赋值7.输出数组 结果: 请输入创建数组的长度:3输入数组的长度为:3请输入第1个元素的值:3请输入第2个元素的值:4请输入第3个元素的值:5请输入扩展数组的长度:2扩展数组的长度为:2请输入第4个元素的值:6请输入第5个元素的值:7第1个元素的值为:3第2个元素的值为:4第3个元素的值为:5第4个元素的值为:6第5个元素的值为:7*/ main(){ printf("请输入创建数组的长度:\n") ; //1获取一个长度 int length; scanf("%d",&length); printf("输入数组的长度为:%d\n",length) ; //2据长度分配内存空间 int* iArray = malloc(length*4); //3组元素依次赋值 int i; for(i=0;i<length;i++){ printf("请输入第%d个元素的值:\n",i+1); scanf("%d",iArray+i); } //4接收扩展长度 int length1; printf("请输入扩展数组的长度:\n") ; scanf("%d",&length1); printf("扩展数组的长度为:%d\n",length1) ; //5根据长度重新分配内存空间 iArray = realloc(iArray,(length+length1)*4); //6根据长度重新分配内存空间 for(i=length;i<length+length1;i++){ printf("请输入第%d个元素的值:\n",i+1); scanf("%d",iArray+i); } //7输出数组 for(i=0;i<length+length1;i++){ printf("第%d个元素的值为:%d\n",i+1,*(iArray+i)); } system("pause");}
七、内存分配
变量的分配
- 从静态存储区域分配
内存在程序编译的时候已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量 - 从栈上创建
执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动释放。栈内存分配效率高,但容量有限 - 从堆上分配
动态内存分配。程序在运行的湿乎乎用malloc或new申请内存,自己负责free或delete释放内存,使用灵活,但是容易造成问题。
堆和栈的区别
- 申请方式
- 栈:有系统自动分配,如声明一个局部变量int b,在调用函数时需要保持变量,如递归调用,要系统自动分配一个栈空间,后进先出。
- 堆:需要自己申请,并指明大小
- 申请后的系统响应
- 栈:只要神域空间大于所申请的空间,系统将为程序提供,否则报异常提示栈溢出。
- 堆:首选应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,
寻找第一个空间大于申请空间的堆节点,然后将该节点从空闲节点链表中删除,并将该节点的空间分配给程序。
另外,对于大多数系统,会在这块内存空间中的首地址记录本次分配的大小,这样,代码中的delete语句才能正确释放本内存空间。
另外,由于找到的堆节点大小不一定正好等于申请的大小,系统会自动将多余的那部分重新放入空闲链表中。
- 申请大小的限制
- 栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存区域。意思是栈顶的地址和栈的最大容量是系统预先规定好的。在WINDOWS下,栈的大小默认是2M。
- 堆:堆是向搞地质扩展的数据结构,是不连续的内存区域,空间比较灵活,也比较大。
- 申请效率
- 栈:系统自动分配,速度较快,单程序员无法控制。
- 堆:malloc/new分配的内存,一般速度比较慢,而且容易产生内存碎片,但是用起来方便。
- 存储内容
- 栈:在函数调用时,第一进栈的是主函数后的下一条指令的地址,然后是函数的个个参数,在大多数c编译器中,参数是由右往左入栈的,然后是函数的局部变量。注意静态变量不入栈。
- 堆:一般在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。
- 内存回收
- 栈:编译器自动回收
- 堆:free显式回收
1. 静态内存分配
1.1 说明
- 静态内存是栈分配的
1.2 实例
#include<stdio.h>#include<stdlib.h>/*静态内存分配 :静态内存是程序编译执行后系统自动分配,由系统自动释放 */void func(int** address){ int i=100; //把i对应的地址赋值给iPoint *address = &i;} main(){ int* iPoint; func(&iPoint);//一级指针的地址为二级指针 //注意到i为定义到func函数中的变量 printf("*iPoint = %d\n",*iPoint); //*iPoint = 100 //执行完成后栈中func部分被销毁,i不存在,iPoint无法指向 printf("*iPoint = %d\n",*iPoint); //*iPoint = 0 printf("*iPoint = %d\n",*iPoint); //*iPoint = 0 system("pause"); }
2. 动态内存分配
2.1 说明
- malloc()//分配
- ralloc()//重新分配,使用见动态数组
- free()//释放
2.2 实例
#include<stdio.h>#include<stdlib.h>/*动态内存分配 */void func(int** address){ int i = 100; int* temp; //malloc(int),返回内存地址 //这个内存地址,存放在堆空间,不会被系统自动回收 ,其中保存的值自然不会 temp = malloc(sizeof(int)); //将地址赋值 *temp = i; //将地址赋给二级指针的值 *address = temp; //回收堆空间变量 //free(temp); }main(){ int* iPoint; func(&iPoint);//一级指针的地址为二级指针 //注意到i为定义到func函数中的变量 printf("*iPoint = %d\n",*iPoint); //*iPoint = 100 printf("*iPoint = %d\n",*iPoint); //*iPoint = 100 printf("*iPoint = %d\n",*iPoint); //*iPoint = 100 system("pause");}
八、函数指针
1. 说明
- 定义一个带参数和返回值的函数指针,指向一个函数
2.实例
#include<stdio.h>#include<stdlib.h>/**函数指针 *///定义一个函数//1. 指针参数等于函数参数的情况:Log: result = 20int add( x,int y){ return x + y;} /*2. 指针参数多于函数参数的情况:只有函数参数个数对应的参数能传递过来 Log:result = 12 int add(int x){ return x;} *//*3. 指针参数少于函数参数个数的情况:函数参数的前指针参数个赋值正确,后面参数被赋为内存垃圾值 Log: z = 6233040 result = 6233065 int add(int x,int y,int z){ printf("z = %d ",z); return x + y + z;}*/int main(void){ //定义函数指针 //定义一个两参的函数指针 int (*quantai)(int x,int y); //函数指针赋值 //指针指向函数名 quantai = add; //使用函数指针 int result = quantai(12,13); printf("result = %d",result); return 0;}
0 0
- (三)C语言基础(数组,内存分配,函数指针)
- C语言-函数指针+动态内存分配
- 【C/C++语言基础学习】在主函数的定义的指针数组、二维数组通过三级指针在被调用函数分配内存
- C语言编程基础-16动态内存分配 二级指针做形参 函数指针
- C语言 内存分配 地址 指针 数组 参数 实例解析
- C语言 内存分配 地址 指针 数组 参数 实例解析
- C语言 内存分配 地址 指针 数组 参数 实例解析
- C语言 内存分配 地址 指针 数组 参数 实例解析
- C语言 内存分配 地址 指针 数组 参数 实例解析
- C语言 内存分配 地址 指针 数组 参数 实例解析
- C语言 内存分配 地址 指针 数组 参数 实例解析
- C语言指针学习(三) ---- 动态内存分配
- C语言基础及指针⑤动态内存分配
- c语言—指针基础(7:静态分配内存)
- C语言基础之函数、虚拟键盘的使用、数组、指针、动态申请内存、内存泄漏
- C语言基础之函数、虚拟键盘的使用、数组、指针、动态申请内存、内存泄漏
- 指针函数&内存分配 C
- C语言--指针数组--动态内存分配+结构体数组(递归指针)--day10
- 编译与链接过程详解
- Kmeans几种方法比较
- win8 解决文件夹无法访问,安装使用软件莫名报错的问题 【提升当前用户权限】
- C++实现矩阵压缩存储与(快速)转置
- 我的服务器开发之路-thinkphp和子域名的结合省略项目名
- (三)C语言基础(数组,内存分配,函数指针)
- HTML块元素与内联元素
- MSP430F149片内温度
- Ubuntu 16.04 LTS 更新源,亲测好用!
- PostgreSQL 与 SQL Server 的数据类型映射
- 操作系统ucore lab1实验报告
- 文件操作
- 手帐的需求描述
- 素数距离问题