指针
//指针强化
//指针:指针变量,是一种数据类型,占内存空间,用来报存内存地址
//不管几级指针(int* int**),指向什么类型数据(char* int*)-->都只占4字节
void test03()
{
char* p = NULL;
//1.使用指针之前,最好先判空
if (p != NULL)
{
strcpy(p, "hello");
}
}
野指针
//野指针:指向一个已经删除的对象 or 没有申请访问权限的内存 的指针
//1.指针变量没有初始化
//2.指针指向的内存释放了,但指针没有置空
//3.访问越界
char* getSpace()
{
char* str = (char*)malloc(sizeof(char) * 100);
return str;
}
void test04()
{
//1.指针变量没有初始化
//int* p;
//printf("%p\n", p);
//int* p2 = NULL;
//*p2 = 10;
//2.指针指向的内存释放了,但指针没有置空
char* p = getSpace();
strcpy(p, "hello");
printf("%s\n", p);
/*...*/
if (p != NULL)
{
free(p);
p = NULL; //free之后,及时置为空
}
/*...*/
if (p != NULL)
{
free(p);
p = NULL;
}
//3.越界
//char str[3] = "abc";
}
指针的步长
//指针的步长:指针+1,到底加了多少字节
//取决于,指针指向数据的数据类型
void test05()
{
char* p = NULL; //加1
printf("%p\n", p);
printf("%p\n", p+1);
printf("%p\n\n", p+2);
int* p2 = NULL; //加4
printf("%p\n", p2);
printf("%p\n", p2 + 1);
printf("%p\n\n", p2 + 2);
double* p3 = NULL; //加8
printf("0x%p\n", p3);
printf("0x%p\n", p3 + 1);
printf("0x%p\n", p3 + 2);
printf("0x%p\n\n", p3 + 3);
char buf[100] = { 0 };
printf("%p\n", buf); //加1
printf("%p\n", buf + 1);
printf("%p\n\n", buf + 2);
printf("& %p\n", &buf); //加100*1
printf("& %p\n", &buf + 1);
printf("& %p\n\n", &buf + 2);
printf("before: %s\n", buf);
int a = 200;
memcpy(buf + 1, &a, sizeof(int)); //把int类型的a放入,char类型的buf
printf("after: %s\n", buf);
printf("取出来:%d\n", *((int*)(buf + 1))); //地址 buf+1, 取4字节:(int*), 解引用
}
//结构体
struct Teacher
{
int a;
char b;
char buf[64];
int d;
};
void test06()
{
Teacher t = { 10, 'a',"hello",200 };
printf("t.a = %d\n", t.a);
printf("t.b = %c\n", t.b);
printf("t.buff = %s\n", t.buf);
printf("t.d = %d\n\n", t.d);
//偏移量
printf("a offset: %d\n", offsetof(struct Teacher, a)); //0
printf("b offset: %d\n", offsetof(struct Teacher, b)); //4
printf("buf offset: %d\n", offsetof(struct Teacher, buf)); //5
printf("d offset: %d\n\n", offsetof(struct Teacher, d)); //72
//只给出结构体首地址,取出d
printf("d=%d\n", *(int*)((char*)(&t) + offsetof(struct Teacher, d)));
//不能结构体的首地址,直接加上d的偏移量 (char*)(&t)
//先将结构体转换为1字节,再加上d的偏移量 (char*)(&t) + offsetof(struct Teacher, d)
//取4字节 (int*)强制转换 (int*)((char*)(&t) + offsetof(struct Teacher, d))
//解引用
}