C语言笔记含源码(变量、输入输出、分支、循环、函数、数组、指针、字符串、结构体)小总结

一、变量与输入输出

定义变量需要:类型、变量名、变量值(可有可无)

#include <stdio.h>
#include <stdlib.h>
int main() //程序入口
{
	printf("hello\n");
    
    int num1;
    int num2;
    
    /* 01
    printf("请输入一个加数:\n");
    scanf("%d",&num1); 	//1.双引号中除了占位符,其余尽量不要写,否则可能产生错误
			//输入:		//2.占位符代表从键盘输入一个数,注意取地址
                        //3.输入输出擦别:输入比输出多了一个“&” 即取址符
                        //4.当连续输入多个变量时,分开写
    
    printf("请输入一个加数:\n");
    scanf("%d",&num2);
    
    int num3=num1+num2;
    printf("我很帅\n");*/
    
    
    printf("请输入两个加数\n");	
    
    //scanf("%d %d",&num1,&num2);//多个变量输入 严格按照“”里面的格式
    scanf("%d,%d",&num1,&num2);//必需输入  4,4
    
    int num3=num1+num2;
    
    printf("结果:%d+%d=%d\n",num1,num2,num3);	//占位符,%d 代表在输出的地方,占了一个坑,至于输出啥,根据逗号后面的变量名里面的变量值
	system("pause");
    
    
	return 0;
}

心得一:在输出(printf)时时刻注意换行(\n)的使用
心得二:非必要情况,选择英文输入法。如上例程序:
英文输入法下正常:在这里插入图片描述
中文输入法下的结结果在这里插入图片描述

二、分支语句

分支语句包括if-else及其嵌套,swtich
if-else

#include <stdio.h>
#include <stdlib.h>
int main()
{
	//0.定义变量
    int num;
    
	//1.请输入一个数
    printf("请输入一个数\n");
    
    //2.获取用户输入
    scanf("%d",&num);
    
    //3.是否满足条件
    if(num==100){
		//满足 输出满足
        printf("我嫁给你\n");
    }
    else{
		//不满足
		printf("那就这样吧\n");
    }
    
	system("pause");
	return 0;
}

运行结果:
在这里插入图片描述
在这里插入图片描述
if-else嵌套

//判断分数等级 等级条件略。。。

#include <stdio.h>
#include <stdlib.h>
int main()
{
	int score;

	//1.提示输入
    printf("请输入成绩\n");
    
    //2.获取用户输入
    scanf("%d",&score);
    
    //3.判断等级
    if(score >= 90){
    
		printf("成绩优秀\n");
    }else if(75 <= score && score < 90){
		printf("成绩良好\n");
    }else if(60 <= score && score < 75){
		printf("成绩及格\n");
    }else if(40<= score && score <60){
		printf("不及格\n");
    }else{
		printf("很差劲,退学!\n");
    }
    
	system("pause");
	return 0;
}

运行结果:

请输入成绩
90
成绩优秀
请按任意键继续. . .

switch

#include <stdio.h>
#include <stdlib.h>
int main()
{
	//0.定义
    int data;

	//1.提示用户输入
    printf("请输入一个数\n");
    
    //2.获取用户输入
    scanf("%d",&data);
    
    //3.判断数据
    if(data == 100){
		printf("牛逼,可以找对象了\n");
    
    }else{
		switch(data/10){
		/* case 1:
			printf("你输入了一个1\n");
			break;
            
        case 2:
			printf("你输入了一个2\n");
			//break;*/
            
        case 1:
        case 2:
        case 3:
			printf("不及格,而且很擦\n");
			break;
            
        case 4:
        case 5:
			printf("不及格\n");
			break;
            
        case 6:
        case 7:
			printf("还行,及格了\n");
			break;
             
        case 8:
			printf("成绩良好\n");
            break;
        
        case 9:
			printf("成绩优秀\n");
            break;
        //case 10:
			//printf("")
        default:
			printf("非法成绩\n");
            break;  
    
    
    }
    
    }    
	system("pause");
	return 0;
}

运行结果:

请输入一个数
56
不及格
请按任意键继续. . .

三、循环

for循环

#include <stdio.h>
#include <stdlib.h>
int main()
{
	int score;
    int ciShu = 0;//循环的初始条件
    
//    while(1)
    //for(ciShu = 0; ciShu < 5; ciShu = ciShu + 1)
    for(;;){ //强调分号
    
		//cishu = cishu + 1; //循环条件发生变化
		
    	//1.提示输入
		printf("请输入第%d成绩\n",ciShu+1);
    
		//2.获取用户输入
		scanf("%d",&score);
    
		//3.判断等级
		if(score >= 90){
    
			printf("成绩优秀\n");
		}else if(75 <= score && score < 90){
			printf("成绩良好\n");
		}else if(60 <= score && score < 75){
			printf("成绩及格\n");
		}else if(40<= score && score <60){
			printf("不及格\n");
		}else{
			printf("很差劲,退学!\n");
		}
        
        /*if (cishu == 3){ //循环终止条件
			break; //跳出循环
        } */
    }
	system("pause");
	return 0;
}

运行结果:

请输入第1成绩
23
很差劲,退学!
请输入第2成绩
52
不及格
请输入第3成绩
65
成绩及格
请输入第4成绩
99
成绩优秀
请输入第5成绩

do-while
do-while循环与while循环:do-while至少执行一次,不关心条件,第一次循环执行后循环次数才与条件有关。while循环的每次循环都与循环的条件相关。

#include <stdio.h>
#include <stdlib.h>
int main()
{
	/*while(1){
		printf("***帅\n");
    }*/
    int i=0;
    do{
		i++;
		printf("可以处对象了\n");
    
    }while(i<=10);//11次,i==10时多执行一次
    
	system("pause");
	return 0;
}

运行结果:

可以处对象了
可以处对象了
可以处对象了
可以处对象了
可以处对象了
可以处对象了
可以处对象了
可以处对象了
可以处对象了
可以处对象了
可以处对象了
请按任意键继续. . .

四、函数

形参的作用域是函数的左耳朵(左括号)和右耳朵(右括号)之间

#include <stdio.h>
#include <stdlib.h>

//函数是一个功能模块
/*
定义函数:1.返回值 2.形参 3.函数名 4.函数体 代码块
调用函数:函数(形参)
 */

/*
为什么用函数:1.代码很好看 2.容易定位问题 3.可复用性强 4.分工
*/

int prepare(){ //有返回无参数
	printf("做准备\n");
    printf("洗漱\n");
    printf("穿衣\n");
    printf("准备完毕\n\n");
    
	return 0;
}

int onTheBorad(){
	printf("在路上\n");
    printf("订饭店\n");
    printf("找滴滴\n");
    printf("路上事情做完\n\n");
	return 0;
}

int datting(){
	printf("约会中\n");
    printf("寒暄\n");
    printf("吃饭\n");
    printf("看电影\n");
    printf("约会完毕\n\n");
	return 0;
}

int goBackHome(){
	printf("回家\n");
    printf("Ok\n\n");
    
    int mark = 0;
    
	return 0;
}



void delay(int i){//无返回有参数
	//int i;//局部变量 类似形参
    for(i = 0; i < 5000; i++);
}

//你爸爸叫你买米,不关心买多少斤(形式参数),也不关心买回来了没有
void buyRice(){ //无返回无参数
	printf("去买米。。。\n\n");
}

void buyRice2(int jinShu){ //jinShu是形式参数,类似变量定义 int i;
	printf("去买%d斤米。。。\n",jinShu); //如果提示\243,\254则说明你可能写了中文符号
    
}


