C语言基础概要

前言:在学习Cpp这本书的时候,十分详尽、说理论据是我对这本书的直观感受,但也是由于这种细致让我时常会有道阻且长的枯燥感,所以干脆就整理了学习C必须要理解透彻的基础概要,算是把骨架先搭好,理清脉络,之后在编写程序的实操中遇到什么问题,再带着问题补充学习,把这本13W字的书当作字典来查阅,我相信从效率上和心理上应该都会有不错的效果。
1.1 C程序要点
语言程序有且仅有一个main函数,是程序运行的起点。
每个C语言程序完成后,都是先编译(生成.c文件),后链接(生成.obj文件),最后运行(生成.exe文件)。
注意:.c和.obj文件是无法运行的,只有.exe文件才可以运行。

1.2 标识符的概念
标识符是由字母,数字,下划线组成。并且一个必须为字母或下划线。标识符分为关键字、预定义标识符,用户标识符。
1.关键字:不可以作为用户标识符号,有数据类型关键字(char、double、float、int等)、控制语句关键字(for、if、while、switch、return等)、存储类型关键字(auto、extern、register、static)、其他关键字(const、sizeof、typedef、volatile)
2.预定义标识符是C语言中系统预先定义的标识符,如系统类库名、系统常量名、系统函数名。如:define、scanf、printf、include。
3.用户标识符:用户在写代码时自己命名的合法标识符。
注意:严格区分大小写,尽可能采用能说明程序对象意义的标识符。

1.3 进制转换
1.C语言只有8、10、16进制,没有二进制;但在运行时,所有进制都要转换成(机器语言)二进制来处理。
8进制规定要以0开头、没有8,逢8进1;16进制规定要以0x开头。
2.小数的合法写法:C语言小数点两边有一个是零的话,可以不用写。如:1.0可写成1. 0.1可写成.1
3.实型数据的合法形式如:2.333e-1表示的数据为2.333×10-1
4.整型(int)一般是4个字节,字符型(char)是1个字节,双精度型(double)一般是8个字节。

1.4 算术表达式和赋值表达式
1.算术表达式:+,-,,/,%
注意
:“/”两边都是整形的话,结果就是一个整型,3/2的结果就是1。
“/”如果有一边是小数,那么结果就是小数。3/2.0的结果就是1.5。
“%”符号注意是余数,符号两边要求是整数。
2.赋值表达式
变量=数值,如:a=b=5;该表达式为5,常量不可以赋值。
Int x=y=10; //错误,定义时,不可以连续赋值
Int x,y;
x=y=10; //正确
int x=7.7; //正确,x值为7
float y=7; //正确,x值为7.0

3.自加表达式
假设a=5,++a是先把变量的数值加上1,然后把得到的数值放在变量a中,然后再用这个++a的表达式时的数值为6。
a++是先用该表达式的数值5,然后再把a的数值加上1,再放到变量a中。进行了++a和a++后,下面的程序再用到a的话变量a的值就都为6了。
即:++在前先加后用,++在后先用后加。
4.逗号表达式
优先级别最低。表达式的数值是逗号最右边的那个表达式的数值。
如:(2,3,4)的表达式的数值就是4。
z=(2,3,4)(整个是赋值表达式)这个时候z的值是4;
z=2,3,4(整个是逗号表达式)这个时候z的值为2。
x=(a=3,6a) a=3 ; x=18
x=(a=3
5,a*4),a+15 表达式值30,x=60

补充:
1.空语句不可以随意执行,会导致逻辑错误。
2.注释不是c语言,不占用运行时间,没有分号。不可以嵌套。
3.强制类型转换:(比如,a原本为float型,(int)a将其转换为整型)
一定是(int)a不是(int)a,注意类型上一定有括号的。
注意(int)(a+b)和(int)a+b的区别;前者是把a+b转型,后者是先转型a再加上b。
4.三种取整丢小数的情况:int a=1.6 ;b=(int)a ; 3/2。

1.5 字符
1.字符数据的合法形式:
’1’是字符占一个字节,“1”是字符串占两个字节(含有一个结束符号)。
‘0’的ASCII数值表示为48,’a’的ASCII数值是97,’A’的ASCII数值是65。
字符是可以惊醒算术运算的:‘0’-0=48
大写字母和小写字母转换的方法:‘A’+32=’a’,相互之间一般是相差32。
2.转义字符:
一般转义字符:水平制表\t、换行\n、单引号\’、双引号 \“、反斜杠\ ;
八进制转义字符:‘141’是合法的,前导的0是不能写的;
十六进制转义字符:‘\x6d’才是合法的,前导的0不能写,并且x是小写。

