刨析《C语言》【进阶】付费知识【一】

{

case 1+0://ok

    printf("星期一");

case 1.0://error ,只能是整形常量

case n://error



break;//在最后的case语句加一个break,为以后添加case分支而好维护

}




[]( )if代码规范

------------------------------------------------------------------



int num = 4;

if(5 == num)//常量和变量比较时,常量因放在变量左边

//if(5 = num);//编译失败,直观错误

printf(“hehe”);




[]( )函数

--------------------------------------------------------------



### []( )实际参数(实参)



> 真实传给函数的参数,叫实参,实参可以是:常量,变量,表达式,函数等。无论实参是何种类型的量,在进行函调用时,它们都必须有确定的值,以便把这些值传递给形参。



### []( )形式参数(形参)



> 形式参数是指函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才实例化(分配内存单元),所以叫形式参数,形式参数当函数调用完成之后就自动销毁,因此形式参数只在函数中有效



时间函数



#include <stdio.h>

#include <time.h>

int main ()

{

time_t rawtime;

struct tm * timeinfo;



time ( &rawtime );

timeinfo = localtime ( &rawtime );

printf ( "当前本地时间为: %s", asctime (timeinfo) );



return 0;

}




[]( )函数的调用

-----------------------------------------------------------------



#include<stdio.h>

void Swap2(int* pa,int* pb)

{

int tmp = 0;

tmp = *pa;

*pa = *pb;

*pb = tmp;

}

//void Swap1(int x,int y)

//{

//

// int tmp = 0;

// tmp = x;

// x = y;

// y = x;

//}

int main()

{

int a = 10;

int b = 20;

printf("交换前:a = %d b = %d\n",a,b);

//Swap1(a, b);//传值调用

Swap2(&a, &b);//传址调用

printf("交换后:a = %d,b = %d\n",a,b);

return 0;

}




### []( )传值调用:



函数的形参和实参分别占有不同的内存块,对形参的修改不会影响实参。



### []( )传址调用✅✅



*   传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。

*   这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操作函数外部的变量。



> 传址调用可以节省内存,因为传值的话,我们需要拷贝,参数压栈的系统开销比较大,导致性能下降



### []( )函数嵌套



#include<stdio.h>

int main()