//形式参数,作用域仅限该函数

int main()
{
	prepare();//出门前的准备
    
    onTheBorad();//在路上
    
    datting();//约会中
    
    goBackHome();//回家
    //以上是自定义函数,需要去把函数做出来
    printf("\n");
    
    buyRice();
    buyRice2(20);	//带形参的自定义函数
    buyRice2(5);
    
	system("pause");//调用windows指令
	return 0;
}

运行结果:

做准备 洗漱 穿衣 准备完毕

在路上 订饭店 找滴滴 路上事情做完

约会中 寒暄 吃饭 看电影 约会完毕

回家 Ok

去买米。。。

去买20斤米。。。 去买5斤米。。。 请按任意键继续. . .

自定义函数实现计算器
函数可以多级调用

#include <stdio.h>
#include <stdlib.h>

void tip(){
    printf("********************\n");
    printf("***作者:最帅------*\n");
    printf("********************\n");
}

int add(int data1,int data2){
	int ret=data1+data2;
    return ret;
}

int minu(int data1,int data2){
	int ret=data1-data2;
    return ret;
}

int mult(int data1,int data2){
	int ret=data1*data2;
    return ret;
}

float chu(int data1,int data2){
	float ret=(float)data1/data2;
    return ret;
}
void tipSuanFa(char suanFa){
	switch(suanFa){
		case '+':
			printf("你选择了加法\n");
            break;
        case '-':
			printf("你选择了减法\n");
            break;
        case '*':
			printf("你选择了乘法\n");
            break;
        case '/':
			printf("你选择了除法\n");
            break;
    }

}


void realCalc(int data1,int data2,char suanFa)
{
	switch(suanFa){
		case '+':
			printf("加法结果:%d+%d=%d\n",data1,data2,add(data1,data2));
            break;
        case '-':
			 printf("减法结果:%d-%d=%d\n",data1,data2,minu(data1,data2));
            break;
        case '*':
			printf("乘法结果:%d*%d=%d\n",data1,data2,mult(data1,data2));
            break;
        case '/':
			printf("除法结果:%d/%d=%f\n",data1,data2,chu(data1,data2));
            break;
    }
}
void clac(char suanFa)
{
	
    int data1;
    int data2;
    
    tipSuanFa(suanFa);
    
    printf("请输入第一个数\n");
    scanf("%d",&data1);         
    printf("请输入第二个数\n");
    scanf("%d",&data2);
    
    realCalc(data1,data2,suanFa);
          
}

int main()
{
	//int data1;
    //int data2;
    
   // int ret;
    
    char ch;
    
    int i=0;
    while(1){
		tip();
		if(i!=0)
			getchar();//吸收第一次(不吸收)之后的 输入完“请输入第二个数”之后的回车符
        i=1;
        
		printf("请输入你要运算的类型\n");
		scanf("%c",&ch);
        getchar();//回车符也是一种字符,getchar用来获取字符,此处用来吸收字符
        clac(ch);
    }   
	system("pause");
	return 0;
}

运行结果:

********************
***作者:最帅------*
********************
请输入你要运算的类型
+
你选择了加法
请输入第一个数
2
请输入第二个数
3
加法结果:2+3=5
********************
***作者:最帅------*
********************
请输入你要运算的类型
/
你选择了除法
请输入第一个数
9
请输入第二个数
3
除法结果:9/3=3.000000
********************
***作者:最帅------*
********************
请输入你要运算的类型

五、数组

数组的定义、初始化、访问

#include <stdio.h>
#include <stdlib.h>
int main()
{
	
    printf("hello\n");
    
    int array[100];//没有初始化数组,仅仅申请了100个内存空间  最好初始化array[100]={0}
    int array2[3]={1,2,3};//有初始化的数组,该数组申请了三个整型数内存空间,并赋值1 2 3
    int array3[100]={1,2,3};//有初始化的数组,不完整初始化,该数组申请了100个内存空间,但是只赋值了三个数1 2 3,放在了数组的前三个位置 其余默认是 0
    
    //int n;
    //scanf("%d",&n);
    //int array4[n];//实际应用中无报错,可以使用,但教材中认为非法
    //学到指针时,就可以抛弃这种方法,用指针思维来做
    
    //***************数组通过下标引用元素**********************
    printf("array2的第二个元素是:%d\n",array2[1]);
    
    //数组中[]只有定义时候是表示数组大小,其余任何情况都表示用下标访问数组
    int i;
	for(i = 0; i < 3; i++){
		printf("第%d个元素是:%d\n",i+1,array2[i]);
    }
    
	system("pause");
	return 0;
}
/*
1.数组是数据集
2.数组数据同类型
*/

运行结果:

hello
array2的第二个元素是:2
第1个元素是:1
第2个元素是:2
第3个元素是:3
请按任意键继续. . .

数组与函数(算数组大小,数组传参、形参)

#include <stdio.h>
#include <stdlib.h>
					//地址!!
void arrayPrint(int datas[],int cnt)//形式参数中,虽然写的是数组样子 但是 中括号中数组大小是没有用的
{									//中括号里写多少都不能代表形参数组有多大
									//这里中括号的作用仅仅是用来表示该参数是一个地址(这里是数组首地址) 在windows啊哈C中4个字节表示地址 linux64位中用8个字节表示
                                    
	int i;
     //printf("函数中array数组个数:%d\n",sizeof(datas)/sizeof(datas[0]));// 4/4=1
    for(i = 0;i<cnt;i++)
    {
		printf("%d ",datas[i]);
    }
    putchar('\n');//putchar 输出一个字符 getchar()获取一个字符的输入 当时过滤回车
    
}

int main()
{
	int array[20]={11,22,33};
    printf("array数组个数:%d\n",sizeof(array)/sizeof(array[0]));
    //printf("array数组个数:%d\n",sizeof(&array[0])/sizeof(array[0]));  //sizeof(&array[0]) 指针大小 4,数组名代表数组大小
    arrayPrint(array,sizeof(array)/sizeof(array[0]));
    arrayPrint(&array[0],sizeof(array)/sizeof(array[0]));
    
    //sizeof计算操作数存储字节大小
    /*
    printf("array数组名大小:%d\n",sizeof(array));//数组名代表数组  20 x 4
    printf("指针大小:%d\n",sizeof(&array[0]));//是指针 4
    */
    
    
    int a[3];
    char b[3];
											//类型大小 * 元素个数
    printf("a数组大小:%d\n",sizeof(a));	//	4		*3  
    printf("b数组大小:%d\n",sizeof(b));	//	1		*3
    
    printf("一个int数据类型的大小:%d\n",sizeof(int));	//4
    printf("一个char数据类型的大小:%d\n",sizeof(char));	//1
    
    //请问数组长度??
    printf("a数组长度为:%d\n",sizeof(a)/sizeof(a[0]));//避免了数据类型 巧用a[0]
    printf("b数组长度为:%d\n",sizeof(b)/sizeof(b[0]));
    
    
    /*
	//arrayPrint(array);
    //1.数组和函数结合,数组名做实际参数
    */
	system("pause");
	return 0;
}

运行结果

array数组个数:20
11 22 33 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
11 22 33 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
a数组大小:12
b数组大小:3
一个int数据类型的大小:4
一个char数据类型的大小:1
a数组长度为:3
b数组长度为:3
请按任意键继续. . .

数组和函数综合应用

#include <stdio.h>
#include <stdlib.h>


