第一周
1.1数字在计算机原码的形式
详情见:https://blog.csdn.net/cai88453626/article/details/130019699
1.2 位运算
流水灯实验。
1.3 sqart 接收为double的参数
1.4 ctrl+d与EOF()的关系
1.5 标准输入scanf()和fgets(),getchar()
1.6 变量是标记内存地址,指针也是标记内存地址,那么变量和指针的区别是什么?
指针相当于一本书的目录,简洁。而指针所指向的内容是目录所对应的具体内容。
变量是具体内容。适合小的声明数据。
1.7 为什么字符数组可以在printf中直接打印,而数字数组不可以在pritnf中直接打印,需要遍历?
在用%c,%d时都能作为首地址输出第一个字母或数组元素。
但是如果换用,%s输出字符串,他就会根据给出的字符指针位置往后寻找字符,直到遇到’\0结束’。
printf 遇到 “%c” 就会在后面参数列表找 char 类型的参数,输出一个字符,而遇到 “%s” 就会在后面参数列表找 char 类型的参数,输出一个字符串。*
第二周
2.1 定义函数中的数组长度不等于原函数的数组长度为什么?sizeof(arr)不同
定义函数中的数组长度是传的地址,不会自动向后,数组作为函数的参数进行传递时 ,该数组自动退化为同类型的指针,不会再复制,节省内存空间。
2.2 数组指针和指针数组的区别
先从声明出发,本质上是因为符号的优先级不同。
int *pt = arr; 指向数组的值
数组指针的定义:指向一维数组的指针int (*arr)[5]; *先与arr结合,声明一个指向数组,数组里的元素有5个int类型
指针数组的定义: int arr[5];
首先[ ]的优先级比较高,先与arr结合;
其次表示arr数组内含5个指针;
最后int表示arr数组中的指针都指向int类型。
数组里的元素有5个指向int类型的指针。
2.3 static在修饰全局变量和局部变量分别是什么含义
static在修饰全局变量的时候,表示只用在当前文件中内部链接
static在修饰局部变量时,局部变量会进入静态空间,获得静态存储期。
2.4 malloc()函数如果没有进行释放会发生什么?怎么解决?
首先malloc()函数会申请一块内存,假设让其指向一个自动变量的指针temp。
其次,当函数结束的时候,自动变量的存储期的会消失,但是malloc()申请的内存仍然存在
最后,由于temp指针已经被销毁,所以无法访问这块内存,也不能被重复使用。当第二次调用
malloc()函数又分配了相同字节。当重复调用这个函数时,内存池会被耗尽,造成内存泄露问题(memory leak)。
解决:在函数末尾处调用free()函数可避免这类问题的发生。
2.5 对于二维数组 &arr,arr,*arr有什么区别和共同点?
不同:&arr指向二维数组整体 int[3] [4]; arr指向二维数组里的数组int[*][4]; *arr指向二维数组里的值
&arr + 1:增加48字节的空间
arr + 1 :增加16字节的空间
*arr + 1:增加4字节的空间
共同点:都能代表二维数组的首地址,是相同的。都是指向arr[0][0]
2.6 定义函数指针的意义?
可以指向某个相同类型的函数,需要哪个赋值给函数指针,然后进行调用。如果需要修改调用函数,只需要修改函数指针的赋值就可以,不需要全局改变,思想类似define 定义常量。
2.7 函数指针和指针函数的不同
函数指针是指向函数的指针变量,即本质是一个指针变量。
int (*f)(int x); /*声明一个函数指针*/
f = func; /*将func函数的首地址赋给指针f*/
指针函数是指带指针的函数,即本质上是一个函数,函数返回的是一个地址。
int *f(x,y);
第三周
3.1 auto申请的变量一定在堆上吗?free释放的空间,释放哪里的空间(堆,栈,静态内存空间,),如何判别变量在实际内存的哪里
3.2 void可以修饰的类型
形参或者指针
#include <stdio.h>
int main(void)
{
int a = 10;
int *pt = &a;
void *pointer = pt;
printf("%d\n",*((int *) pointer));
return 0;
}
3.3 常量指针和指针常量
注意const修饰谁,谁就是不可修改的常变量。(C++中表示const 修饰的值是常量)
#include <stdio.h>
int main(void)
{
int a = 10;
int b = 201;
// const int *pt = &a;
// printf("%d\n",*pt);
// // *pt = 200; //错误 表达式的左值必须是可修改的变量
// printf("%d\n",*pt);
int *const pt = &a;
// pt = &b; //错误 表达式的左值必须是可修改的变量
*pt = 200;
printf("%d\n",*pt);
return 0;
}
3.4 字节对齐
目的:以空间换时间,提高内存取数的效率。
结构体对齐规则:1、从零地址开始,当前的地址值是当前成员占用空间的整数倍
2、最终结构体占用字节数必须是结构体中占用空间最大成员占用的整数倍;
3、有效对齐值:自身对齐值和指定对齐值中小的那个值。
怎么消除字节对齐,我的空间我做主。
3.5 判断内存中的数据是采用大端存储还是小端存储的方法?
联合体
3.6 柔性数组
3.7 滚动数组
第四周
4.1为什么unsigned 只能修饰整数型变量,不能修饰浮点数?
unsigned 的意思就是把内存中的数据第一位也用来表示数据,而不用于表示符号位。而浮点数规定内存中数据的第一位必须是符号位。因此两者之间是互相矛盾的,这也就是为什么浮点数不会有unsigned类型
4.2 声明和定义
声明:向程序表明变量类型和名字,没有分配内存空间;
//结构体声明
typedef struct{
float bottom;
float height;
}Triangle_st;
//函数声明,带有{ }的就是定义,否则就是声明
extern double max(double d1,double d2);
//变量的声明,除非有extern关键字,否则都是变量的定义
extern int i; //声明
int i; //定义
定义:为变量分配内存存储空间,还可以为变量指定初始值。
定义也是声明,声明不是定义。
区别:有无分配内存空间
4.3变量占用内存空间位置
栈空间:局部变量和函数参数;
静态全局区:全局变量和静态变量,常量;
未初始化全局变量和静态变量 在.bss
初始化全局变量和静态变量 在.data
常量:.rodata;
堆空间:动态内存分配空间。
4.4数组定义的字符串和指针定义字符串的区别
数组定义的可修改,而指针定义的不可修改。
因为指针定义的字符串在静态全局区的只读文件中
4.5条件编译
防止头文件重复包含
第五周
5.1、什么时候数组名表示整个数组的大小?
5.2、了解联合体和结构体吗
5.3、如何测试以后机器是大端还是小端
5.4指针中*和&的区别
*是间接运算符,取出指针指向的内容
&是取地址符,取出指针指向的地址。