文章目录
一、指针和数组
1.什么是指针:
- 指针就是个变量,用来存放地址,地址唯一标识一块内存空间。
- 指针的大小是固定的4/8个字节(32位平台/64位平台)。
- 指针是有类型,指针的类型决定了指针的±整数的步长,指针解引用操作的时候的权限。
2.什么是指针数组?什么是数组指针?什么是函数指针?
int* p[] //指针数组
int(*p)[] //数组指针
void(*p)(int x,int y) //函数指针
3.程序的结果是什么?(含答案)
1.
int main()
{
int a[5] = {
1, 2, 3, 4, 5 };
int *ptr = (int *)(&a + 1);
printf( "%d,%d", *(a + 1), *(ptr - 1));
return 0;
}
(a + 1)等同于a[1],第一个是4,a的类型是int [5],&a的类型就是int()[5],是个数组指针。所以给int(*)[5]类型加一,相当于加了一个int [5]的长度。也就是这个指针直接跳过了a全部的元素,直接指在了刚好越界的位置上,然后转换成了int *后再减一,相当于从那个位置向前走了一个int,从刚好越觉得位置回到了1的地址处,所以第二个是1。
答:4,1
2.
struct Test
{
int Num;
char *pcName;
short sDate;
char cha[2];
short sBa[4];
}*p;
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
int main()
{
printf("%p\n", p + 0x1);
printf("%p\n", (unsigned long)p + 0x1);
printf("%p\n", (unsigned int*)p + 0x1);
return 0; }
第一行:20的16进制是14,14+0 = 14
第二行:强转long,1+0 = 1
第三行:强转指针:4/8+0 = 4/8
3.
int main()
{
int a[4] = {
1, 2, 3, 4 };
int *ptr1 = (int *)(&a + 1);
int *ptr2 = (int *)((int)a + 1);
printf( "%x,%x", ptr1[-1], *ptr2);
return 0; }
答:4,2
.
4.
#include <stdio.h>
int main()
{
int a[3][2] = {
(0, 1), (2, 3), (4, 5) };
int *p;
p = a[0];
printf( "%d", p[0]);
return 0;
}
逗号表达式,只存右边第一个数,其余补0,所以输出1
5.
int main()
{
int aa[2][5] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int* ptr1 = (int*)(&aa + 1);
int* ptr2 = (int*)(*(aa + 1));
printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));
return 0;
}
1的地址+整个数组的地址-1 ->10的地址:10
aa+1 指向二维数组第二行第一个6,输出:10,5
6.
int main()
{
char *a[] = {
"work","at","alibaba"};
char**pa = a;
pa++;
printf("%s\n", *pa);
return 0; }
pa++后指向“at”
7.
int main()
{
const char* c[] = {
"ENTER","NEW","POINT","FIRST" };
const char** cp[] = {
c + 3,c + 2,c + 1,c };//逆置"FIRST","POINT","NEW","ENTER"
const char*** cpp = cp;
printf("%s\n", **++cpp);//"POINT"
printf("%s\n", *-- * ++cpp + 3);//"ENTER" 从第三个开始er
printf("%s\n", *cpp[-2] + 3);//"FIRST" 从第三个开始 st
printf("%s\n", cpp[-1][-1] + 1);//"NEW" 从第一个开始EW
return 0;
}
二、结构体
结构是一些值的集合,这些值称为成员变量
。结构的每个成员可以是不同类型的变量。
如:
struct Stu
{
char name[20];//名字
int age;//年龄
char sex[5];//性别
char id[20];//学号
};
1.结构体、联合、枚举体他们之间区别
联合也是一种特殊的自定义类型,这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体)。
联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)
联合体内存取最大值并对齐
。
2.内存对齐
内存对齐的规则+如何计算
按最大的内存对齐,小的放在一起,不够的补齐。
eg1:
struct S1
{
char c1;//2
int i;//4
char c2;//2
};
printf("%d\n", sizeof(struct S1));
第一行、第三行:2补齐为4,所以输出12
.
eg2:
struct S2
{
char c1;
char c2;
int i;
};
printf("%d\n", sizeof(struct S2));
一二行凑够4,所以输出8
结构体嵌套
struct S3
{
double d;
char c;
int i;
};
printf("%d\n", sizeof(struct S3));
struct S4
{
char c1;
struct S3 s3;
double d;
};
printf("%d\n", sizeof(struct S4);
)
struct s3是16,此时s4嵌套了s3,但是依旧是以s3 的double d为准对齐
,所以char c1;补齐为8,struct S3 s3;,2*8 = 16,double d为8 。答案是32
.
为什么要对齐:
如果不对齐的话,一个变量就会被分到2个(或多个)内存空间。
性能原因:为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
三、库函数
1.常见的库函数的功能及使用
2.模拟实现常见库函数
四、关键字
1.const
2.static
五、其他
1.什么是大小端?如何判断大小端?
2.malloc和calloc和realloc的区别
malloc:向内存申请一块连续可用的空间,并返回指向这块空间的指针。
calloc:会在返回地址之前把申请的空间的每个字节初始化为全0。
realloc:对动态开辟内存大小的调整。(增大或缩小)