void initScores(int datas[],int size)
{
	int i;
    
    for(i=0;i<size;i++)
    {
		printf("请输入第%d个学生的分数:",i+1);
        scanf("%d",&datas[i]);
       
        if(datas[i]<0 || datas[i]>100)
        {
			printf("我信你个大头鬼\n");
            printf("tui~\n");
            system("pause");
            
            exit(-1);
        }
    }
	
}

void printScores(int datas[],int size)
{
	int i;
    
	printf("学生分数如下:\n");
    for(i=0;i<size;i++)
    {
		printf("第%d个学生的分数是%d\n",i+1,datas[i]);
    }

}

int scoresMax(int datas[],int size)
{
	int i;
    int max;
    
    max=datas[0];//初始赋值
    
    for(i=1;i<size;i++) //比较
    {
		if(max<datas[i])
        {
			max=datas[i];
        }
    }

	return max;
}

int scoresMin(int datas[],int size)
{
	int i;
    int min;
    
    min=datas[0];//初始赋值
    
    for(i=1;i<size;i++) //比较
    {
		if(min>datas[i])
        {
			min=datas[i];
        }
    }

	return min;
}

float scoresAver(int datas[], int size)
{
	int sum;
    int i;
    
    sum=0;
    
    for(i=0;i<size;i++)
    {
		sum+=datas[i];
    }
    //printf("%d",sum);
    return (float)sum/size;
}

printRet(int data1,int data2,float data3)
{
	printf("分数最大值:%d\n分数最小值:%d\n分数平均值%f\n",data1,data2,data3);
}

int main()
{

	int scores[10]={0};
    int len;
    int max;
    int min;
    float average;
    
    len=sizeof(scores)/sizeof(scores[0]);
    
    //1.初始化学生分数
    initScores(scores,len);
    
    //2.输出学生分数
    printScores(scores,len);
    
    //3.计算分数最大值
    max=scoresMax(scores,len);
    
    //4.计算分数最小值
    min=scoresMin(scores,len);
    
   // 5.计算分数平均值
    average=scoresAver(scores,len);
    
   // 6.输出结果
    printRet(max,min,average);
    
    
	system("pause");
	return 0;
}

运行结果:

正常分数输入的

请输入第1个学生的分数:60
请输入第2个学生的分数:70
请输入第3个学生的分数:80
请输入第4个学生的分数:90
请输入第5个学生的分数:100
请输入第6个学生的分数:60
请输入第7个学生的分数:32
请输入第8个学生的分数:65
请输入第9个学生的分数:56
请输入第10个学生的分数:10
学生分数如下:
第1个学生的分数是60
第2个学生的分数是70
第3个学生的分数是80
第4个学生的分数是90
第5个学生的分数是100
第6个学生的分数是60
第7个学生的分数是32
第8个学生的分数是65
第9个学生的分数是56
第10个学生的分数是10
分数最大值:100
分数最小值:10
分数平均值62.299999
请按任意键继续. . .

分数不正常输入:

请输入第1个学生的分数:20
请输入第2个学生的分数:60
请输入第3个学生的分数:90
请输入第4个学生的分数:100
请输入第5个学生的分数:101
我信你个大头鬼
tui~
请按任意键继续. . .

六、指针

C语言中的指针可以直接对特定的内存地址操作,这是很多编程语言所不具备的。巧妙运用指针能使程序变得灵活。

定义指针(对比非指针变量)

#include <stdio.h>
#include <stdlib.h>
int main()
{

	int a=10;//整型变量
    a=100;
    char c;//字符变量
    c='a';
    int array[3]={1,2,3};//数组 变量
    
    
    
	int *p;//指针变量存放的地址
    p = &a;//给指针变量赋值
    
    int *p2=&a;//定义并且初始化指针变量
    
    
		/*
			共同点:都是变量
            不同:变量类型
        */
    
    
    /*
		问:什么变量能存放地址,存放的是地址?
        答:指针变量
        问:怎么定义指针变量?
        int* p; 
        int *p;
        char  
    */
	system("pause");
	return 0;
}

通过指针访问变量

#include <stdio.h>
#include <stdlib.h>

/*
一、变量名的访问方式有两种
变量名 地址

四、指针=地址 
*/
int main()
{
	int juHuaTai=10;	//定义变量
    int meiGuiTai=88;
    
    int *p;	//定义指针
    p=&juHuaTai;
    int *p2=&meiGuiTai;
    
    printf("juHuaTai=%d\n",juHuaTai);	//一、通过变量名输出
    printf("meiGuiTai=%d\n",meiGuiTai);
    
    printf("juHuaTai的地址是:%p\n",&juHuaTai);	//二、取变量名所代表的变量的内存地址(取地址)
    printf("meiGuiTai的地址是:%p\n",&meiGuiTai);
    
    printf("通过地址访问juHuaTai的值=%d\n",*(&juHuaTai));	//三、此时,*是一个运算符 与+-*/类似,该运算符的功能是取出内存地址中的数据的值(取内存)
    printf("通过地址访问meiGuiTai的值=%d\n",*(&meiGuiTai));	
    
    printf("通过地址访问juHuaTai的值=%d\n",*p);		//取内存
    printf("通过地址访问juHuaTai的值=%d\n",*p2);
    
    
	system("pause");
	return 0;
}

运行结果:

juHuaTai=10
meiGuiTai=88
juHuaTai的地址是:0060FEF4
meiGuiTai的地址是:0060FEF0
通过地址访问juHuaTai的值=10
通过地址访问meiGuiTai的值=88
通过地址访问juHuaTai的值=10
通过地址访问juHuaTai的值=88
请按任意键继续. . .

指针分类型&指针与数组

#include <stdio.h>
#include <stdlib.h>
int main()
{
	int a=10;
    char c='s';
    
    int *p;
    char *p2;
    
    p=&a;//p=&c判断计算机的大小端
    p2=&c;
    
    printf("a的值是%d\n",a);
    printf("c的值是%c\n",c);
    
    printf("a的地址是%p\n",p);
    printf("a的++地址是%p\n",++p);
    printf("c的地址是%p\n",p2);
    printf("c的++地址是%p\n",++p2);
    
    int array[3]={1,2,3};//数组 关心首地址 1.数组名array2.第一个元素的地址&array[0]
    
    printf("第一个数组元素的地址%p\n",&array[0]);
    printf("第二个数组元素的地址%p\n",&array[1]);
    printf("第三个数组元素的地址%p\n",&array[2]);
    
    //遍历数组
    int i;
    for(i=0;i<3;i++)
    {
		printf(" %d ",array[i]);
    }
    
    int *parray;
    
    parray=array;
    /*
    printf("\n第一个数组元素的地址%p\n",parray++);
    printf("第二个数组元素的地址%p\n",parray++);
    printf("第三个数组元素的地址%p\n",parray++);
    
    
    parray=array;
    */
    for(i=0;i<3;i++)
    {
		printf(" %d ",*parray++);	// * 优先级 > ++ 优先级
    }

    parray=array;
    for(i=0;i<3;i++)
    {
		printf(" %d ",parray[i]);
    }

    
	system("pause");
	return 0;
}

运行结果:

a的值是10
c的值是s
a的地址是0060FEDC
a的++地址是0060FEE0
c的地址是0060FEDB
c的++地址是0060FEDC
第一个数组元素的地址0060FECC
第二个数组元素的地址0060FED0
第三个数组元素的地址0060FED4
1 2 3 1 2 3 1 2 3 请按任意键继续. . .

指针数组函数的综合
此例代码主要将上述某代码函数的数组形参改为指针形参。

