003

003,第1张

一、printf输出int值
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);
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/3002706.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-09-27
下一篇 2022-09-27

发表评论

登录后才能评论

评论列表(0条)

保存