2.1数据输出printf()
1.使用过printf和scanf函数时,要在最前面加上#include<stdio.h>
2. printf可以只有一个参数,也可以有两个参数。
3. eg: printf(“a=%d,b=%d”,12,34) 输出结果为a=12,b=34
printf(“a=%d,\n b=%d”,12,34) 输出结果为a=12,
b=34
4.int x=017; //八进制数

printf(“%d”, x); //15,十进制
printf(“%o”, x); //17,八进制
printf(“%#o”, x); //017,带前导的八进制
printf(“%x”, x); //f,十六进制
printf(“%#x”, x); //0xf,带前导的十六进制

2.2 数据输入scanf()
1.eg:scanf(“a=%d,b=%d”,&a,&b) 输入为a=12,b=34时,即完全按照格式输入才可以把12和34正确赋给a和b。&表示取a、b的地址,不能省略。
2.指针在scanf的考察
Eg:int x=2 ; int *p; p=&x;
scanf(“%d”,x); 错误
scanf(“%d”,p); 正确
scanf(“%d”,&p); 错误
scanf(“%d”,*p); 错误
3.指定输入的长度
终端输入:1234567
scanf(“%2d4d%d”,&x,&y,&z); x为12,y为3456,z为7。
终端输入:1 234567 (由于1和2中间有空格,所以只有1位给x)
scanf(“%2d4d%d”,&x,&y,&z); x为1,y为2345,z为67。
4.字符和整型的区别
int x=97;
printf(“%c”,x); 结果为a
printf(“%d”,x); 结果为97

scanf(“%c”,&x) 输入1,表示的是字符’1’,ASCII为整数49。
scanf(“%d”,&x) 输入1,表示的是整数1。
5.putchar和getchar函数
Char a=getchar()是没有参数的,从键盘得到一个你输入的字符给变量a。
Putchar(‘y’)把字符y输出到屏幕中。
6.如何实现两个变量x,y的数值交换
t=x; x=y; y=t; //用中间变量

3.1表达式
1.关系表达式:
关系表达式的数值只能是1(表示真),或0(表示假)。
Eg:int x=1,y=0,z=2;
x<y<z为真还是假?
解:1<0为假得到0,表达式则变为判断0<2,即运算结果为1(真)。
补充:=表示赋值。表示等号。
2.逻辑表达式:
表达式的数值只能是1(真)或0(假)。
三种逻辑运算符号: &&(与) || (或) !(非)
优先级:!> && > ||
Eg:表示x大于0小于10:(0<x)&&(x<10)
3.2 if语句
1.单独的if语句:if (a<b) t=a;
标准的if语句:if (a<b) min=a;
else min=b;
嵌套的if语句:if (a<b)
If (b>c) printf(“ok!”);
多选一的if语句:if (a
t) printf(“a”);
else if (bt) printf(“b”);
else if (c
t) printf(“c”);
else printf (“d”);
2.条件表达式:
表达式1?表达式2:表达式3
注意是当表达式1的数值是非0时,才采用表达式2的数值作为整个运算结果,当表达式1的数值为0时,就用表达式3的数值作为整个的结果。
Eg:int a=1,b=2,c=3,d=4,e=5;
k=a<b?c:d; k的数值为3
k=d>e?d:e; k的数值为5
3.switch语句
A.break:没有break的时候i,只要有一个case匹配了,剩下的都要执行,有break则是直接跳出了switch语句。
B.switch只可以和break一起用,不可以和continue用。
C.Switch(x) x:是整型常量,字符型常量,枚举型数据。
{case 1: … 不可以是变量
case 2: ….}
D.eg:
#include<stdio.h>
int main()
{
char grade=’B’
switch(grade)
{
case’A’:printf(“完美!\n“);
break;
case’B’:printf(“很棒!\n“);
break; // ①
case’C’:printf(“做的好!\n“);
break; // ②
case’D’:printf(“60分万岁!\n“);
break;
default:printf(“无效的成绩\n”);
}
printf(“您的成绩是%c\n”,grade);
return 0;
}

输出结果为:
很棒!
您的成绩是B

删掉①和②行的break,输出结果为:
很棒!
做的好!
60分万岁!
您的成绩为B

3.3 循环结构
1.三种循环结构:for() ; while() ; do-while() ;
2.for循环当中必须是两个分号。
3.循环一定要有结束的条件。
4.do-while()循环的最后一个while();的分号一定不能丢,do-while循环是至少执行一次循环。
5.break和continue的区别:
Break:打破,到break就退出整个循环。
Continue:继续,继续循环运算,但是要结束本次循环,就是循环体内剩下的语句不再执行,跳到循环开始,然后判断条件,进行新一轮的循环。
6.用三种循环语句实现1+2+3+…+1000。
#include<stdio.h>
void main()
{
int i,sum=0; int i=1,sum=0; int i=1,sum=0;
for(i=1;i<=1000;i++) while(i<=1000){ do{
sum+=i; sum+=i; i++;
printf(“%d”,sum); i++; sum+=i;
} } }while(i<1000);

4.1 函数
1.函数:是具有一定功能的一个程序块,是c语言的基本组成单位。
2.函数的定义:[函数类型]函数名(形式参数) 函数不可以嵌套定义,但是可以嵌套调用。
3.函数名缺省返回值类型,默认为int。
4.c语言由函数组成,但有且仅有一个main函数,是程序的开始。
5.如何判断a是否为质数:

//判断是否为质数
#include<stdio.h>
#include<string.h>
int prime(int);
void main()
{
	int a;
	int p;
	printf("请输入一个数字:\n");
	scanf_s("%d", &a);
	p = prime(a);
	if (p)
		printf("该数字为质数");
	else
		printf("该数字不是质数");
	system("pause");
	return 0;
}

int prime(int a)
{
	int i;
	int flag;
	for(i=2;i<a/2;i++)
		{
			if(a%i==0)
			{
				flag=0;
				break;
			}
			else flag=1;
		}
	if(flag==0)
		return 0;
	else return 1;
}

运行截图
在这里插入图片描述

5.1 指针
1.指针:指针变量的本质是用来存放地址,而一般的变量是放数值的。
①int x=3;int *p=&x ;
②int x; int *p;
x=3;p=&x
int *p中 *p和p的区别:*p是数值,p是地址。
*p可以当做变量来用;*的作用是取后面地址p里面的数值。
P是当作地址来用的,可以用在scanf函数中:scanf(“%d”,p);
2.*p++和(*p)++之间的区别:
*p++是地址,会变化。取当前值,然后再移动地址。
(*p)++是数值会变化。取当前值,然后再使数值增加1。
3.二级指针:
*p:一级指针:存放变量的地址。
**q:二级指针:存放一级指针的地址。
Eg:int x=7;
int p=&x,**q=p;
p为7,*q为p,**q为7。
4.数组名、函数名、字符串常量名
数组名:表示第一个元素的地址。数组名不可以自加,他是地址常量名。
函数名:表示该函数的入口地址。
字符串常量名:表示第一个字符的地址。
5.移动指针
Char *s=”yidongzhizhen”
While(*s){printf(“%c”,*s);s++;}
这个s首先会指向第一个字母m然后通过循环回一次打印出一个字符,s++是地址移动,打印了一个字母后,就会移动到下一个字母。
6.指针变量两种初始化
方法一:int a=2,*p=&a;(定义的同时初始化)
方法二:int a=2,*p;(定义之后初始化)
P=&a;

6.1 数组
1.数组:存放的类型是一致的,多个数组元素的地址是连续的。特点:一次存入,多次使用。
2.一维数组的定义:
int a[5];定义时数组的个数不是变量而是常量。
补充:
a表示数组名,是第一个元素的地址,也就是元素a[0]的地址。(等价于&a)
a是地址常量,所以只要出现a++,或者是a=a+2赋值都是错误的。
a是一维数组名,所以它是列指针,也就是说a+1是跳一列。
Eg:一维数组的初始化:
int a[5]={1,2,3,4,5}; 合法
int a[5]={1,2,3, }; 合法
int a[]={1,2,3,4,5}; 合法,后面决定前面的大小
int a[5]={1,2,3,4,5,6}; 不合法,赋值的个数多于数组的个数了
3.二维数组的初始化:
对a[2][3]的补充讨论:
a表示数组名,是第一个元素的地址。也就是元素a[0][0]的地址。
a是地址常量,所以只要出现a++,或者是a=a+2赋值都是错误的。
a是二维数组名。所以他是行指针,也就是说a+1是跳一行。
a[0]、a[1]、a[2]也都是地址常量,不可以对它进行赋值操作,同时他们都是列指针,a[0]+1,a[1]+1,a[2]+1都是跳一列。
注意a和a[0]、a[1]、a[2]是不同的,他们的基类型是不同的。前者是一行元素,后三者是一列元素。
Eg:
int a[2][3]={1,2,3,4,5,6}; 合法,标准二维数组的赋值。
int a[2][3]={1,2,3,4,5, }; 合法,后面一个默认为0。
int a[2][3]={{1,2,3} {4,5,6}}; 合法,每行三个。
int a[2][3]={{1,2} {3,4,5}}; 合法,第一行最后一个默认为0。
int a[2][3]={1,2,3,4,5,6,7}; 不合法,赋值的个数多余数组的个数了。
int a[][3]={1,2,3,4,5,6}; 合法,可以缺省行的个数。
int a[2][3]={1,2,3,4,5,6}; 不合法,不可以缺省列的个数。

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值