#include <stdio.h>
#include <stdlib.h>

void initScores(int *datas,int size)
{
	int i;
    
    for(i=0;i<size;i++)
    {
		printf("请输入第%d个学生的分数:",i+1);
        scanf("%d",datas);		//用指针就不用取地址(&)
       
        if(*datas<0 || *datas>100)
        {
			printf("我信你个大头鬼\n");
            printf("tui~\n");
            system("pause");
            
            exit(-1);
        }
        datas++;
    }
	
}

void printScores(int *datas,int size)
{
	int i;
    
	printf("学生分数如下:\n");
    for(i=0;i<size;i++)
    {
		printf("第%d个学生的分数是%d\n",i+1,*datas++);
    }

}

int scoresMax(int *datas,int size)
{
	int i;
    int max;
    
    max=*datas++;//初始赋值
    
    for(i=1;i<size;i++) //比较
    {
		if(max < *datas)
        {
			max=datas[0];//指针后移 不能交叉使用datas[i]
        }
        datas++;
    }

	return max;
}

int scoresMin(int *datas,int size)
{
	int i;
    int min;
    
    min=*datas++;//初始赋值
    
    for(i=1;i<size;i++) //比较
    {
		if(min>*datas)
        {
			min=datas[i];
        }
    }

	return min;
}

float scoresAver(int datas[], int size)
{
	int sum;
    int i;
    
    sum=0;
    
    for(i=0;i<size;i++)
    {
		sum+=*datas++;
    }
    //printf("%d",sum);
    return (float)sum/size;
}

printRet(int data1,int data2,float data3)
{
	printf("分数最大值:%d\n分数最小值:%d\n分数平均值%f\n",data1,data2,data3);
}

int main()
{

	int scores[10]={0};
    int len;
    int max;
    int min;
    float average;
    
    len=sizeof(scores)/sizeof(scores[0]);
    
    //1.初始化学生分数
    initScores(scores,len);
    
    //2.输出学生分数
    printScores(scores,len);
    
    //3.计算分数最大值
    max=scoresMax(scores,len);
    
    //4.计算分数最小值
    min=scoresMin(scores,len);
    
   // 5.计算分数平均值
    average=scoresAver(scores,len);
    
   // 6.输出结果
    printRet(max,min,average);
    
    
	system("pause");
	return 0;
}

运行结果:

请输入第1个学生的分数:12
请输入第2个学生的分数:56
请输入第3个学生的分数:60
请输入第4个学生的分数:100
请输入第5个学生的分数:90
请输入第6个学生的分数:88
请输入第7个学生的分数:80
请输入第8个学生的分数:70
请输入第9个学生的分数:30
请输入第10个学生的分数:10
学生分数如下:
第1个学生的分数是12
第2个学生的分数是56
第3个学生的分数是60
第4个学生的分数是100
第5个学生的分数是90
第6个学生的分数是88
第7个学生的分数是80
第8个学生的分数是70
第9个学生的分数是30
第10个学生的分数是10
分数最大值:100
分数最小值:12
分数平均值59.599998
请按任意键继续. . .

为什么用指针
1.在指定地址存储数据

#include <stdio.h>
#include <stdlib.h>

/*
为什么要用指针
*/

//能不能 a(10) 强制保存我要的地址 0060FEF8 java

int main()
{
	int a; //a的地址肯定是随机分配
    a=10;
    
    int *p;
    p=&a;
    
    printf("a的地址是%p\n",p);
    
    int *p2=(int *)0x0060FE00;//int a=10 ARM架构 裸机编程 ARM驱动
    *p2=10;
    
    printf("在内存%p的位置存放的的是数值%d\n",p2,*p2);
    
    //volatile int *p2 = (volatile int *)0x0060FEF8 //类型修饰符
    /*
		volatile 多线程编程
        每次从内存中取数据,而不是寄存器
               ()               (快)
    */
	system("pause");
	return 0;
}

运行结果:

a的地址是0060FEF4
在内存0060FE00的位置存放的的是数值10
请按任意键继续. . .

2.在自定义函数中通过指针形参对主函数数据本身操作。

#include <stdio.h>
#include <stdlib.h>

void jiaJiaA(int a)
{
	a++;
    printf("jiaJiaA里面的值是%d\n",a);
}

void jiaJiaA2(int *p)
{
	*p=*p+1;
    printf("jiaJiaA2里面的值是%d\n",*p);
}

void swap(int *a,int *b)
{
	int temp;
    temp=*a;
    *a=*b;
    *b=temp;
}
int main()
{
	/*
	int a=10;
    
	jiaJiaA(a);		//main中a不变 10
    //jiaJiaA2(&a);	//main中a变化 11
    printf("main函数里面a的值是%d\n",a);
    */
    
    int a=1;
    int b=5;
    
    printf("a and b %d %d\n",a,b);
    swap(&a,&b);
    printf("a and b %d %d\n",a,b);
    
	system("pause");
	return 0;
}

运行结果:

a and b 1 5
a and b 5 1
请按任意键继续. . .

指针数组
能将无关数据组合到一起。

#include <stdio.h>
#include <stdlib.h>
int main()
{
	int a = 1;
    int b = 2;
    int c = 3; //三个毫无关系的整型变量
    
    int array[3]; //多个整数叫整数数组
    
    int* p[3];
    
    //这样来定义指针数组
    int* parray[3]; //多个指针叫指针数组 数组中每一个元素都是指针变量
					//指针变量存放的是地址的变量
    
    
    parray[0] = &a;
    parray[1] = &b;
    parray[2] = &c; //三个普通没有任何关系的 整型变量的地址 存入指针数组
    
    int i;
    
    for(i=0;i<3;i++)
    {
		printf(" %d ",*(parray[i]));
    }
    
    
	system("pause");
	return 0;
}

运行结果:

1 2 3 请按任意键继续. . .

数组指针

#include <stdio.h>
#include <stdlib.h>

//上例讲的是指针数组,多个指针
//本例说的可是“数组指针” 一个指针

int main()
{

	int  a[3]={0,1,2};
    
    
    int (*p)[3];
    p=a;
    
    int *p2;
    p2 = a;
    
    
    printf("数组的地址是%p\n",a);
    printf("数组的地址是%p\n",&a[0]);
    printf("p数组的地址是%p\n",p);
    printf("p2数组的地址是%p\n",p2);//0060FEDC
    
    printf("==================区别=================\n");
    printf("++p的结果是%p\n",++p);  //0060FEE0   ++p 数组指针自加
									//0060FED4  p   首地址
                                           // =12
    /* 二者自加偏移量不同:
    	数组指针偏移整个数组大小的长度
    	普通(指向数组)指针自加偏移一个数组元素大小长度 */
    printf("++p2的结果是%p\n",++p2);//0060FED8  ++p2 普通(指向数组)指针自加
									//0060FED4   p2 首地址
                                            //=4
    //printf()    
    
    												
    int *p3;
    p3=a;
    int i;
    for(i=0;i<3;i++)
    {
		printf(" %d ",*p3++);
    }
	
	system("pause");
	return 0;
}

运行结果:

数组的地址是0060FED4
数组的地址是0060FED4
p数组的地址是0060FED4
p2数组的地址是0060FED4
================== 区别 =================
++p的结果是0060FEE0
++p2的结果是0060FED8
0 1 2 请按任意键继续. . .

函数指针

#include <stdio.h>
#include <stdlib.h>

void printWelcome()
{
	printf("欢迎昌老湿\n");
}