{

printf("%d",printf("%d",printf("%d",printf("%d",4))));//打印4111

//因为最后一个printf打印4,倒数第二个printf打印调用printf输出的个数为1(包括空格),依次...详细看printf函数文档

printf("%d",printf("%d",printf("%d",43))//4321

return 0;

}




### []( )函数递归(递去归来)



**递归的两个必要条件**



*   存在限制条件,当满足这个限制条件的时候,递归便不再继续

*   每次递归调用之后越来越接近这个限制



错误使用 递归



#include<stdio.h>

int main()

{

main();//err

return 0;

}




正确使用递归



#include<stdio.h>

void print(int n)//依次打印1 2 3 4

{

if(n>9)

	print(n/10);

printf("%d ",n%10);

}

int main()

{

int num = 0;

scanf("%d",&num);//1234

print(num);

}




### []( )回调函数



#include<stdio.h>

#include<stdlib.h>

#include<string.h>

//void qsort(void *base, //base中存放的是待排序数据中的第一个对象的地址

// size_t num, //排序数据元素的个数

// size_t size,//排序数据中一个元素的大小,单位是字节

// int (cmp)(const void,const void*)//是用来比较待排序数据中的2个元素的(一个)函数

// );

int cmp_int(const void* e1,const void* e2)

{

return *(int *)e1-*(int *)e2;//因为参数类型是void,我们用(*int)强制类型转换

/*返回值 意义

<0			所指向的元素在所指向的元素之前p1p2

0			指向的元素等效于 指向的元素p1p2

>0			指向的元素位于 指向的元素之后p1p2

*/

}

void print(int arr[],int sz)

{

int i= 0;

for(i=0;i<sz;i++)

{



	printf("%d ",arr[i]);

}

printf("\n");

}

void test1()

{

//整形数据的排序

int arr[]={9,8,7,6,5,4,3,2,1,0};

int sz=sizeof(arr)/sizeof(arr[0]);

//排序

qsort(arr,sz,sizeof(arr[0]),cmp_int);

//打印

print(arr,sz);

}

struct Stu

{

char name[20];

int age;

};

int sort_by_age(const void* e1,const void* e2)

{

return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;//转换结构体类型指针,e1指向age成员

}

void test2()

{

//排序结构体数据

struct Stu s[3]={ {"zhangsang",30},{"lisi",34},{"wangwu",20}};

int sz=sizeof(s)/sizeof(s[0]);

//按照年龄来排序



qsort(s,sz,sizeof(s[0]),sort_by_age);

}

int sort_by_name(const void* e1,const void* e2)

{

return strcmp(((struct Stu*)e1)->name ,((struct Stu*)e2)->name);

}

void test3()

{

//排序结构体数据

struct Stu s[3]={ {"zhangsang",30},{"lisi",34},{"wangwu",20}};

int sz=sizeof(s)/sizeof(s[0]);

//按照名字来排序



qsort(s,sz,sizeof(s[0]),sort_by_name);

}

int main()

{

//test1();

//test2();

test3();

return 0;

}




* * *



[]( )数组

--------------------------------------------------------------



*   数组的长度单位是常量表达式表示

*   数组在内存中连续存放的,



![请添加图片描述](https://img-blog.csdnimg.cn/b85453b4db1f4167b4ce444cef5de561.png)



int n =10;

int arr[n]={1,2,3,4,4,};//error




* * *



### []( )下标



> 如果下标是从那些已知正确的值计算得来,那么就无需检查它的值。如果一个用作下标的值是根据某种方法从用户输入的数据产生而来的,那么在使用它之前必须进行检查,确保它们位于有效的范围之内。



[]( )指针

==============================================================



### []( )指针,间接访问和变量



![请添加图片描述](https://img-blog.csdnimg.cn/796c8cad2dce4df99b845d5699c2b553.png)



#include<stdio.h>

int main()

{

int a=7;

int *d = &a;

*d = 10-*d;//*d==a   --  a=10-a(7)

//d= 10- *d;//err,因为d是个指针变量

//整形变量不能存储一个指针变量



*&a=*d;//说明变量a==*d,不建议这种表达式



printf("a==%p \n",a);

printf("*a==%p \n",*d);

printf("d==%p\n",d);

printf("&a==%p\n",&a);

return 0;

}




### []( )函数指针



void test(int **p2)

{

**p2=20;

}

int test_p(int x,int y)

{

return x+y;

}

#include<stdio.h>

int main()

{

int a =10;

int * pa=&a;//pa是一级指针

int **ppa=&pa;//ppa是二级指针

//二级指针传参

test(ppa);

test(&pa);//传一级指针的地址



int* arr[10]={0};

test(arr);

printf("%d ",a);



//pf函数指针变量

int (*pf)(int ,int )=&test_p;

return 0;

}


int Add(int x,int y)

{

return x+y;

}

#include<stdio.h>

int main()

{

//int (*pf)(int,int )=&Add;

int (*pf)(int,int )=Add;//Add  == pf



//int ret=(Add)(3,5);//3

//int ret=(*pf)(3,5)//1	;*是摆设,可以int ret=(*****pf)(3,5)结果依然正确

//int ret=*pf(3,5)//err;优先级  pf会先和(3,5)结合,任何*对函数的返回值8解引用肯定会错



int ret = pf(3,5);//2

printf("%d ",ret);//

return 0;

}




### []( )函数指针数组



int add(int x,int y)

{

return x+y;

}

int sub(int x,int y)

{

return x-y;

}

#include<stdio.h>

int main()

{

int (*pf1)(int ,int)=add;

int (*pf2)(int ,int)=sub;



int (*pfarr[2])(int ,int )={add,sub};//pfarr就是函数指针数组,{}里可以是pf1,pf2,*注意是花括号

//add函数和sub函数的形参因为一样,内存存放也是一样,而数组前提就是内存类型一样;

//所以可以同数组存放到函数指针,故叫做函数指针数组。

return 0;

}




### []( )函数指针数组的使用



#include<stdio.h>

int Add(int x, int y)

{

return x + y;

}

int Sub(int x, int y)

{

return x - y;

}

int Mul(int x, int y)

{

return x * y;

}

int Div(int x, int y)

{

return x / y;

}

void menu()

{

printf("**************************\n");

printf("**** 1. add    2. sub ****\n");

printf("**** 3. mul    4. div ****\n");

printf("****     0. exit      ****\n");

printf("**************************\n");

}

int main()

{

int input = 0;

//计算器-计算整型变量的加、减、乘、除

//a&b a^b a|b a>>b a<<b a>b



do {

	menu();

	

	int x = 0;

	int y = 0;

	int ret = 0;

	printf("请选择:>");

	scanf("%d", &input);



	switch (input)

	{

	case 1:

		printf("请输入2个操作数>:");

		scanf("%d %d", &x, &y);

		ret = Add(x, y);

		printf("ret = %d\n", ret);

		break;

	case 2:

		printf("请输入2个操作数>:");

		scanf("%d %d", &x, &y);

		ret = Sub(x, y);

		printf("ret = %d\n", ret);

		break;

	case 3:

		printf("请输入2个操作数>:");

		scanf("%d %d", &x, &y);

		ret = Mul(x, y);

		printf("ret = %d\n", ret);

		break;

	case 4:

		printf("请输入2个操作数>:");

		scanf("%d %d", &x, &y);

		ret = Div(x, y);

		printf("ret = %d\n", ret);

		break;

	case 0:

		printf("退出程序\n");

		break;

	default:

		printf("选择错误,重新选择!\n");

		break;

	}

	

} while (input);

return 0;

}




优化后的代码:



#include<stdio.h>

int Add(int x, int y)

{

return x + y;

}

int Sub(int x, int y)

{

return x - y;

}

int Mul(int x, int y)

{

return x * y;

}

int Div(int x, int y)

{

return x / y;

}

void menu()

{

printf("**************************\n");

printf("**** 1. add    2. sub ****\n");

printf("**** 3. mul    4. div ****\n");

printf("****     0. exit      ****\n");

printf("**************************\n");

}

int main()

{

int input = 0;

//计算器-计算整型变量的加、减、乘、除

//a&b a^b a|b a>>b a<<b a>b



do {

	menu();



	//pfArr就是函数指针数组

	//转移表 - 《C和指针》



	int (*pfArr[5])(int, int) = { NULL, Add, Sub, Mul, Div };

	int x = 0;

	int y = 0;

	int ret = 0;

	printf("请选择:>");

	scanf("%d", &input);//2



	if (input >= 1 && input <= 4)

	{

		printf("请输入2个操作数>:");

		scanf("%d %d", &x, &y);

		ret = (pfArr[input])(x, y);

		printf("ret = %d\n", ret);

	}

	else if(input == 0)

	{

		printf("退出程序\n");

		break;

	}

	else

	{

		printf("选择错误\n");

	}

} while (input);

return 0;

}




### []( )回调函数\_qsort函数的使用



#include<stdio.h>

#include<stdlib.h>

#include<string.h>

//void qsort(void *base, //base中存放的是待排序数据中的第一个对象的地址

// size_t num, //排序数据元素的个数

// size_t size,//排序数据中一个元素的大小,单位是字节

// int (cmp)(const void,const void*)//是用来比较待排序数据中的2个元素的(一个)函数

// );

int cmp_int(const void* e1,const void* e2)

{

return *(int *)e1-*(int *)e2;//因为参数类型是void,我们用(*int)强制类型转换

/*返回值 意义

<0			所指向的元素在所指向的元素之前p1p2

0			指向的元素等效于 指向的元素p1p2

>0			指向的元素位于 指向的元素之后p1p2

*/

}

void print(int arr[],int sz)

{

int i= 0;

for(i=0;i<sz;i++)

{



	printf("%d ",arr[i]);

}

printf("\n");

}

void test1()

{

//整形数据的排序

int arr[]={9,8,7,6,5,4,3,2,1,0};

int sz=sizeof(arr)/sizeof(arr[0]);

//排序

qsort(arr,sz,sizeof(arr[0]),cmp_int);

//打印

print(arr,sz);

}

struct Stu

{

char name[20];

int age;

};

int sort_by_age(const void* e1,const void* e2)

{

return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;//转换结构体类型指针,e1指向age成员

}

void test2()

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)
img

最后

文章到这里就结束了,如果觉得对你有帮助可以点个赞哦

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img

int);

//打印

print(arr,sz);

}

struct Stu

{

char name[20];

int age;

};

int sort_by_age(const void* e1,const void* e2)

{

return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;//转换结构体类型指针,e1指向age成员

}

void test2()

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-KjIGCh2O-1712903804563)]
[外链图片转存中…(img-8Cx2Fj1l-1712903804564)]
[外链图片转存中…(img-N8fwjsyT-1712903804564)]
[外链图片转存中…(img-dRlgzthm-1712903804565)]
[外链图片转存中…(img-1e3Rqfwz-1712903804565)]
[外链图片转存中…(img-A4i0YgdU-1712903804565)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)
[外链图片转存中…(img-4kxxXqiO-1712903804565)]

最后

文章到这里就结束了,如果觉得对你有帮助可以点个赞哦

[外链图片转存中…(img-0JFNILIW-1712903804566)]

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-E2XcbHHb-1712903804566)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值