C语言提高笔记
标签(空格分隔): C++ C语言
day1
数组做函数参数的退回问题
数组做函数参数会退回为一个指针, 正确做法:把数组的内存首地址和数组的有效长度传给被调用函数。
实参的a 和 形参的a 的数据类型本质不一样, 形参中的数组,编译器会把它当成指针处理 只会分配四个字节。
形参写在函数上,和写在函数内是一样的,只不过是具有对外的属性而已.
数据类型本质分析
- 数据类型可理解为创建变量的模具(模子);是固定内存大小的别名;
- 数据类型的作用:编译器预算对象(变量)分配的内存空间大小
b &b
数组数据类型 (1定义一个数组类型 2定义一个数组指针 3数组类型和数组指针类型的关系) ====>压死初学者的三座大山
可以用数组的名字作为指向数组第一个元素的指针。
void main()
{
int a; //告诉c编译器分配4个字节的内存
int b[10] ; //告诉c编译器分配40个自己内存
printf("b:%d, b+1:%d, &b:%d, &b+1:%d \n", b, b+1, &b, &b+1);
printf("sizeof(b):%d \n", sizeof(b)); //40
printf("sizeof(a):%d \n ", sizeof(a)); //4
// b+1 &b+1 结果不一样 //b &b所代表的数据类型不一样
//b 代表的数组首元素的地址
//&b代表的是整个数组的地址
printf("hello....\n");
system("pause");
}
void类型
C语言规定只有相同类型的指针才可以相互赋值
void*
指针作为左值用于“接收”任意类型的指针
void*
指针作为右值赋值给其它指针时需要强制类型转换
函数也可以看成一种数据类型
变量的本质
既能读又能写的内存对象,称为变量;若一旦初始化后不能修改的对象则称为常量
本质:一段连续内存空间的别名。通过变量来申请和命名内存空间。
三要素: 名称、大小、作用域
指针是内存空间的别名。
程雪内存四区模型
- 栈区:由编译器自动分配释放,存放函数的参数值,局部变量的值等;
- 堆区:一般由程序员分配释放,若程序员不释放,程序结束时可能由操作系统回收;
- 全局区:全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域,该区域在程序结束后由操作系统释放;
- 常量区:字符串常亮和其他常量的存储位置,程序结束后由操作系统释放;
- 程序代码区:存放函数体的二进制代码。
// 全局区的理解
char *getStr1()
{
// 指针指向谁,将将谁的地址赋给地址
// 指针变量与它指向的内存空间变量不同
char *p1 = "abcdefg2"; //静态变量,全局区
return p1;
// 函数析构后,p1消失,常量"abcdefg2"不被析构
}
char *getStr2()
{
// 编译器做完词法分析、句法分析、语法分析,然后做优化,若两个常量相同,在全局区中只创建一个
char *p2 = "abcdefg2"; //静态变量,全局区
return p2;
}
void main()
{
char *p1 = NULL;
char *p2 = NULL;
p1 = getStr1();
p2 = getStr2();
//打印p1 p2 所指向内存空间的数据
printf("p1:%s , p2:%s \n", p1, p2);
//打印p1 p2 的值
printf("p1:%d , p2:%d \n", p1, p2);
printf("hello...\n");
system("pause");
return;
}
// 堆栈区的理解
//堆
char *getMem(int num)
{
char *p1 = NULL;
p1 = (char *)malloc(sizeof(char) * num);
if (p1 == NULL)
{
return NULL;
}
return p1;
// 函数结束后,p1指向的内存块不会被析构
}
//栈
//注意 return不是把内存块 64个字节给return出来,而是把内存块的首地址(内存的标号0xaa11) ,返回给 tmp
// 理解指针的关键,是内存. 没有内存哪里的指针
char *getMem2()
{
char buf[64]; //临时变量 栈区存放
strcpy(buf, "123456789");
//printf("buf:%s\n", buf);
return buf;
}
void main61()
{
char *tmp = NULL;
tmp = getMem(10);
if (tmp == NULL)
{
return ;
}
strcpy(tmp, "111222"); //向tmp做指向的内存空间中copy数据
//tmp = getMem2();
tmp = 0xaa11;
printf("hello..tmp:%s.\n", tmp);
system("pause");
return ;
}
void main()
{
int a;
int b ;
char buf[128]; //静态联邦的时候 buf所代表的内存空间的标号 就已经定义下来了
printf("&a:%d , &b: %d \n", &a, &b);
system("pause");
return ;
}
在release 和debug模式下,栈的开口方向不同,releas模式向上,debug向下,一般认为栈开口向下,不管栈开口向上还是向下,静态联邦的时候 buf所代表的内存空间的标号 就已经定义下来了。