int add(int a,int b)
{
	return a+b;
}


int main()
{
	//1.如何定义一个函数指针
	void (*p)();//1.如何表示指针:*  
				//2.如何知道是函数 
                //3.函数指针是专用的,格式要求很强(参数类型,个数,返回值)就像数组指针一样
    
    //2.如何给函数指针赋值
    p=printWelcome; //函数名就是地址,就像地址一样,数组名就是地址
    
    //3.如何通过函数指针调用函数
    p();//直接通过名字+()
    (*p)();//取内容 (*指针名字)()
    
    
    
    int (*padd)(int a,int b);	//严格按照函数声明原型定义函数指针
    
    padd = add;			//为函数指针赋值
    
    int ret = (*padd)(1,5);	//通过函数指针调用函数
    
    printf(" %d \n",ret);
    
	system("pause");
	return 0;
}

运行结果:

欢迎昌老湿
欢迎昌老湿
6
请按任意键继续. . .

无类型指针 &malloc& 避免内存泄漏

#include <stdio.h>
#include <stdlib.h>
//无类型指针

int main()
{

	int n;
    
    printf("请输入int型数组元素个数\n");
    scanf("%d",&n);
	int *parray = (int*)malloc(n * sizeof(int));//我尼玛是可变长度数组
    
    int i;
    
    for(i=0;i<n;i++)
    {
		printf("请输入第%d个学生的sb分数:\n",i+1);
        scanf("%d",&parray[i]);
    }
    
    for(i=0;i<n;i++)
    {
		printf("第%d个学生的sb分数是:%d\n",(i+1),parray[i]);
    }
	
/*
	避免内存泄漏
    1.程序刚跑起来 很好,跑几个小时,或者几天,或几周 程序崩溃
    while(1)
    {
		sleep(1);
        int *p = malloc(1024);//malloc 申请的空间,程序不会自动释放。linux中的话,程序结束后,系统会自动回收这个空间。
        避免:
			1.注意,循环中有没有一直申请
            2.及时合理释放 free(p); p=NULL;
    }
    
    int *p;野指针
    定义时最好初始化

*/    
	free(parray);
    
	system("pause");
	return 0;
}

运行结果:

请输入int型数组元素个数
5
请输入第1个学生的sb分数:
10
请输入第2个学生的sb分数:
20
请输入第3个学生的sb分数:
30
请输入第4个学生的sb分数:
40
请输入第5个学生的sb分数:
50
第1个学生的sb分数是:10
第2个学生的sb分数是:20
第3个学生的sb分数是:30
第4个学生的sb分数是:40
第5个学生的sb分数是:50
请按任意键继续. . .

指针收官

#include <stdio.h>
#include <stdlib.h>
int main()
{
	int c;    
    int *p;
    int a[5];
    int *pa[4];//指针数组
    int (*pb)[4];//数组指针
    int f();
    
    int *fun();//返回指针的函数
    int (*pf)();//指向函数的指针
    int **pc;
    void *pd;
	
	system("pause");
	return 0;
}

七、字符串

字符串定义初始化
定义字符串四种方式
第一种:char str[5]={‘a’,‘b’,‘c’,‘d’,‘e’};//类比于整数数组
第二种:char str2[5]=“abcde”;
第三种:char str3[]=“aaaaaasdkjhgfdytrv”;//数组原属个数不写,会根据真是大小默认分配
第四种:char *str4=" hello world !!";//指针方式

#include <stdio.h>
#include <stdlib.h>
int main()
{
	//C语言字符串 定义以及初始化
    
	int i;
    int a[3]={0,2,3};
    
    char c;
    
    //定义字符串的第一种方法,和整型数组类似!  傻逼法!!!!
    char str[5]={'a','b','c','d','e'};//类比于整数数组
    for(i=0;i<sizeof(str)/sizeof(str[0]);i++)
    {
		printf(" %c ",str[i]);
    }
    putchar('\n');
    
    //定义字符串的第二种方式:和整型数组类似,没那末傻逼!!!!
    char str2[5]="abcde";
    for(i=0;i<sizeof(str2)/sizeof(str2[0]);i++)
    {
		printf(" %c ",str[i]);
    }
    putchar('\n');
    
    //定义字符串的第三种方式:和整数数组类似没那末傻逼
    char str3[]="aaaaaasdkjhgfdytrv";//数组原属个数不写,会根据真是大小默认分配
    for(i=0;i<sizeof(str3)/sizeof(str3[0]);i++)
    {
		printf(" %c ",str3[i]);
    }
    putchar('\n');
    
    //定义字符串数组的第四种方式:
    //数组名就是地址(大多数情况下)
    char *str4=" hello world !!";//指针方式 如果操作不当 内存非法 易造成段错误sigment error
    printf("%s\n",str4);//字符串用格式占位符%s,不需要用i遍历
    
	puts("");
    puts(str);
    puts(str2);
    puts(str3);
    puts(str4);
	system("pause");
	return 0;
}

运行结果:

 a  b  c  d  e
 a  b  c  d  e
 a  a  a  a  a  a  s  d  k  j  h  g  f  d  y  t  r  v
 hello world !!

abcde
abcdeabcde
aaaaaasdkjhgfdytrv
 hello world !!
请按任意键继续. . .

字符串数组大小

不能使用sizeof计算字符串中有效字符的个数!! 应该要用strlen,她在计算字符串大小时,遇到’\0’就结束计数。sizeof是计算在内存中的字节数

#include <stdio.h>
#include <stdlib.h>
int main()
{

	char a[]="changxiatrui";
    printf("a数组大小%d\n",sizeof(a));
    printf("a数组大小%d\n",strlen(a));//strlen 计算有效字符大小
    
    char *a2="changxianruib";
    printf("a2字符串大小%d\n",sizeof(a2));//计算指针  :(
	printf("a2字符串大小%d\n",strlen(a2));
    
    
    //不能使用sizeof计算字符串中有效字符的个数!! 应该要用strlen,她在家算字符串大小时,遇到'\0'就结束计数
    
    char a3[20]="hello\0jkl";//后面一堆'\0'
    printf("a3数组大小%d\n",sizeof(a3)/sizeof(a3[0]));
    printf("希望得到a3大小%d\n",strlen(a3));
    printf("打印字符串%s\n",a3);
    
	system("pause");
	return 0;
}

运行结果:

a数组大小13
a数组大小12
a2字符串大小4
a2字符串大小13
a3数组大小20
希望得到a3大小5
打印字符串hello
请按任意键继续. . .

字符串常用函数一

#include <stdio.h>
#include <stdlib.h>
int main()
{
	char *str = "而非很快就去";
    /*puts(str);
    printf("%d\n",strlen(str));   // 12 一个汉字占两个字节
    */
    
    //char pstr[128]={'\0'};//1.申请空间 2.初始化 把每个元素都初始化为'\0'
    char *pstr;//野指针 造成非法内存访问,出现段错误 cmd窗口闪退
    pstr=(char *)malloc(128);//1.申请了空间 2.一旦用了malloc,一定要注意内存泄漏的问题, 3.malloc可能会失败,要对返回值做判断
    
    if(pstr == NULL)
    {
		printf("申请内存失败\n");
        exit(-1);
    }
    memset(pstr,'\0',128);//
    //1.pstr 初始化的对象 2.初始化成什么字符 3.多大
    
    printf("请输入字符串\n");
    //scanf("%s",pstr);
    gets(pstr);
    puts(pstr);
    
	system("pause");
	return 0;
}

运行结果:

