C语言进阶(详细讲解)


一、数据的储存–各个类型的储存方式


1、介绍空类型–void 的使用

#include <stdio.h>

介绍空类型--void 的使用 
//void test()
//{
//	printf("hehe\n");
// } 
// int main()
// {
// 	test();
// 	return 0;
// }

2、大小端查询–写一个程序,判断该机器是大端存储模式还是小端

使用指针,,取地址
看第一个字节,如果为低位(00)就为大端,如果为高位的就为小端
//法一,,该题代码出错了,不能判断大小端 
//XXXXXXXXXXXXXXXXXXXXXXXXXX 
int main()
{
	int a = 3;
	//char* p = (char*) &a;
	char* p = &a;//a为整型,p为字符型,类型不一,需要强制转换,但是该软件不转也可以 
	if(*p == 1)//if(p == 1)
	{
		printf("小端\n");
	}
	else
	{
		printf("大端\n");
	}
	return 0;
 } 
//
//
//
法二,,用函数
int check_sys()
{
	int a = 1;
	char* p = (char*)&a;
	if(*p == 1)
		return 1;
	else
		return 0;
 } 
//
//简化
 int check_sys()
{
	int a = 1;
	char* p = (char*)&a;
	//返回1,小端;返回0,大端 
		return *p;
 } 
//
再简化
// int check_sys()
//{
//	int a = 1; 
//		return *(char*)&a;
// } 

3、// //指针类型的意义

// //1.指针类型决定了指针解引用操作符能访问几个字节;char*p;*p访问了1个字节,int*p;*p访问4个字节
// //2.指针类型决定了指针+1,-1,加的或者减得是几个字节;char*p;p+1,跳过一个字符。int*p;p+1,跳过一个整型-4个字节 
//int main()
//{
//	int ret = check_sys();
//	if(ret == 1)
//	{
//		printf("小端\n");
//	}
//	else
//	{
//		printf("大端\n");
//	}
//	return 0;
// } 

3、浮点型在内存中的储存

	//int main()
	//{
	//	double d = 1E10;//1乘10的10次方 
	//	printf("%lf\n",d);
	//	return 0;
	// } 

// 例题

int main()
{
	//9.0---1001.0
	//(-1)^0 * 1.001 *2^3
	// (-1)^S * M * 2^E
	//S=0   M=1.001   E=3   E=3+127=130=10000011
	//0 10000010 001 0000 0000 0000 0000 0000
	//0100 0001 1001 0000 0000 0000 0000 0000 

int n = 9;
//0 00000000 00000000000000000001001-补码 --E全为0,很小很小的数,,M=0.+00000000000000000001001 
float *pFloat = (float *)&n;
printf("n的值为: %d\n", n);//9 
printf("*pFloat的值为: %f\n", *pFloat);//0.000000
//(-1)^0 * 0.00000000000000000001001 * 2^-126 --很小很小的一个数 

*pFloat = 9.0;
//1001.0--1.001
//(-1)^0 * 1.001 * 2^3 ,,E=3+127=130
//0 10000010 001 0000 0000 0000 0000 0000
//0100 0001 0001 0000 0000 0000 0000 0000 
//1091567616--转换成十进制 
printf("num的值为: %d\n", n); 
printf("*pFloat的值为: %f\n", *pFloat);
return 0;
}



//int main()
//{
//	float f = 5.5;
//	//5.5---0101
//	//101.1
//	//(-1)^0 * 1.011 * 2^2
//	//S=0  M=1.011  E=2
//	//按照 S E M 存放进去,,
//	//存放 E 时要加上127,即E=129==100000001=128+1 
//	//存放 M时只存放小数点后面的数  M=011+0加到23位 
//	//0 10000001 011 0000 0000 0000 0000 0000
//	//0100 0000 1011 0000 0000 0000 0000 0000 
//	//0x40b00000--十六进制 
//	printf("%f\n",f);
//	return 0;
//}

二、面试例题


1、//输出结果是什么?

#include <stdio.h> 

//输出结果是什么?
一、 
//int main()
//{
//	//内存存的是补码 
//	char a= -1;
//	//10000000000000000000000000000001--原码 
//	//11111111111111111111111111111110--反码
//	//11111111111111111111111111111111--补码--反码加1
//	//11111111=a输入的结果  
//	//整型提升--按原符号位提升,有符号的第一位为符号位,补符号位 1
//	//11111111111111111111111111111111--整型提升后的结果 
//	//输出--是输出原码的结果,找到原码 a=-1
//	signed char b= -1;
//	//111111111=b
//	//和a一样,,b=-1 
//	unsigned char c= -1;
//	//11111111=c 
//	//无符号位 ,补0 
//	//00000000000000000000000011111111--用计算机算出后结果就为255 
//	printf("a=%d,b=%d,c=%d",a,b,c);//%d是指输出的为整型,此处会整型提升,有符号的,要加符号位,补1 
//	
//	return 0;
//}

