//
// main.m
// 第三周第三天
//
// Created by scjy on 15/10/28.
// Copyright (c) 2015年第三周. All rights reserved.
//
#import <Foundation/Foundation.h>
typedef struct studfent{
char name[20];
int age;
}Student;
int main(int argc,const char * argv[]) {
@autoreleasepool {
// insert code here...
NSLog(@"Hello, World!");
// C语言第十讲*****存储区划分,堆内存分配函数,其他内存分配函数,内存操作函数
// 内存区域划分:
//对于任何一块内存其实都包括五个区域(栈区,堆区,静态区,常量区,代码区)(了解:内存地址按顺序由高到低,或由大到小)
//栈内存特点:由系统分配及回收内存。 定义在函数体内分配的变量会被分配在栈区
// int a=8;//出了函数作用域就会被回收
// for (int i=1; i<5; i++) {
// }
// printf("i=%d\n",i);
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
堆区特点:(重点--动态分配内存)由用户(程序猿)申请分配和回收.假如一直开辟内存而不去回收,会导致系统内存越用越少,最终导致程序崩溃crash.假如不回收也没崩溃,当程序退出的时候,系统会自动回收
!!!!!!!!!!!!!!!!!!
静态区特点:定义在函数体外的变量,或者由static关键字修饰的变量,程序运行过程中,一直存在,直到程序退出时,由系统回收
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
常量区特点:用来存放常量的内存区域
#############################
代码区特点:把源代码转化成0101的二进制(CPU指令)序列存放在代码区
*/
//常量区.常量占用内存是只读状态,决不可被修改
// char *string ="iPhone";
// string[0]='F';
// 被static关键字修饰的变量的特点
// 1.只初始化一次
// 2。没有初始值,默认为零
// 3,只有程序退出才释放
// 4,该变量存在内存的静态区
// /堆内存分配函数:
// void *malloc(unsigned int size);
// malloc是函数名,malloc函数向系统申请分配size个连续的内存空间(size以字节为单位)
// 函数的返回值类型是void *类型
// void * 属于指针类型,不代表确切的指针类型。程序员根据需要转换成自己需要的类型
//
// int a=10;//a分配在栈内存
// printf("a=%p\n",&a);
// void *p=malloc(10);//p指向的是堆内存里边的一个地址
// //指针p里边存储的是10个字节的内存的首地址
// printf("p=%p\n",p);
//
// char *str= malloc(15);
// strcpy(str, "Lamborghini");
// printf("str=%s\n",str);
//
// free(p);
//
// char *str1=malloc(8);
// strcpy(str, "iPhone");
// for (int i=0; i<8; i++) {
// printf("str1[%d]=%c\n",i,str1[i]);
// }
//
// int *c=malloc(4);
// *c=30;
// printf("c=%d\n",c);
//
// free(c);
//
// //数组
// //malloc堆内存分配函数特点:分配指定大小的内存空间,但不会把分配的内存空间清零
// int *array=malloc(sizeof(int)*5);//等价于 int *array=malloc(4*5);
// array[0]=18;
// array[1]=21;
// array[2]=24;
// array[3]=27;
// for (int i=0; i<5; i++) {
// printf("array[%d]=%d\n",i,array[i]);
// }
// free(array);
//
// //二维数组
// int (*p1)[3]=malloc(sizeof(int)*2*3);
// for (int i=0; i<2; i++) {
// for (int j=0; j<3; j++) {
// p1[i][j]=arc4random()%(60-30+1)+30;
// printf("p1[%d][%d]=%d\n",i,j,p1[i][j]);
// }
// }
// free(p1);
//
// //字符串数组
// char (*p2)[255]=malloc(5*255);
// strcpy(p2[0],"iPhone6sPlus");
// strcpy(p2[1],"iPhone5sPlus");
// strcpy(p2[2],"iPhone4sPlus");
// strcpy(p2[3],"iPhone3sPlus");
// strcpy(p2[4],"iPhone2sPlus");
// strcpy(p2[5],"iPhone1sPlus");
//
// for (int i=0; i<6; i++) {
// printf("p2[%d]=%s\n",i,p2[i]);
// }
// free(p2);
//
// //结构体
//
// Student *p3 = malloc(sizeof(Student));
// strcpy(p3->name,"Maserati");
// p3->age = 23;
// printf("p3.name=%s\n",p3->name);
// printf("p3.name=%d\n",p3->age);
//
// free(p3);
//结构体数组
// Student *p4 = malloc(sizeof(Student)*5);
// p4[0].age=21;
// p4[1].age=20;
// p4[2].age=25;
// p4[3].age=22;
// p4[4].age=21;
// p4[0].age = 23;
// strcpy(p4[0].name, "Maserati");
// printf("p4[0].name=%s\n",p4[0].name);
// printf("p4[0].age=%d\n",p4[0].age);
//
// for (int i=0; i<5; i++) {
// printf("p4[i].age=%d\n",p4[i].age);
// }
// free(p4);
// 内存的释放
// void free(void *)
// free函数的作用是释放内存,内存释放是标记删除(不清除里边的内容):假如一部电影占了2G内存,正常理解删除电影的话应该是把这部电影清除了,也就是对应的内存空间里面的字节全部清零。但是这是一个非常庞大的工作量需要很长时间完成,但实际生活中删除一部电影几乎一秒内就完成了,其实也就是标记删除,告诉系统你这2G的空间不用,谁想用就分配给谁
// void free(void *);
//
// 有一字符串,其中包含数字 ,提取其中的数字 .要求动态分配内存保存
char *q ="st456sth5aety5524ts5";
int length = 0,i=0;
//循环找出字符串中数组个数,用来创建新的数组
while (*(q+i)!='\0') {
if (*(q+i) >= '0' && *(q+i) <= '9') {
length++;
}
i++;
}
printf("length=%d\n",length);
//length加一是为了给\0留一个位置
char *str1 =malloc(sizeof(char)*(length+1));
int j=0,k=0;
while (*(q+j)!='\0'){//循环终止条件当字符是'\0'的时候,结束循环
if (*(q+j)>='0' && *(q+j) <= '9')
{
//j数字在原来数组中的位置,初始值k=0,也就是在字符串0的位置赋值
//*(str1 + k)字符数组中第几个元素的位置
*(str1 + k)= q[j];
k++;//第一次存在了0的位置,按顺序存在字符数组中
}
j++;
}
printf("%s\n",str1);
//calloc 跟malloc不一样的地方在于,通过calloc分配的内存空间上的所有字节都会被清零
//分配n个size大小的空间
// int *array1= calloc(5,4);
// array1[0]=121;
// array1[1]=1452;
// array1[2]=1789;
// array1[3]=9882;
// printf("array1[4] = %d\n",array1[4]);
// printf("array1[3] = %d\n",array1[3]);
// printf("array1[2] = %d\n",array1[2]);
// printf("array1[1] = %d\n",array1[1]);
//书写更加明了
// Student *p5 = calloc(5,sizeof(Student));
//realloc
// void *realloc(void *p,unsigned nesSize);
// 按nesSize的长度重新分配内存
// Student * p6 = realloc(p3, sizeof(Student)*2);
//注意:不管用malloc,calloc, realloc,都需要free(释放内存)
//其他内存操作函数
//内存初始化
//void *memset(void *s,int c,size_t n);
// s是指针的首地址,从s指向的内存地址开始分配,分配n个字节大小的数据c;通常用于清除结构体或数组中的数据
// memset(array1, 0, 20);
// for (int i=0; i<5; i++) {
// printf("array1[%d]=%d\n",i,array1[i]);
// }
//函数拷贝:void *memcpy(void *dest, const void *src, size_t n);
// 从source指向的位置开始拷贝,拷贝到dest,长度位n
// Student *p8 = malloc (sizeof(Student));
// memcpy(p8,p3, (sizeof(Student));
// printf("p8.age" = %d\n,p8->age);
// printf("p8.name" = %s\n,p8->name);
// free(p3);
// free(p8);
// //自己的p8未定义
//内存比较
// int memcmp (const void *buf1, const void *buf2, unsigned int count);
// buf1和buf2是两个指针,但是比较的是两个内存地址了的ASCII码值,比较结果有三种情况,大于0,小于0,等于0;
// char *str=malloc(25);
//
// int k=0;
// strcpy(str, "532sr4544dsfsdf9j010");
//
// for (int i=0; i<25; i++) {
//
// if (str[i]>='0' &&str[i]<='9') {
// printf("%c\n",str[i]);
// k++;
//
// }
//
// }
//
// printf("k=%d\n",k);
//
// int l[11]={0};
// 内存操作函数,既可以用作堆内存,也可以用作栈内存:memset,memcpy,memcmp
// 堆内存专属函数:malloc,calloc,realloc
//
}
return 0;
}
//C语言内存操作函数汇总:http://blog.chinaunix.net/uid-20782170-id-248690.html
课后习题作业:
// 输入3个单词,动态分配内存保存单词,并在最后输出
// char (*p)[10]=malloc(sizeof(char)*3*7);
//
// strcpy(p[0], "qiao");
// strcpy(p[1], "zi");
// strcpy(p[2], "peng");
// for (int i=0; i<3; i++) {
// printf("%s\n",p[i]);
// }
// free(p);
//定义两个整型指针,分别用malloc、calloc对其分配空间保存3个元素,malloc分配的空间用memset清零,随机对数组进行赋值 随机范围1-3,赋值后用memcmp比较两个数组。如果相同打印Good!否则打印Failed...
int * p=malloc(sizeof(int)*3);
int * p1=calloc(3, 4);
memset(p, 0, 3*4);
for (int i=0; i<3; i++) {
p[i]=arc4random()%(3-1+1)+1;
p1[i]=arc4random()%(3-1+1)+1;
printf("%d",p[i]);
}printf("\n");
for (int i=0; i<3; i++) {
printf("%d",p1[i]);
}
printf("\n");
if (memcmp(p,p1,12) ==0) {
printf("Good\n");
}
else printf("Failed\n");
free(p);
free(p1);