请输入字符串
c is the best laug
c is the best laug
请按任意键继续. . .

字符串常用函数二

strcpy是一种C语言的标准库函数,strcpy把含有’\0’结束符的字符串复制到另一个地址空间,返回值的类型为char*。

strncpy函数用于将指定长度的字符串复制到字符数组中,是 C语言的库函数之一,来自 C语言标准库,定义于 string.h。语法形式为:char *strncpy(char *dest, const char *src, int n),表示把src所指向的字符串中以src地址开始的前n个字节复制到dest所指的数组中,并返回被复制后的dest。

strcat函数将两个char类型连接。例如:
char d[20]=“Golden”;
char s[20]=“View”;
strcat(d,s);
//打印d
printf(“%s”,d);
输出 d 为 GoldenView (中间无空格)d和s所指内存区域不可以重叠且d必须有足够的空间来容纳s的字符串。
返回指向d的指针。

strcmp函数是string compare(字符串比较)的缩写,用于比较两个字符串并根据比较结果返回整数。基本形式为strcmp(str1,str2),若str1=str2,则返回零;若str1<str2,则返回负数;若str1>str2,则返回正数。

#include <stdio.h>
#include <stdlib.h>
int main()
{

	//char strDest[128] ={'\0'};//第一个 \0 之后全是 \0
    char *strDest;					//01.定义
    strDest=(char *)malloc(128);	//02.申请内存空间
    memset(strDest,'\0',128);		//03.初始化
    
    char *strSrc = " cxr hs";
    
    strcpy(strDest,strSrc);
    printf("复制后的字符串:%s\n",strDest);
   
    /* //字符串拷贝的两种方法
    memset(strDest,'\0',sizeof(strDest)/sizeof(strDest[0]));
    strcpy(strDest,"hello");
    puts(strDest); 		//hello
    
    memset(strDest,'\0',sizeof(strDest)/sizeof(strDest[0]));
    
    char *str = (char *)malloc(10 * sizeof(char));
    memset(str, '\0', 10);
    str=strncpy(strDest,"he llo",5);
    puts(str);
    
    puts(strDest); 		//he ll
	*/
    
    //字符串连接
    char test[128]=" 没毛病 ";
    strcat(strDest,test);
    puts(strDest);
    
    
    //字符串比较
    char *str1="123";
    char *str2="jkl";
    
    int ret = strcmp(str1,str2);
    if(ret == 0)
    {
		printf("一样大小\n");
    }
    else{
		printf("不一样大小\n");
    }
	
	system("pause");
	return 0;
}

运行结果:

复制后的字符串: cxr hs
cxr hs 没毛病
不一样大小
请按任意键继续. . .

字符串常用函数三
strchr函数功能为在一个串中查找给定字符的第一个匹配之处。函数原型为:char *strchr(const char *str, int c),即在参数 str 所指向的字符串中搜索第一次出现字符 c(一个无符号字符)的位置。strchr函数包含在C 标准库 <string.h>中。

strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串。如果是,则该函数返回 str1字符串从 str2第一次出现的位置开始到 str1结尾的字符串;否则,返回NULL。

strlwr函数的功能是将字符串中的S参数转换为小写形式。

strupr,函数的一种,将字符串s转换为大写形式。

strotk函数,分解字符串为一组字符串。s为要分解的字符串,delim为分隔符字符(如果传入字符串,则传入的字符串中每个字符均为分割符)。首次调用时,s指向要分解的字符串,之后再次调用要把s设成NULL。

#include <stdio.h>
#include <stdlib.h>
int main()
{
	
    char *str = "changxianrui";
    char c = 'a';
    char *p = NULL;
    /*
    //查找字符
	p = strchr(str,c);
    if(p==NULL){
		printf("没有找到\n");   
        //puts(p);     
    }
    else{
		printf("找到了 为:");
		puts(p);     //输出后面的字符串 angxianrui
    }
	*/
    
    
    //字符串中查找子串
    /*
    char *zi="xian";
    p=strstr(str,zi);
    if(p==NULL){
		printf("没有字串\n");
    }
    else{
		printf("字串存在\n");
        puts(p);	//xianrui
    }*/
    
    
    
    //字符串大小写转换
    /*
    char v[]="Hello World";
    
    p=strlwr(v);
    puts(p);		// hello world
    puts(strupr(v));// HELLO WORLD
    */
    
    
    //zi字符串分割
    int i = 0 ;
    char *pubs[3];
    char s[]="chang,xian,rui";
    
    p=strtok(s,",");//''既然不行
    if(p!=NULL){
		i++;
		//printf("第%d个子串是%s\n",i,p) ;
        pubs[i-1] = p;
    }
    
    
    while(1){
		p=strtok(NULL,",");
		if(p!=NULL){
			i++;
			//printf("第%d个子串是%s\n",i,p) ;
            pubs[i-1] = p;
		}
        else{
			printf("没有子串了\n");
			break;
        }
    }
    
    int j;
    for(j = 0; j <= i; j++){
		puts(pubs[j]);
    }
    
    
    /*
    if(p!=NULL){
		printf("第一个子串是%s\n",p) ;
    }
    //获取第二个字串的方式很奇葩 跟第一次不一样的是,目标字符串表示为NULL;
    p=strtok(NULL,","); 
    printf("第二个字串是%s\n",p);

	//获取第三个字串的方式很奇葩 跟第一次不一样的是,目标字符串表示为NULL;
    p=strtok(NULL,",");
    printf("第三个字串是%s\n",p); 
	
    //获取第四个字串的方式很奇葩 跟第一次不一样的是,目标字符串表示为NULL;
    p=strtok(NULL,",");
    if(p == NULL){
		printf("没有子串了\n");
    }
    else{
		printf("第四个字串是%s\n",p);    
    }*/

	system("pause");
	return 0;
}

运行结果:

没有子串了
chang
xian
rui
请按任意键继续. . .

八、结构体

结构体

#include <stdio.h>
#include <stdlib.h>


//struct关键字
//1.结构体的定义和使用 @!!!!提醒:新手容易忘记结构体后的;
//2.如何访问结构体: 目标 内部的变量
struct Student//字定义类型
{
	int score;		//特性:分数
    char name[128];	//特性:名字
    //void (*pintroduce)(char *pnme);	//行为:函数指针(自我介绍);

};

int main()
{
	//类型        变量   初始值
	int 			a	=	10;
    struct Student  stu1= {59,"昌显瑞"};
    
    printf("a=%d\n",a);
    printf("结构体中的score=%d\n",stu1.score);
    printf("结构体中的name=%s\n",stu1.name);
    
    putchar('\n');
    
    int b;
    b=10;
	struct Student test;
    test.score=12;
    //test.name="小红";//字符串只能 通过复制
    strcpy(test.name,"小红");
    printf("结构体中的score=%d\n",test.score);
    printf("结构体中的name=%s\n",test.name);
    
    
	system("pause");
	return 0;
}

结构体的定义和使用:

#include <stdio.h>
#include <stdlib.h>

//struct关键字
//1.结构体的定义和使用 @!!!!提醒:新手容易忘记结构体后的;
//2.如何访问结构体: 目标 内部的变量
struct Student//字定义类型
{
	int score;		//特性:分数
    char name[128];	//特性:名字
    //void (*pintroduce)(char *pnme);	//行为:函数指针(自我介绍);

};