二、

//int main()
//{
//	//无符号的原反补码一样 
//	char a = -128;//char a = -128;127+1=-128两个结果一样,char类型没有128,只有负的 
//	//100000000000000000000000010000000--(-128)的二进制原码
//	//111111111111111111111111101111111--反码
//	//111111111111111111111111110000000--补码 
//	//10000000--输入的数
//	//111111111111111111111111110000000--整型提升后的补码
//	//找到原码 //无符号的原反补码一样 ,所以这就是结果 
//	printf("%u\n",a);//--结果4294967168
//	//%d- 打印十进制的有符号数字
//	//%u - 打印十进制的无符号数字 
//	return 0;
// } 

三、

//int main()
//{
//	int i = -20;
//	unsigned char j = 10; 
//	printf("%d\n",i+j);
//	return 0;
// } 
// //-20
// //10000000 00000000 00000000 00010100
// //11111111 11111111 11111111 11101011--反码
// //11111111 11111111 11111111 11101100--补码
// //00000000 00000000 00000000 00001010--补码  -10的
// //11111111 11111111 11111111 11110110--相加结果
// //11111111 11111111 11111111 11110101--减1
// //10000000 00000000 00000000 00001010--原码--最后结果 =-10 ,,符号位不变 

四、

//#include <windows.h>
//int main()
//{
//	unsigned int i;
//	for(i=9;i>=0;i--)//当i=0后,i--为-1,-1的补码为全1,是个很大的数字 
//	{
//		printf("%u\n",i);
//		Sleep(100); 
//	}
//	//死循环 
//	return 0;
// } 

五、

//#include <windows.h>
//int main()
//{
//	char a[1000];
//	int i;
//	for(i=0;i<1000;i++)
//	{
//		a[i] = -1-i;
//	} 
//	printf("%d\n",strlen(a));//strlen要遇到"\0"才会停,-128到127,,,127到1,0,停下,255个 
//	return 0;
// } 

//六

unsigned char i = 0;//范围为0-255 
int main()
{
	for(i=0;i<=255;i++)//i<=255恒成立,死循环 
	{
		printf("hello world\n");
	}
	return 0;
}

三、指针详解


1、看此处输出的是几个字符,32和64为系统的

#include <stdio.h>
看此处输出的是几个字符,,32和64为系统的 
//void test(int arr[])//错误:void test(a)
//{
//	int sz = sizeof(arr) / sizeof(arr[0]);
//	printf("%d\n",sz);
//}
//int main()
//{
//	int arr[10] = {0};
//	test(arr);//错误:int test(arr); 
//	return 0;
// } 

2、//字符指针

//写法一 
//int main()
//{
//	char ch[] = "w";
//	char* p = &ch;
//	printf("%s\n",p);
//	return 0;
// } 
 
 
 写法二 
// int main()
// {
// 	char arr[] = "abcdef";
// 	char* p = arr;
// 	printf("%s\n",p);
// 	printf("%s\n",arr);
// 	return 0;
// }

写法三 
//int main()
//{
//	const char* p = "abcdef";//"abcdef"是一个常量字符串 ,,不能改 
//	printf("%c\n",*p);//输出结果为a,,输出的是首字符的地址 
//	printf("%s\n",p);//输出的是字符串abcdef 
//	return 0;
//}

3、//面试题

//int main()
//{
//	char arr1[] = "abcdef";
//	char arr2[] = "abcdef";
//	char* p1 = "abcdef";
//	char* p2 = "abcdef";
//	//一,,输出结果不相等,haha 
//	if(arr1 == arr2)
//	{
//		printf("hehe\n");
//	}
//	else
//	{
//		printf("haha\n");
//	}

二,,hehe
//	if(p1 == p2)
//	{
//		printf("hehe\n");
//	}
//	else
//	{
//		printf("haha\n");
//	}
//	return   0;
//}

4、//说明

//int main()
//{
//	int arr[10] = { 0 };//整型数组 
//	char ch[5] = { 0 };//字符数组 
//	int* parr[4];//存放整型指针的数组 - 指针数组 
//	char* pch[5];//存放字符指针的数组 - 指针数组 
//	return 0;
// } 

5、//举例

