void test02(){
int b = 1024;
printf("%o\n",b);//2000
printf("%x\n",b);//400
printf("%X\n",b);//400
printf("%8p\n",&b);//这个8位没有生效,输出的还是0x7ffe6c164f24
printf("%x\n",&b);//6c164f24
printf("%012X\n",&b);//00006C164F24
}
二、int类型数值溢出
void test01(){
int a = 0x7fffffff;
a = a+3;
printf("%d\n",a);//-2147483646
/**
0x7fffffff:0111 1111 1111 1111 1111 1111 1111 1111
+3 : 0000 0000 0000 0000 0000 0000 0000 0011
//高位溢出
1000 0000 0000 0000 0000 0000 0000 0010
1000 0000 0000 0000 0000 0000 0000 0010的原码如下:
1111 1111 1111 1111 1111 1111 1111 1101 + 1 =
1111 1111 1111 1111 1111 1111 1111 1110
首位是符号位,因此这个数值部分位7fff fffe,即这个数的十进制为-2147483646
*/
}
三、常量指针和指针常量
void test01() {
int a = 10;
const int* p = &a;
int b = 20;
p = &b;
//*p = 100;//IDE提示报错,const位于*之前表示p是指向常量的指针,所以不能通过*p修改p指向地址里面的值
int* const p1 = &a;
//p1 = &b;//IDE提示报错,*位于const之前表示p1是指针常量,所以不能修改p1指向的地址,但是可以通过*p1修改p1指向地址里面的值
printf("%d %d\n",*p,*p1);
}
四、auto、volatile、register
/*
auto关键字:https://zhuanlan.zhihu.com/p/348520921
有修饰变量生命周期的作用,也有类型推导的作用
volatile关键字:https://zhuanlan.zhihu.com/p/343688629
有禁止编译器优化,以及刷新变量值作用
register关键字:https://zhuanlan.zhihu.com/p/263575137
*/
五、函数指针
int add(int a,int b) {
return a + b;
}
//返回值类型 (* 自定义类型名称)(参数类型)
typedef int(*FuncName)(int,int);
void test08() {
FuncName fn = add;
int(*Fn)(int, int) = add;
printf("%d %d\n", Fn(100,34),fn(12,22));
}
六、malloc、calloc、realloc
//开辟一个10字节大小的内存
int *b = malloc(10);//不会设置内存值为0
//开辟一个4*sizeof(int)字节大小的内存
int* c = calloc(4, sizeof(int));//会设置内存为0
//对于b扩容,如果开辟的b后面还有剩余内存的话,则会在b后面紧接着开辟内存内存。
//如果没有的话,则会全部重新开启内存。把之前b的内容复制过去
b = (char*)realloc(b,10);
七、字符串数组
void test01() {
//char a[10] = "hello world"; //报错,字符串常量不能直接赋值给字符数组
char* str[] = {"ab","cd","123"};
char* str2[] = { "ab","cd","123" };
char** st1 = str;
/*
打印:ab b cd 123
*st1:表示常量字符串"ab"的首地址
*st1+1:表示常量字符串"ab"的第二个字符值
*(st1+1):表示常量字符串"cd"的首地址
*(st1 + 2):表示常量字符串"123"的首地址
*/
printf("%s %s %s %s\n",*st1,*st1+1,*(st1+1), *(st1 + 2));
}
八、通过内存拷贝获取结构体属性的字符串
typedef struct {
char* str1;
int age;
} person_t;
void test01() {
/*
* 当前默认的结构体对齐的模数是8,str1的类型是char *,age的类型是int,所以sizeof(p)的值16
*/
person_t p = {
.str1 = "hello world",
.age = 23
};
char** str1 = calloc(1, sizeof(char*));
/*
将p在内存中的前8个字节的内容拷贝给二级指针str1。
因为p在内存中的前8个字节的内容是字符串"hello world"在内存中的地址值,
所以这个地方要用二级指针来接收
*/
memcpy(str1, &p, 8);
//*str1将会得到"hello world"字符串首个字符的地址值。即p1与p2的值是相等的。
printf("str1=%s p1=%p p2=%p\n", *str1,*str1, &((*str1)[0]));
for (int i = 0; i < strlen(*str1);i++) {
printf("%c\n",(*str1)[i]);
}
free(str1);
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)