int main()
{
	//类型        变量   初始值
	int 			a	=	10;
    struct Student  stu1= {59,"昌老湿"};
    
    printf("a=%d\n",a);
    printf("结构体中的score=%d\n",stu1.score);
    printf("结构体中的name=%s\n",stu1.name);
    
    putchar('\n');
    
    int b;
    b=10;
	struct Student test;
    test.score=12;
    //test.name="小红";//字符串只能 通过复制
    strcpy(test.name,"小红");
    printf("结构体中的score=%d\n",test.score);
    printf("结构体中的name=%s\n",test.name);   
    
	system("pause");
	return 0;
}

运行结果:

a=10
结构体中的score=59
结构体中的name=昌老湿

结构体中的score=12
结构体中的name=小红
请按任意键继续. . .

结构体:旧知识新用法

#include <stdio.h>
#include <stdlib.h>
//jie结构体里面的东西都是熟悉的,外面只是一个框架 旧知识新用法而已

void func(int data)
{
	printf("数据:%d\n",data);
}
struct Student
{
	char *name;
    char sex;
    int age;
    float score;
    char *adress;
    
    void (*peat)();	//函数指针
    void (*itroduce)(char *name,char *adress,int age);
};

int main()
{
    struct Student stu1;
	system("pause");
	return 0;
}

野指针是致命问题

#include <stdio.h>
#include <stdlib.h>

struct Datas	//结构体:不建议这种方式存字符串
{
	char *p;	//必须 malloc
};

struct Test		//结构体:建议这种方式存字符串
{
	char p[128];
};

int main()
{
  
    /*
	struct Datas d;	//指针
    
    strcpy(d.p,"就立刻ncv"); 	//Datas linux下段错误
    puts(d.p);					//程序崩掉 :因为是 野指针 没有内存
    
    */
    
    /*
    struct Test d;	//数组
    
    strcpy(d.p,"就立刻ncv"); 	//
    puts(d.p);					//程序不崩
    */
    	
	struct Datas d;
    d.p=(char *)malloc(128);
    memset(d.p,'\0',128);
    strcpy(d.p, "你好,世界。");
    
	puts(d.p);
    printf("%s\n",d.p);
	
	system("pause");
	return 0;
}

运行结果:

你好,世界。
你好,世界。
请按任意键继续. . .

结构体数组玩成绩

#include <stdio.h>
#include <stdlib.h>

struct Student
{
	int score;
    char *name;
    
};

int main()
{
	int            i;
    struct Student stus[5];
    struct Student maxStu,minStu;
    
    
    for(i=0;i<sizeof(stus)/sizeof(stus[0]);i++){
		printf("请输入第%d个学生的名字\n",i+1);
        stus[i].name = (char *)malloc(128);
        scanf("%s",stus[i].name);
        
		printf("请输入第%d个学生的分数\n",i+1);
        //stus[i].name = (char *)malloc(128);
        scanf("%d",&stus[i].score);
    }
    
    for(i=0;i<sizeof(stus)/sizeof(stus[0]);i++){
		printf("输出第%d个学生的名字和分数",i+1);
		printf("%s:%d\n",stus[i].name,stus[i].score);
    }
    
    maxStu = minStu = stus[0];
    for(i=1;i<sizeof(stus)/sizeof(stus[0]);i++){
    
		if(minStu.score > stus[i].score){
			minStu = stus[i];
        }
        if(maxStu.score < stus[i].score){
			maxStu = stus[i];
        }
		//printf("%s:%d\n",stus[i].name,stus[i].score);
    }
    printf("分数最高的人%s:%d\n",maxStu.name,maxStu.score);
    printf("分数低的人%s:%d\n",minStu.name,minStu.score);
    
	system("pause");
	return 0;
}

运行结果:

请输入第1个学生的名字
one
请输入第1个学生的分数
50
请输入第2个学生的名字
two
请输入第2个学生的分数
60
请输入第3个学生的名字
three
请输入第3个学生的分数
70
请输入第4个学生的名字
four
请输入第4个学生的分数
80
请输入第5个学生的名字
five
请输入第5个学生的分数
90
输出第1个学生的名字和分数one:50
输出第2个学生的名字和分数two:60
输出第3个学生的名字和分数three:70
输出第4个学生的名字和分数four:80
输出第5个学生的名字和分数five:90
分数最高的人five:90
分数低的人one:50
请按任意键继续. . .

结构体指针

#include <stdio.h>
#include <stdlib.h>

struct Student
{
	int score;
    char name[128];
};

int main()
{
	struct Student stu1;
    stu1.score=10;
    strcpy(stu1.name,"zhangsan");
    printf("%s : %d\n",stu1.name,stu1.score);
    
    struct Student *p;//野指针
    p=(struct Student *)malloc(sizeof(struct Student));
	//p.score错		//如果用结构体指针就不能用点运算符来访问结构体中的变量 要用->
    p->score=20;
    strcpy(p->name,"liwu");
    printf("%s : %d\n",p->name,p->score);
    
    
    free(p);/*free()只是将malloc()函数申请的空间释放掉,并不能将指针置空,
				指针的指向还是之前的,并不会改变,所以用指针与NULL比
                较作为循环的结束条件在双链表之中是不适合的,
                会导致死循环的产生。*/
    p=&stu1;
    printf("%s : %d\n",p->name,p->score);
	
    printf("地址:%p\n",p++);	//0060FE68  +  132  =
    printf("之后地址:%p\n",p);  //0060FEEC
	system("pause");
	return 0;
}

运行结果:

zhangsan : 10
liwu : 20
zhangsan : 10
地址:0060FE68
之后地址:0060FEEC
请按任意键继续. . .

结构体指针玩成绩

#include <stdio.h>
#include <stdlib.h>

struct Student
{
	int score;
    char *name;
    
};

int main()
{
	int len;
    int i;
    printf("请输入个数:n=");
    scanf("%d",&len);
    //struct Student stus[3];
    //struct Student *p;
	struct Student *p=(struct Student *)malloc(sizeof(struct Student)*len);
    
    //p=stus;
    
    for(i=0; i<len; i++){
		p->name = (char *)malloc(128);
		printf("请输入第%d个学生的名字\n",i+1);
        scanf("%s",p->name);
        
        printf("请输入第%d个学生的分数\n",i+1);
        scanf("%d",&(p->score));
        
        p++;
    }
    
    p = p-len;
    for(i=0; i<len; i++){
        printf("第%d个学生 %s : %d\n",i+1, p->name, p->score);        
        p++;
    }
  
	system("pause");
	return 0;
}


运行结果:

请输入个数:n=3
请输入第1个学生的名字
one
请输入第1个学生的分数
77
请输入第2个学生的名字
two
请输入第2个学生的分数
88
请输入第3个学生的名字
three
请输入第3个学生的分数
99
第1个学生 one : 77
第2个学生 two : 88
第3个学生 three : 99
请按任意键继续. . .

结构体、指针、函数综合处理学生成绩

#include <stdio.h>
#include <stdlib.h>

struct Student{
	char *name;
    int score;
};

//初始化函数
struct Student *initStudent(int len)
{
	int i;
    printf("开始录入:\n");
    struct Student *p = (struct Student *)malloc(len*sizeof(struct Student));//在队上面开辟空间,函数结束调用不会释放
    for(i=0;i<len;i++){
		
        //memset(p->name,'\0',128);
		printf("请输入第%d个学生姓名:\n",i+1);
        p->name = (char *)malloc(64);
        scanf("%s",p->name);
        printf("请输入第%d个学生分数:\n",i+1);
        scanf("%d",&(p->score));
		p++;
    }
    
    return p-len;
}