错误示范,,指针数组不是这样用的 
//int main()
//{
//	int a = 10;
//	int b = 20;
//	int c = 30;
//	int* arr[3] = {&a,&b,&c};
//	int i = 0;
//	for(i=0;i<3;i++)
//	{
//		printf("%d ",*(arr[i]));
//	}
//	return 0;
// } 

正确用法
//int main()
//{
//	int arr1[10] = {1, 2, 3, 4, 5};
//	int arr2[10] = {2, 3, 4, 5, 6};
//	int arr3[10] = {3, 4, 5, 6, 7};
//	int* parr[] = {arr1,arr2,arr3};
//	int i = 0;
//	for(i=0;i<3;i++)//找到每个数组的第一个数字 
//	{
//		int j = 0;
//		for(j=0;j<5;j++)//每个数组从第一个往后面走 
//		{
//		printf("%d ",*(parr[i]+j));	
//	}
//		printf("\n");
//	}
//	return 0;
//}

6、//数组指针

//int main()
//{
//	int *p = NULL;//p是整型指针 - 指向整型的指针 - 可以存放整型的地址 
//	char* pc = NUNLL;//pc是字符指针 - 指向字符的指针 - 可以存放字符的地址 
//	//数组指针 - 指向数组的指针 - 存放数组的地址 
//	int arr[10] = {0};
//	//arr - 首元素的地址
//	//&arr[0] - 首元素的地址
//	//&arr - 数组的地址
//	
//	int arr[10] = {1,2,3,4,5,6,7,8,9,10};
//	int (*p)[10] = &arr;//数组的地址要存放起来,把数组的地址给指针p 
//	//上面的p就是数组指针,,因为[]的优先级大于*,如果是int* p[10]的话,表示的是一个数组 
//	
//	
//	return 0;
// } 

7、注意一下两个的区别,注意*的个数,以及指针数组和数组的表示方法

//int main()
//{
//	char* arr[5];//指针数组 
//	char* (*parr)[5] = &arr;
//	
//	int arr2[10] = { 0 };//数组 
//	int (parr2)[10] = &arr2;
//	return 0;
// } 

8、

//int main()
//{
//	//法一,不用数组指针
//	int arr[10] = {1,2,3,4,5,6,7,8,9,10};
	int *p = arr;
	int i = 0;
	for(i=0;i<10;i++)
	{
		printf("%d ",*(p+i));
	 } 
//	 
//	 //法二,法三,用的是数组指针,但是不方便,数组指针一般用于二维数组
	 int (*pa)[10] = &arr;
	 int i = 0;
	 for(i=0;i<10;i++)
	 {
	 	printf("%d ",*(*pa+i));//*pa == arr;
	 }
//	//法三
//	int (*pa)[10] = &arr;
//	int i = 0;
//	for(i=0;i<10;i++)
//	 {
//	 	printf("%d ",(*pa)[i]);
//	 } 
//
//
//	return 0;
// } 

9、数组指针的正确用法

参数是数组的形式 
//void print1(int arr[3][5],int x,int y)
//{
//	int i = 0;
//	int j = 0;
//	for(i=0;i<x;i++)
//	{
//		for(j=0;j<y;j++)
//		{
//			printf("%d ",arr[i][j]);
//		}
//		printf("\n");
//	}
//}
参数是指针形式 
//void print2(int (*p)[5],int x,int y)
//{
//	int i = 0;
//	int j = 0;
//	for(i=0;i<x;i++)
//	{
//		for(j=0;j<y;j++)
//		{
//			//以下方法均可以,,具体看下面的一维数组的代码 
//			printf("%d ",p[i][j]);
//			//printf("%d ",*(p[i])+j); 
//			//printf("%d ",*(*(p+i)+j));//P+i解引用得到的是二维数组中第i行的的一维数组所有元素,加j则是这行第j个的地址,然后再解引用得到第j个的值
//			//printf("%d ",(*(p+i))[j]);//这样也可以 
//		}
//		printf("\n");
//	}
//}
//int main()
//{
//	int arr[3][5] = {{1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7}};
//	print1(arr,3,5);//arr - 数组名 - 数组名就是首元素地址 
//	print2(arr,3,5); 
//	return 0;
// } 


//对应上题的一维数组举例
int main()
{
	int arr[10] = {1,2,3,4,5,6,7,8,9,10};
	int i = 0;
	int* p = arr;
	for(i=0;i<10;i++)
	{
		//printf("%d ",p[i]);
		printf("%d ",*(p+i));
		//printf("%d ",*(arr+i));
		//printf("%d ",arr[i]);//arr[i] == *(arr+i) == *(p+i) ==p[i]
		
		
	}
	return 0;
 } 
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值