C 语言特点
1.结构化的程序设计语言:层次清晰,便于按模块化方式组织程序,易于调试和维护
2.语句简洁:学习时入门相对容易,C 语言很好地总结了其他语言提出的程序库概念
3.功能强大:既可用于系统软件的开发,也适合于应用软件的开发。
4.移植性好:只要对这种语言稍加修改,便可以适应不同型号机器或各类操作系统。
C 程序的基本结构
#include <stdio.h>
void main()
{
printf("Hello World\n");
}
C 程序结构特点
? 函数与主函数
– 程序由一个或多个函数组成
– 必须有且只能有一个主函数main()
– 程序执行从main开始,在main中结束,其它函数通过嵌套
调用得以执行。
? 程序语句
– C程序由语句组成
– 用“;”作为语句终止符
? 注释
– //表示单行注释
– /* */为注释,不能嵌套
– 不产生编译代码
编译和执行C程序
C 源程序----编译----目标文件----连接----可执行文件-----可执行程序
源程序:是用户创建的文件,以“.c”为文件扩展名保存
目标文件:是编译器的输出结果。这类文件的常见扩展名为“.o”或“.obj”
头文件:含有函数的声明和预处理语句,用于帮助访问外部定义的函数。头文件的扩展名为“.h”。
可执行文件:是连接器的输出结果。可执行文件的扩展名为“.exe”。
C程序的开发过程
分析问题-----编制程序----编译----连接----调试运行---完成
流程图
----起止框
---输入输出框 ------判断框 -----处理框
或
----流程图
-----连接点
----注释框
? C语言的特点包括:结构化的程序设计语言、语句简洁、功能强大、移植性好
? C程序的基本结构包括:预处理语句、main函数,main函数中的内容使用{ }括起来,
每条语句必须用分号结束
? C程序编写完成后,首先需通过编译转换成目标文件,再通过连接创建可执行程序,
最后才可执行该程序
? 算法是程序执行的步骤,可以用伪代码与流程图表示
?
常量是在程序中保持不变的量
常量用于定义具有如下特点的数据:
? 在程序中保持不变
? 在程序内部频繁使用
? 需要用比较简单的方式替代某些值
变量在程序运行过程中,其值可以被改变的量
定义变量
1.数据类型 标识符名; 例:int x;
2.数据类型 标识符名=值; 例:int x=50;
注:定义一个变量的深层的意思:是在内存空间开辟空间;如果不进行初始化时,这个变量的存储的数据是一个未知的;
常量:
1.把一个变量变成一个常量
const 数据类型 标识符名=值; 例:const float PI=3.14;
2.用宏命令
#define 标识符名 值 例:#define PI 3.14 注:没有分号,没有=
区别:第一种,分配内存空间 第二种是在预编译的时,进行替换操作
定义两个变量 int i ,j:
要求:给 i赋值为 5 ,给j赋值为i乘以6,打印输出i与j的值
#include <stdio.h>
main()
{
int i, j;
i=5;
j=i*6;
printf("i= %d\n",i);
printf("j = i*6 = %d\n",j);
}
变量的命名规则:
– 变量名可以由字母、数字和 _(下划线)组合而成
– 变量名不能包含除 _ 以外的任何特殊字符,如:%、# 、逗号、空格等 – 变量名必须以字母或 _(下划线)开头
– 变量名不能包含空白字符(换行符、空格和制表符称为空白字符)
– C 语言中的某些词(例如 double 和 float 等)称为保留字,具有特殊意义,
不能用作变量名
– C 语言区分大小写,因此变量 price 与变量 PRICE 是两个不同的变量 数据类型:
整型 int 32位
浮点型 float 32位 double 64位
字符型 char 8位
ASCII码--ASCII码中,小写字母的范围是:97~122 大些字母范围是65~90;小写字母得到相应大写字母需要-32;
编写程序:1. 打印出字母 a 的ASCII号
2. 将字母a转化为字母A
#include "stdio.h"
main()
{
char i ='a';
int j = i-32 ;
printf("%c",j);
}
表达式的定义
? 表达式由操作数和运算符的组合而成
? 表达式中的操作数可以是字母、数字或者下划线
? 运算符的主要类型有:
算术运算符 + - * / % ++ --
重点:/ 整型是除数取整, % 除模取余 ++ --前置与后置运算
赋值运算符 = += -= *= /= %= 要求左边必须是一个变量
例:
sum=sum+s;
sum+=s
关系运算符 > < >= <= == !=
? 在C语言中,“0”表示“假”,“非0”表示“真”
逻辑运算符
&& || ! 是连接一个或多个关系运算和逻辑运算的表达式
10<x<20 错误
10<x && x<20 对
短路与,短路或
例: int s=10,i=1;
s==9 && i++;
s==10 || i++;
使用&&运算符
#include <stdio.h>
void main()
{
float rate1,rate2,rate3;
double discount,total;
printf("\n请输入第一种商品的价格:");
scanf("%f",&rate1);
printf("\n请输入第二种商品的价格:");
scanf("%f",&rate2);
printf("\n请输入第三种商品的价格:");
scanf("%f",&rate3);
total=rate1+rate2+rate3;
if((rate1>50)||(rate2>50)||(rate3>50)||(total>100)) {
discount=0.15*total;
total=total-discount;
printf("\n折后总价为:%6.2f\n",total);
}
else
printf("\n总价为:%6.2f\n",total);
}
使用 ! 运算符
#include <stdio.h>
void main()
{
int num;
printf("\n 请输入一个数:");
scanf("%d",&num);
if ( !(num %5) )
printf("\n 该数能被 5 整除 \n ");
else
printf("\n 该数不能被 5 整除 \n ");
}
打印出书籍的价格并且将数据的价格增加12.5后也打印输出
#include <stdio.h>
void main ()
{
float book_price = 60.75;
printf("\n 书的价格 = %f",book_price);
book_price += 12.50;
printf("\n 书的新价格 =%f\n",book_price);
}
【int j=7,q,a=2;
q=a+++j;
printf("%d",q);】
? 贪心法则 :
– 每一个符号应该包含尽可能多的字符.也就是说,编译器将程序分解成符号的
方法是:从左到右一个一个字符地读入,如果此字符可能组成一个符号,那么再读入下 一个字符,判断已经读入的两上字符组成的字符组成的字符串是否可能是一个符号的组成部分,如果可能,继续读入下一个字符,重复上述判断,直到读入的字符组 成的字符串已不再可能组成一个有意义的符号.这个处理的策略被称为"贪心法".
运算符优先级
() 从左至右
! ++ -- sizeof
*% /
+ -
< <= > >=
== !=
&&
||
= += *= /= %= -=
【
#include <stdio.h>
void main()
{
int year;
printf("\n 请输入年份:");
scanf("%d",&year);
if((year % 4 ==0 && year % 100 != 0) || (year % 400 == 0))
printf("\n %d 年是闰年 \n ", year);
else
printf("\n %d 年不是闰年 \n ", year);
}
】
【
#include <stdio.h>
void main()
{
long ge,shi,qian,wan,x;
printf("\n 请输入一个五位整数:");
scanf("%ld",&x);
wan=x/10000; //分解出万位数
qian=x%10000/1000; //分解出千位数
shi=x%100/10; //分解出十位数
ge=x%10; //分解出个位数
if (ge==wan && shi==qian) /*个位等于万位并且十位等于千位*/ printf("\n 这个数是回文数\n");
else
printf("\n 这个数不是回文数\n");
}
】
输出输入
格式化输出printf()
1.printf("hehehehhe");
2.printf("%d",i);
3.printf("%d%d",x,y);
4.printf("x=%d y=%d",x,y);
格式化输入scanf()
scanf("%d",&x);
scanf("%d%d",&x,&y);
scanf("%d%d%d",&x,&y,&z);
注:scanf语句格式化字符串,尽量不要使用除%d,%f,%s,%c以后字符
%2d %2f %2.2f
针对单个字符的输入输出
字符的输入 getchar()
例:char ch;
ch=getchar();
字符的输出putchar()
char ch='a';
putchar(ch);
%s字符串的输入
%7.2d输出宽度为7和小数点后的两位数【宽度,表示所有的数字和小数点所占的位数。不够7位右对齐。】
Float默认是精确到6位小数
? 题目:
– 请输入圆柱体底面积的半径和圆柱体的高,并且计算圆柱体的体积。 #include <stdio.h>
void main()
{
double radius,high,vol;
printf("请输入圆柱体底面积的半径和圆柱体的高: ");
scanf("%lf%lf",&radius,&high);
vol=3.14*radius*radius*high;
printf("radius=%7.2f, high=%7.2f, vol=%7.2f\n",
radius,high,vol);
}
getchar()和putchar()示例
#include <stdio.h>
void main()
{
char a,b;
printf(" 请输入两个字符:\n");
a=getchar();
fflush(stdin);
b=getchar();
fflush(stdin);
putchar(a);
putchar(b);
putchar('\n');
}
选择结构
? 条件结构就是需要根据不同条件进行判断,然后执行不同的操作 单分支
if (条件表达式)
{
当条件表达式为真,才执行这里的语句;
}
# include <stdio.h>
void main()
{
int num1, num2, sum;
printf("\n请输入两个数:");
scanf("%d %d", &num1,&num2);
sum = num1+ num2 ;
if(sum > 100)
printf("\n两数的和大于 100 \n "); }
双分支
if (条件表达式)
{
当条件表达式为真,才执行这里的语句; }
else
{
当条件表达式为假时,才执行这里的语句; }
【三元运算符
A=x>y?x:y; 条件为真还回x 条件为假还回y #include <stdio.h>
void main()
{
int num;
printf("\n请输入一个整数:");
scanf ("%d",&num);
if(!(num % 2) )
printf("%d 是一个偶数。\n",num); else
printf("%d 是一个奇数。\n",num); }
多分支
嵌套
#include<stdio.h>
void main()
{
int a,b;
printf("\n 请输入 A 和 B 的值: ");
scanf("%d%d",&a,&b);
if(a!=b)
if(a>b)
printf("\n A>B\n");
else
printf("\n A<B\n");
else
printf("\n A=B\n");
}
问题描述:
编写一个程序,根据用户输入的期末考试成绩,输出相应的成绩评定信息。成绩大于等于90分输出“优”;成绩大于等于80分小于90分输出“良”;成绩大于等于60分小于80分输出“中”;成绩小于60分输出“差”。
#include <stdio.h>
void main()
{
float grade;
printf("\n 请输入期末考试成绩: "); scanf("%f", &grade); if(grade>=90) printf("\n 优"); else if ((grade>=80) && (grade<90)) printf("\n 良"); else if ((grade>=60) && (grade<80)) printf("\n 中"); else
printf("\n 差");
printf("\n");
}
注:格式,大括号
C语言规定,每个 else 部分总属于前面最近的那个缺少对应的 else 部分的 if 语句。 提倡使用大括号括起来以避免看起来有二义性。
switch(结果为整型或字符型的表达式)
{
case 常量值1 :
语句;
break;
case 常量值2 :
语句;
break;
………………….
default:
语句;
break;
}
? 在使用switch结构时应注意以下几点:
– 在case后的各常量表达式的值不能相同,否则会出现错误;
– 在case后,允许有多个语句,可以不用{}括起来;
– 每个case 语句的结尾绝对不要忘了加break,否则将导致多个分支重叠(除
非有意使多个分支重叠)
– 各case和default子句的先后顺序可以变动,而不会影响程序执行结果;
– default子句可以省略;
问题描述:
要求用户输入一个字符值并检查它是否为元音字母。
char in_char;
printf("\n 请输入一个小写字母: ");
scanf("%c", &in_char);
switch(in_char)
{
case 'a': printf("\n 您输入的是元音字母 a\n");
break;
case 'e': printf("\n 您输入的是元音字母 e\n");
break;
case 'i': printf("\n 您输入的是元音字母 i\n");
break;
case 'o': printf("\n 您输入的是元音字母 o\n");
break;
case 'u': printf("\n 您输入的是元音字母 u\n");
break;
default: printf("\n 您输入的不是元音字母 \n");
}
问题描述:
要求判别键盘输入字符的类别。可以根据输入字符的ASCII码来判别类型。由ASCII码表可知ASCII码值小于32的为控制字符。 在0~9之间的为数字,在A~Z之间为大写字母, 在a~z之间为小写字母,其余则为其它字符。
void main()
{
char c;
printf("\n 请输入一个字符: ");
c=getchar();
if(c<32)
printf("\n 该字符是一个控制字符。\n");
else if(c>='0'&&c<='9')
printf("\n 该字符是一个数字。\n");
else if(c>='A'&&c<='Z')
printf("\n 该字符是一个大写字母。\n");
else if(c>='a'&&c<='z')
printf("\n 该字符是一个小写字母。\n");
else
printf("\n 该字符是其他字符。\n");
}
问题描述:
编写一个简单的计算器,实现两个整型数的四则运算。
int a,b; char op;
printf("\n 输入操作数1,运算符,操作数2: ");
scanf("%d,%c,%d",&a,&op,&b);
switch(op)
{
case '+': printf("\n %d+%d=%d\n",a,b,a+b);
break;
case '-': printf("\n %d-%d=%d\n",a,b,a-b);
break;
case '*': printf("\n %d×%d=%d\n",a,b,a*b);
break;
case '/': printf("\n %d/%d=%d\n",a,b,a/b);
break;
default: printf("\n 运算符错误!");
}
循环
初始化语句;
while (循环条件)
{
循环语句;
步长语句;
}
初始化语句;
do
{
循环语句;
步长语句;
}while(循环条件);
问题描述:
猜数游戏。要求猜一个介于1~10之间的数字,根据用户猜测的数与标准值进行对比,并给出提示,以便下次猜测能接近标准值,直到猜中为止。
int number=5,guess;
printf ("猜一个介于 1 与 10 之间的数\n");
do
{
printf("请输入您猜测的数:");
scanf("%d",&guess);
if (guess > number)
printf("太大\n");
else if (guess < number)
printf("太小\n");
} while (guess != number);
printf("您猜中了! 答案为 %d\n",number);
for(初始化;循环条件;步长)
{
循环语句;
}
#include <stdio.h>
void main()
{
int number,count,factorial=1;
printf("\n 请输入任意一个正整数:");
scanf("%d",&number);
for(count = 1; count <=number; count++)
factorial=factorial*count;
printf("\n %d的阶乘 = %d\n",number,factorial);
}
三大循环的区别:while是先判断,后执行;do while是执行后判断;while有可能一次也不执行,do while至少执行一次;for是常用在能确定循环次数时;遍历输出
重点:三大循环执行的步骤
break; //终止当前的整个循环
break语句
? 1~10之间的整数相加,得到累加值大于20时,跳出循环。
1、使用循环进行累加,从1到10
2、判断累加值是否大于20
3、如果大于20,则跳出循环,并打印当前值
//定义一个变量,进行累加
int sum=0,i;
for(i=1;i<=10;i++)
{
sum=sum+i;
if( sum > 20 )
{
printf("当前数是:%d“,i);
break;
}
}
continue;//终止本次循环,继续执行下一次循环
continue :只能用在循环里
continue 作用:跳过循环体中剩余的语句而执行下一次循环
求1~10之间的所有偶数和
1、使用循环进行累加,循环的范围是从1至10
2 、判断当前数是否为偶数
3 、如果为奇数跳过,执行下一个循环,如果为偶数,进行累加 int sum=0; //定义一个变量,进行累加
for(int i=1;i<=10;i++)
{
if( i % 2 == 1)
{
continue;
//如果i为奇数,结束本次循环,进行下一次循环
}
sum=sum+i;
}
printf("1--10之间的偶数和是:%d\n",sum);
? 找出1~50之间不能被3整除的数作为圆半径,计算其面积,当面积超过2000则终止,并将符合要求的圆半径及其面积输出。
#include "stdio.h"
#define PI 3.14
void main()
{
int r;
double area=0;
printf("半径 面积\n");
for (r=1;r<=50;r++) while(r++<50)
{
if (r%3==0)
{
continue;
}
else
{
area=PI*r*r;
if (area>2000)
{
break;
}
}
printf("%2d\t%.2f\n",r,area);
}
}
? for循环来实现上述的任务要求,源程序代码如下所示:
#include "stdio.h"
#define PI 3.14
void main()
{
int r;
double area=0;
r=0;
printf("半径 面积\n");
while(r++<50)
{
if (r%3==0)
{
continue;
}
else
{
area=PI*r*r;
if (area>2000)
{
break;
}
}
printf("%2d\t%.2f\n",r,area);
}
}
#include "stdio.h"
#define PI 3.14
void main()
{
int r;
double area=0;
r=0;
printf("半径 面积\n");
do
{
if (r%3==0)
{
continue;
}
else
{
area=PI*r*r;
if (area>2000)
{
break;
}
}
printf("%2d\t%.2f\n",r,area);
}while(r++<50);
}
数组是由多个类型相同、内容相关的一组 变量 组成的基本结构。 ? 初始化情况:
? int arr[10] = {10,9,8,7,6,5,4,3,2,1,0}; //错误!越界了 ? int arr[10] = {9,8,7,5}; //正确,后面的6个元素未初始化 ? int arr[] = {9,8,7}; //正确:元素个数为 3
? int arr[]={}; //错误,到底是几个元素?
数组是可以在内存中连续存储多个元素的结构
数组中的所有的量必须属于相同的数据类型,每一个量叫做元素 一维数组1
利用数组求出所购买的5个商品的总计花费
第一步: 定义数组
第二步: 赋值数组
第三步: 取出数值
第四步: 计算总值
# include <stdio.h>
void main()
{
int i;
float item_rate[5],total=0;
printf("\n 请输入商品价格:");
for(i=0;i<5;i++)
{
scanf("%f",&item_rate[i]);
total=total+item_rate[i];
}
printf(“\n 所有商品的合计费用:%f\n ",total); }
问题描述:
求一组数中的最大值和最小值 。
void main()
{
int num[5],max,min,i;
printf("请输入5个数:\n");
for(i=0;i<5;i++)
scanf("%d",&num[i]);
max=num[0];
min=num[0];
for(i=1;i<5;i++)
{
if (max<num[i])
max=num[i];
if (min>num[i])
min=num[i];
}
printf("\n最大值为:%d",max);
printf("\n最小值为:%d\n",min);
}
字符串与字符数组
? 在C语言中没有专门的字符串变量,通常用一个字符数组来存放一个字符串。
? 字符数组和字符串的区别是:字符串的末尾有一个空字符 ‘\0’。 ? 字符串可按如下方式声明并初始化:
char name[15]={ 'W', 'a', 'n', 'g', 'L', 'i', '\0'};手工加入一个空字符
char name[15] = "WangLi";系统将自动加入一个空字符
char password[] = "12345678";省略数组大小,系统自动计算,大小为后面的字符总数加1,最后一个元素存入一个空字符。
用%s按字符串输入与输出。
char str[10];
scanf(" %s ",str);
printf(" %s ",str);
使用 scanf 时,不能输入空格
用字符串输入与输出函数。
char str[10];
gets(str);使用 gets函数允许输入空格
puts(str);
从键盘上读入一个完整的行,存入字符数组name。并用空字符'\0'取代行尾的换行符'\n'。
案例
输入预编译的头文件命令,定义符号常量N,并编写主函数main()。
#include <stdio.h>
#include <string.h>
#define N 5
void main()
{}
定义变量,定义字符型一维数组temp[20]和二维数组city[N][20]。
int i,j;
char city[N][20],temp[20];
利用循环输入5个城市名的字符串,保存到字符数组中。 printf("\n请输入城市名:\n"); for(i=0;i<N;i++) { printf(" %d: ",i+1); gets(city[i]); } 对5个城市名的字符串进行冒泡排序。这里使用了字符串处理函数。 for(i=0;i<N-1;i++) { for(j=0;j<N-1-i;j++) { if(strcmp(city[j],city[j+1])>0) { strcpy(temp,city[j]); strcpy(city[j],city[j+1]);
strcpy(city[j+1],temp);
}
}
}
输出排好序的5个城市名。
printf("\n排序后的城市为:\n");
for(i=0;i<N;i++)
{
printf(" %d: ",i+1);
puts(city[i]);
}
int i,j,student[3][2];
for(i = 0;i < 3;i++)
{
printf("\n 输入学号 %d 两个学期的成绩:",i+1); for(j = 0;j < 2;j++)
scanf("%d",&student[i][j]);
}
printf("\n 学员的学号及其两个学期的成绩为:\n "); printf("\n \t学号\t第一学期\t第二学期");
for(i = 0;i < 3;i++)
{
printf("\n\t");
printf("%d\t",i+1);
for(j = 0;j < 2;j++)
printf("%d\t\t",student[i][j]);
printf("\n ");
}
1、问题描述:
输入10个数,保存在一个数组中,在数组中查找某个数,给出是否找到的信息。如果找到了,要求输出该数在数组中所处的位置;如果找不到,输出“没有找到!”。
#define N 10
for(i=0;i<N;i++)
scanf("%d",&num[i]);
printf("\n 请输入要查找的数:");
scanf("%d",&search);
for (i=0;i<N;i++)
{
if (num[i]==search)
break;
}
if(i<N)
printf("\n 在数组的第 %d 个位置找到了数字 %d !\n",i+1,search);
else
printf("\n 没有找到!\n");
2、问题描述:
编写C程序实现冒泡排序算法,按照降序排列一组数。
#define N 5
int grade[N],temp;
for(i=0;i<N;i++)
scanf("%d",&grade[i]);
for(i=0;i<N;i++)
{
for(j=0;j<N-i-1; j++)
{
if(grade[j] < grade[j+1])
{
temp = grade[j+1]; grade[j+1] = grade[j]; grade[j] = temp; }
}
}
3、问题描述:
如果一个数组中保存的元素是有序的(由大到小),向这个数组中插入一个数,使得插入后的数组元素依然保持有序。
#define N 5
……
int num[N+1]={23,45,60,67,88},in,i;
printf("\n 请输入一个要插入的数:");
scanf("%d",&in);
for(i=0;i<N;i++)
{
if(num[i]>in)
break;
}
for(j=N;j>i;j--)
num[j]=num[j-1];
num[i]=in;
printf("\n 插入后的数组元素:\n");
for(i=0;i<N+1;i++)
printf("%d ",num[i]);
printf("\n");
……
函数
函数的结构包括:返回值类型、函数名、参数列表、函数体
1、C语言的函数:
? C语言的函数是子程序的总称,包括函数和过程。(有返回值、无返回值,有的教材中称为:有返回值函数,无返回值函数)。
? C语言函数可以分为库函数、用户自定义函数。库函数由系统提供,程序员只需要使用(调用),用户自定义函数需要程序员自己编制。
2、C语言的程序由函数组成,函数是C语言程序的基本单位。
#include<stdio.h>
void AreaOfRect(); 函数原型
void AreaOfTriangle();
void AreaOfRound();
void main()
{
int select;
do {
printf(" 0、退出\n 1、长方形\n 2、三角形\n 3、圆形\n");
printf("请选择功能:");
scanf("%d",&select);
if(select == 0) break;
switch(select) {
case 1 : AreaOfRect(); break; //长方形
case 2 : AreaOfTriangle(); break; //三角形
case 3 : AreaOfRound(); break; //圆形
default : printf("输入有误,请在 0~4 之间选择。\n"); }
}while(1);
void AreaOfRect()
{
int x,y;
printf("请输入长方形的长:");
scanf("%d",&x);
printf("请输入长方形的宽:");
scanf("%d",&y);
printf("面积为:%d\n",(x * y));
}
oid AreaOfTriangle()
{
int x,y;
printf("请输入三角形的底:");
scanf("%d",&x);
printf("请输入三角形的高:");
scanf("%d",&y);
printf("面积为:%d\n",(x * y)/2);
}
void AreaOfRound()
{
int r;
printf("请输入圆形的半径:");
scanf("%d",&r);
printf("面积为:%d\n",3.14*r*r);
}
}
函数返回值
? C语言中的函数至多可以返回一个值,不能返回多个值;
? 返回值的数据类型必须与函数原型中返回值的数据类型匹配;
? 当遇到 return 语句时,函数执行将终止。程序控制流将立即返回调用函数 什么是变量的作用域
? 局部变量:不能在函数外使用
? 全局变量:可以在整个程序中使用
怎么使用变量的作用域
1、 #include <stdio.h>
void addNumbers()
{
int num1,num2,sum;
printf("\n 请输入两个数:");
scanf("%d %d",&num1,&num2);
sum=num1+num2;
printf(" 子函数中 sum 的值是 %d \n",sum);
}
void main()
{
int sum=0;
addNumbers();
printf("\n 主函数中 sum 的值是 %d \n ",sum);
}
请输入两个数:56 45
子函数中sum的值是101
主函数中sum的值是 0
2、#include <stdio.h>
int sum=0;
void addNumbers()
{
int num1,num2;
printf("\n 请输入两个数:");
scanf("%d %d",&num1,&num2);
sum=num1+num2;
printf(" 子函数中 sum 的值是 %d \n",sum);
}
void main()
{
addNumbers();
printf("\n 主函数中 sum 的值是 %d \n ",sum);
}
请输入两个数:56 45
子函数中sum的值是101
主函数中sum的值是101
采用传值调用方式时,在被调用函数中改变形参的值,只是改变其副本值,而不会影响调用函数中实参值
采用引用调用方式时,传递的是变量的地址值,这样在被调函数中,对形参的操作实际上操作的是实参本身
值传递 传递的是一份拷贝
例:int a=10,b=20;
fun(a,b);
引用传递 传递的是一个地址
例: int s[5]={1,2,4,5};
fun(s);
传值调用示例 值不变
#include <stdio.h>
void increment(int,int);
void main()
{
int num1,num2; printf("\n 请输入两个数: "); scanf(" %d %d",&num1,&num2); printf("\n 递增前的值是 %d 和 %d\n", num1, num2); increment(num1,num2);
printf("\n 递增后的值是 %d 和 %d\n", num1, num2); }
void increment(int val1,int val2)
{
val1++;
val2++;
printf("\n 子函数中值 %d 和 %d\n", val1, val2);
}
地址传递 值改变
#include <stdio.h>
void increment(int*, int*);
void main()
{
int num1,num2;
printf("\n 请输入两个数: ");
scanf(" %d %d",&num1,&num2);
printf("\n 递增前的值是 %d 和 %d\n",num1,num2);
increment(&num1,&num2);
printf("\n 递增后的值是 %d 和 %d\n", num1, num2); }
void increment(int *ptr1, int *ptr2)
{
(*ptr1)++;
(*ptr2)++;
printf("\n 子函数中值 %d 和 %d\n", *ptr1, *ptr2);
}
问题:输入三人年龄 使用自定义函数得到输入数字,求出最大值 并且输出出来 #include <stdio.h>
int get_age();
void main()
{
int age1, age2, age3;
age1 = get_age();
age2 = get_age();
age3 = get_age();
if ( (age1 > age2) && (age1 > age3))
printf("\n年龄为 %d 的人最大\n", age1);
else if( (age2 > age1) && (age2 > age3))
printf("\n年龄为 %d 的人最大\n", age2);
else if( (age3 > age1) && (age3 > age2))
printf("\n年龄为 %d 的人最大\n", age2);
}
C语言 指针
指针变量是存放地址的变量( 通常指针变量占用2字节或4字节存储单元,可能随计算机系统不同而异)
指针常常用于数组操作,因为指针运算常常比数组下标运算更快。
数据类型 *指针名;int *p;
p =NULL;值为NULL的指针称为空指针,这意味着,指针并不指向任何地址。 在头文件 stdio.h 中,NULL 定义为常量。
char ch *p;取地址符
ch=‘A’;
p = &ch;
char ch *p;
p = &ch;
*p=‘B’; 间接运算符
若指针已声明为指向某种类型数据的地址,则它不能用于存储其他类型数据的地址 应为指针指定一个地址后,才能在语句中使用指针
#include <stdio.h>
void main()
{
int var = 10;
int *ptr_var;
ptr_var = &var;
printf(" var 的值是: %d", var);
printf("\n var 的内存地址是: %x", &var);
printf("\n 指针 ptr_var 的地址是: %x\n", &ptr_var);
printf("\n var 的值是: %d", *ptr_var);
printf("\n var 的地址是: %x\n", ptr_var);
}
void main()
{
int num1 = 50, num2 = 100;
int *ptr1, *ptr2;
ptr1 = &num1;
printf(" num1 的值是: %d", *ptr1);
printf("\n num1 的地址是: %x \n", ptr1);
ptr2 = &num2;
printf("\n num2 的值是: %d", *ptr2);
printf("\n num2 的地址是: %x \n", ptr2);
*ptr2 = *ptr1;
printf("\n 重新赋值后 num2 的值是: %d", *ptr2);
printf("\n 重新赋值后 num2 的地址是: %x\n", ptr2);
}
指针变量作函数参数传递
void Swap1(int x, int y)
{
int temp;
temp = x;
x = y;
y = temp;
}
void Swap2(int *pi, int *pj)
{
int temp;
temp = *pi;
*pi = *pj;
*pj = temp;
}
? 函数:swap1( )和swap2( ),前者通过一般变量传值,后者通过指针传值。
? 通过一般变量传值时,传递的是变量的值,而采用指针变量传值时传递的是变量的
地址
int *ptrnum,arr_num[8];
ptrnum = &arr_num[0];
ptrnum++;地址增加
比较两个指针
#include<stdio.h>
void main ()
{
int *ptrnum1, *ptrnum2;
int value = 1;
ptrnum1 = &value;
value += 10;
ptrnum2 = &value;
if (ptrnum1 == ptrnum2)
printf("\n 两个指针指向同一个地址\n");
else
printf("\n 两个指针指向不同的地址\n");
}
一个数组存储在一块连续内存单元中;数组名就是这块连续内存单元的首地址; 第 (i + 1) 个数组元素的地址可表示为 &data[i] 或 (data+i)。
可以通过以下方式为指向数组的指针赋值:
int a[10];
pa=&a[0]; // 或者 pa=a;
一个指针变量可以指向一个数组元素
int *ptr,data[10];
ptr=data+3;//或者ptr=&data[3]
#include <stdio.h>
void main()
{
int data[] = {5, 10, 15, 20, 25};
int i = 0;
int *ptr;
ptr = data;
while(i < 5)
{
printf(“\n 第 %d 个元素的存储地址为:%x,值为: i++;
ptr++;
}
}
void main()
{
char name[5] = {'M', 'A', 'D', 'A', 'M'};
int flag = 1;
char *start=name, *end=name+4;
for(;start <= end; start++, end--){
if(*start != *end)
{
flag = 0;break;
}
}
if(flag)
printf("\n 该字符串是回文串\n");
else
printf("\n 该字符串不是回文串\n");
}
%d\n“,i+1, ptr, *ptr);
结构体
“结构” 是一种构造数据类型,它是由若干数据项组合而成的复杂数据对象,这些数据项称为结构的成员。
定义结构
struct structurename
{
datatype variable1;
datatype variable2;
...
};
? 结构定义并不预留内存
? 结构定义放置在程序的开始部分,位于头文件声明之后
? 结构定义仅描述了一个结构的形式。如果要在程序里使用结构,需要声明结构变量。 声明结构变量
I.先定义结构,再声明结构变量
struct student
{
int num;
char name[20];
char sex;
float score;
};
struct student student1,student2;
II.在定义结构类型的同时声明结构变量
struct student
{
int num;
char name[20];
char sex;
float score;
}student1,student2;
III. 直接声明结构变量
struct
{
int num;
char name[20];
char sex;
float score;
}student1,student2;
表示结构变量成员的一般形式是:结构变量名.成员名
例如:student1.num、student2.sex、student1.birthday.month
嵌套结构
struct date
{
int month;
int day;
int year;
};
Struct
{
int num;
char name[20];
char sex;
struct date birthday;
float score;
}student1,student2;
1、问题描述:
根据学员的成绩,输出不及格学员的详细信息。
#include<stdio.h>
struct student
{
int num;//学号
char *name;//姓名
char sex;//性别
float score;//成绩
};
void main()
{
static struct student stu1=,1,“张三",'M',61};
static struct student stu2=,2,“李四",'F',92.5};
static struct student stu3=,3,“王二",'M',59};
printf("不及格学员的名单如下:\n");
if(stu1.score<60)
printf("%d\t%s\t%c\t%5.2f\n",stu1.num,stu1.name,stu1.sex,stu1.score); if(stu2.score<60)
printf("%d\t%s\t%c\t%5.2f\n",stu2.num,stu2.name,stu2.sex,stu2.score); if(stu3.score<60)
printf("%d\t%s\t%c\t%5.2f\n",stu3.num,stu3.name,stu3.sex,stu3.score); if(stu1.score>=60 && stu2.score>=60 && stu3.score>=60)
printf("没有不及格的学员。\n");
}
结构数组
? 元素为结构类型的数组称为结构数组。
? 在实际应用中,经常用结构数组来表示具有相同数据结构的一个群体。例如一个班
的学员档案,一个公司的职工档案等。
struct student
{
int num;
char* name;
char sex;
float score;
}stu[30];
定义了一个结构数组stu1,共有30个元素,stu[0]~stu[29]。每个数组元素都具有struct student的结构形式。
2、问题描述:
求学员的总成绩和平均成绩,并统计不及格人数。
struct student
{
int num;
char *name;
char sex;
float score;
-stu*N+=, ,1,“李一”,‘F’,45-,,2,“李二”,‘F’,62.5-,,3,“李三",'M',92.5-,,4,“李四”,‘M’,87-,,5,“;李五",'M',58}};
void main()
{
int i,count=0;
float ave,sum=0;
for(i=0;i<N;i++)
{
sum+=stu[i].score;
if(stu[i].score<60)
count++;
}
printf("总分:%7.2f\n",sum);
ave=sum/5;
printf("平均分:%5.2f\n",ave);
printf("不及格人数为:%d\n",count);
}
3、建立存储宝宝信息的结构体类型。
#include <stdio.h>
#include <string.h>
#define N 5
struct baby
{
char name[20];
float height;
float weight;
};
int main()
{
struct baby baobao[N];
int i,count;
float max;
for(i=0;i<N;i++)
{
/* 输入宝宝的数据信息*/
printf("请输入第%d个宝宝的数据:\n",i+1);
printf("姓名:");
fflush(stdin); //清空输入缓冲区
gets(baobao[i].name);
printf("身高:"); scanf("%f",&baobao[i].height); printf("体重:"); scanf("%f",&baobao[i].weight); }
/*比较身高最高的宝宝*/
max=baobao[0].height;
count=0;
for(i=1;i<N;i++)
{
if(baobao[i].height>max)
{
max=baobao[i].height;
count=i;
}
printf("第%d个宝宝的身高最高,其信息如下:\n",count+1); printf("姓名:%s\n",baobao[count].name);
printf("身高:%5.2f\n",baobao[count].height);
printf("体重:%5.2f\n",baobao[count].weight);
}