(三)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,一个int4字节     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个元素的值:71个元素的值为:32个元素的值为:43个元素的值为:54个元素的值为:65个元素的值为: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释放内存,使用灵活,但是容易造成问题。
堆和栈的区别
  1. 申请方式
    • 栈:有系统自动分配,如声明一个局部变量int b,在调用函数时需要保持变量,如递归调用,要系统自动分配一个栈空间,后进先出。
    • 堆:需要自己申请,并指明大小
  2. 申请后的系统响应
    • 栈:只要神域空间大于所申请的空间,系统将为程序提供,否则报异常提示栈溢出。
    • 堆:首选应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,
      寻找第一个空间大于申请空间的堆节点,然后将该节点从空闲节点链表中删除,并将该节点的空间分配给程序。
      另外,对于大多数系统,会在这块内存空间中的首地址记录本次分配的大小,这样,代码中的delete语句才能正确释放本内存空间。
      另外,由于找到的堆节点大小不一定正好等于申请的大小,系统会自动将多余的那部分重新放入空闲链表中。
  3. 申请大小的限制
    • 栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存区域。意思是栈顶的地址和栈的最大容量是系统预先规定好的。在WINDOWS下,栈的大小默认是2M。
    • 堆:堆是向搞地质扩展的数据结构,是不连续的内存区域,空间比较灵活,也比较大。
  4. 申请效率
    • 栈:系统自动分配,速度较快,单程序员无法控制。
    • 堆:malloc/new分配的内存,一般速度比较慢,而且容易产生内存碎片,但是用起来方便。
  5. 存储内容
    • 栈:在函数调用时,第一进栈的是主函数后的下一条指令的地址,然后是函数的个个参数,在大多数c编译器中,参数是由右往左入栈的,然后是函数的局部变量。注意静态变量不入栈。
    • 堆:一般在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。
  6. 内存回收
    • 栈:编译器自动回收
    • 堆: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
原创粉丝点击