void printStu(struct Student *p,int len)
{
	int i;
    
    for(i=0;i<len;i++){
		printf("%s : %d\n",p->name,p->score);
        p++;
    }

}

struct Student *minStu(struct Student *p,int len)
{
	int i=0;
    
    struct Student *min = NULL;
    min=p;
    for(i=0;i<len;i++){
		if(min->score > p->score){
			min=p;
        }
        p++;
    }
	return min;
}

struct Student *maxStu(struct Student *p,int len)
{
	int i=0;
    
    struct Student *max = NULL;
    max=p;
    for(i=0;i<len;i++){
		if(max->score < p->score){
			max=p;
        }
        p++;
    }
	return max;
}
//平均值
float averStu(struct Student *p,int len)
{
	int i=0;
    int sum=0;
    
    for(i=0;i<len;i++){
		sum += p->score;
        p++;
    }
    
    return (float)sum/len;
}

int findStudnet(struct Student *p,int len,char *name)
{
	int i=0;
    
    for(i=0;i<len;i++){
		if(strcmp(p->name,name)==1){
			return 1;
        }
        p++;
    }
    return -1;
}

int main()
{
	int len=0;
    printf("请输入录入学生个数");
    scanf("%d",&len);
	//长度输入
    
    struct Student *pstus=NULL;
    struct Student *min=NULL;
    struct Student *max=NULL;
    float aver=0;
    
    //初始化
    pstus = initStudent(len);
    
    //输出
    printStu(pstus,len);
    
    //找最大最小值
    min=minStu(pstus,len);
    max=maxStu(pstus,len);
    
    //平均值
	aver=averStu(pstus,len);
    
    //输出
    printf("min %s : %d\nmax %s : %d\naver : %f\n",min->name,min->score,max->name,max->score,aver);
	
	if(findStudnet(pstus,len,"zhangsan") == 1){
		printf("找到\n");
    }else{
		printf("没找到\n");
    }
    
	system("pause");
	return 0;
}

运行结果:

请输入录入学生个数3
开始录入:
请输入第1个学生姓名:
one
请输入第1个学生分数:
100
请输入第2个学生姓名:
two
请输入第2个学生分数:
50
请输入第3个学生姓名:
there
请输入第3个学生分数:
30
one : 100
two : 50
there : 30
min there : 30
max one : 100
aver : 60.000000
没找到
请按任意键继续. . .

typedef关键字

#include <stdio.h>
#include <stdlib.h>
/*
	typedef 重命名
    作用:为一种数据类型定义一个新的名字
    这里的数据类型包括内部数据类型(int,char等)和自定义数据类型(struct等)
    
    和struct来匹配伪类代码编写简洁
    和普通类型匹配,通过名字来获取一些信息
*/

//在单片机开发中,寄存器有8位 16位 32位

typedef unsigned char u_int8; //(0,255)
typedef unsigned short int u_int16;
typedef unsigned int u_int32;


//typedef struct Student STU,*PSTU;不建议

typedef struct Student{
	char *name;
    int score;
    void (*p)(struct Student *);	//结构体里面最好不用STU
}STU,*PSTU;

int main()
{
	PSTU p=NULL;
    //STU p;
    p=(PSTU)malloc(sizeof(STU));
    p->score=99;
    printf("分数:%d\n",p->score);    
    
    
    u_int8 data=10;
    unsigned short int data2=20;
    u_int32 data3=30;
    printf("%d %d %d \n",data,data2,data3);
	
	system("pause");
	return 0;
}

运行结果:

分数:99
10 20 30
请按任意键继续. . .

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 闫学灿老师的蓝桥杯C语言课程笔记是一份非常实用和全面的学习资料。在这份笔记中,他以蓝桥杯C语言竞赛为出发点,系统地介绍了C语言的基本知识、编程技巧和解题思路。 首先,这份笔记C语言的基础知识进行了详细的讲解。从数据类型、运算符、控制结构、数组函数,每个知识点都有清晰的定义和示例。这使得初学者能够迅速上手,了解C语言的基本特性和语法规则。 其次,笔记中还涉及了各种常用的C语言编程技巧。比如,如何进行输入输出、如何进行字符串处理、如何进行文件操作等等。这些技巧是实际编程中经常用到的,通过学习这些技巧,可以提高编程效率和代码质量。 另外,在笔记的后半部分,闫学灿老师还分享了他在蓝桥杯C语言竞赛中的解题思路和经验。这对于想要参加蓝桥杯的学生来说,无疑是非常有价值的。他详细讲解了一些比较经典的题目,以及如何从题目中找到思路和解决方案。 总的来说,闫学灿老师的蓝桥杯C语言课程笔记是一份非常实用和全面的学习资料。不仅适合蓝桥杯竞赛的学生,也适合其他对C语言感兴趣的学习者。通过学习这份笔记,可以提高自己的C语言编程能力,并为今后的编程学习和工作打下坚实的基础。 ### 回答2: 闫学灿是一位知名的编程教育家,他在蓝桥杯和C语言方面有着丰富的教学经验和深厚的专业知识。他的课程笔记以蓝桥杯C语言题目为主线,介绍了C语言的基础知识、高级应用以及解题技巧等内容。 在蓝桥杯C语言竞赛中,学生们通常需要使用C语言编写程序来解决一系列问题。闫学灿的课程笔记通过对大量题目的剖析和解析,帮助学生理解问题的本质,掌握解题的思路和方法。他的讲解通俗易懂,注重实例演示,让学生能够更好地理解和掌握。 课程笔记中,闫学灿详细介绍了C语言的基础语法、控制结构、数组指针等重要知识点,并通过大量编程实例来巩固学生的学习成果。他注重培养学生的实际动手能力,通过编程实践来提高学生的编程水平和解题能力。 此外,闫学灿的课程笔记还包括了一些高级应用,如字符串处理、递归、动态内存分配等,以及一些重要的算法和数据结构,如排序、查找等。通过这些内容的学习,学生可以更全面地掌握C语言的使用和应用。 总的来说,闫学灿的蓝桥杯C语言课程笔记全面系统地介绍了C语言的基础知识和应用技巧,通过丰富的编程实例和解题思路的讲解,帮助学生在蓝桥杯竞赛中取得更好的成绩,并提高他们的编程水平和解决问题的能力。这样的课程材料对于C语言爱好者和想要参加蓝桥杯竞赛的学生来说都是非常有价值的参考资料。 ### 回答3: 蓝桥杯C语言是由蓝桥杯组织举办的一项程序设计竞赛。参赛者需要使用C语言编写程序解决一系列算法和编程题目。 闫学灿(Y总)是一位知名程序员,他开设了一系列C语言课程笔记,内容丰富全面,对于初学者和有一定基础的编程爱好者都非常有帮助。 在闫学灿的C语言课程笔记中,他详细讲解了C语言的基础知识,包括变量、数据类型、运算符、流程控制等等。他还介绍了C语言的一些特性和编程技巧,例如指针结构体、文件操作等。通过学习这些内容,可以帮助我们更好地理解和运用C语言。 闫学灿的C语言课程笔记还包了许多实例和练习题,通过实践的方式帮助我们巩固所学的知识。他还提供了一些实际项目的源码和解决方案,让我们可以实际操作和应用所学的知识。 总的来说,蓝桥杯C语言闫学灿(Y总课程笔记)是一门非常优秀的课程,对于想要学习C语言并参加蓝桥杯竞赛的学生来说是很好的学习资料。通过学习这门课程,我们可以系统地学习和掌握C语言的知识,并通过实践提高我们的编程能力和解决问题的能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值