C语言基础知识:
内存四区:代码区 全局区 栈区(自动释放) 堆区(手动释放)
数据基本类型:
void(空类型;无返回值)short(短整型);int(整型);long(长整型);char(字符型)float(单精度浮点型);double(双精度浮点型);void(空类型);enum(枚举类型);struct(结构体类型);union(共用体类型);T*(指针类型)
变量名:
必须符合c语言对标识符的规定
标识符:
必须以字母或下划线开始,且只能由字母,数字,下划线组成
字节:
8个二进制位
转义字符:
\n:换行
\t:跳到下一个Tab位置
\r:回车:移到本行开头
\f:换页:移到下一页开头
\a:发出铃声
运算符
&&:与:eg: 1&&1→1
||:或:eg: 1||1→1 1||0→1 0||0→0
!:非:eg: !1→0 !0→1
+(加) -(减) *(乘) /(除) %(取模)
输出格式符
%c:输出字符 %s:输出字符串 %d:输出整数 %f:输出小数
常用语句
printf:输出 scanf:输入 putchar getchar puts gets strcat strcpy strncpy strcmp strlen strlwr strupr
数组
eg:
a[2][3][4] //2个[3][4]二维数组,a[3][4]是由3个[4]组成
一维数组
定义:类型说明符 数组名【常量表达式】 eg:
Int a[10]
引用:数组名【下标】 eg:
main(){
int a[5],i; //定义数组a;数组a包含: a[0] a[1] a[2] a[3] a[4] a[5]
for(i=0;i<6;i++){
a[i]=i;
printf("a[%d]=%d\n",i,a[i]);
}
}
初始化:
int a[5]={0,1,2,3,4};//定义数组时赋值
int a[5]={1,2};//定义数组时赋部分值
int a[5]={0};//数组中全部元素值为0
int a[]={0,1,2,3,4};//系统自动定义数组长度为5
二维数组
定义:类型说明符 数组名【常量表达式】【常量表达式】 eg:
float a[3][4],a[5][10]; //定义a为3行4列的数组,b为5行10列的数组
引用:数组名【下标】【下标】 eg:
a[3][4]=5 //a数组3行4列元素赋值为5
初始化:
int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}; //初始化3行的数组,每行4个元素
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12} //同上
int a[3][4]={{1},{5},{9}} //只对每行的第一个元素赋值
字符数组(输入输出)
eg:
void main(){
char a[10]={'I',' ','L','O','V','E',' ','Y','O','U'}; //a为i love you 长度10
char b[]={"good morning"}; //b为good morning 长度为12
char c[50]={"luojing"};
int i;
for(i=0;i<11;i++){ //for函数输出数组a
printf("%c",a[i]);
}
printf("\n第二个输出:%s\n",b); //输出数组b
puts(a); //put函数输出数组a
printf("第四个输出:%s %s\n",a,b); //连续输出数组a和b
printf("第五个输出:%s\n",strcat(a,b)); //strcat函数连接两个字符串a和b,把b接在a后面,并把结果放在数组a内。
if(strcmp(a,b)<0){ //比较字符串 输出为yes
printf("第六个输出yes\n");
}
printf("第七个输出:%d\n",strlen(a)); //测量字符串长度
printf("第八个输出:%d\n",strlen("good\n")); //测量字符串长度
printf("第九个输出:%s\n",strlwr(a)); //将大写字符转换为小写
printf("第十个输出:%s",strcpy(c,b));
return 0;
}
字符串处理函数
puts函数(输出字符串函数):puts(字符数组)
gets函数(读取字符串函数):gets(字符数组)
strcat函数(字符串连接函数):strcat(字符数组1,字符数组2)
strcmp函数(字符串比较函数):strcmp(字符串1,字符串2)//ASCLL码大小 相等为0,大为正,小为负
strlen函数(测量字符串长度):strlen(字符数组)
strlwr函数(将大写字符串转换为小字符串):strlwr(字符串)
strcpy和strncpy函数(字符串复制函数):strcpy(字符数组1,字符串2)
选择语句
If语句(三种格式)
格式一:If(表达式) 语句 eg:
if(a>b) pintf(“%c”,a); //如果a大于b,以字符格式输出a
格式二:If(表达式)语句1 else语句2 eg:
if(a>b)
printf(“%d”,&a); //如果a大于b,以数字格式输出a的地址
else
printf(“%d”,&b); //否则输出以数字格式输出b的地址
**格式三:**If(表达式1)语句1
else if(表达式2) 语句2
else if(表达式3) 语句3
┊
else 语句n eg:
//依据分数,划分成绩等级
if(number>90) printf("成绩优秀");
else if(number>70&&number<90) printf("成绩合格");
else if(number>60&&number<70) printf("成绩合格");
else printf("成绩不合格");
if嵌套
eg:
//能被4,100,400整除的年份为闰年
int main(void) {
int year,leap;
printf("请输入年份\n");
scanf("%d",&year);
if(year%4==0){
if(year%100==0){
if(year%400==0){
printf("此年为闰年\n");
}
else printf("%d年不为闰年\n",year);
}
else printf("%d年不为闰年\n",year);
}
else printf("%d年不为闰年\n",year);
}
条件表达式
条件表达式1?表达式2:表达式3 //表达式1为真,取表达式2的值,否则取表达式3值
max=(a>b)? a:b //判断a>b是否成立,若成立max=a,若不成立max=b
switch语句
switch(表达式)
{
case 常量表达式1:语句1
case 常量表达式2:语句2
┊
case 常量表达式n:语句n
default: 语句n+1
} eg:
//依据分数,划分成绩等级
Switch(grade){
case ‘A’:printf(“90~100\n”);
case ‘B’:printf(“80~90\n”);
case ‘C’:printf(“70~80\n”);
case ‘D’:printf(“60~70\n”);
default:printf(“不及格\n”);
}
循环语句
while循环
While(表达式)语句 eg:
//1+2+3…+100=
void main(){
int i=1,sum=0;
while(i<=100){
sum=sum+i;
i++;
}
printf("从1加到100的和为:%d",sum);
return 0;
}
do…while循环
do
循环体语句
while(表达式); eg:
//1+2+3…+100=
void main(){
int i=1,sum=0;
do{
sum=sum+i;
i++;
}while(i<=100);
printf("从1加到100的和为:%d",sum);
return 0;
}
for循环
for(循环变量赋初值;循环条件;循环变量增值)语句 eg:
//1+2+3…+100=
void main(){
int i,sum;
for(i=1,sum=0;i<=100;i++) sum=sum+i;
printf("从1加到100的和为:%d",sum);
}
改变循环状态
break; //结束整个循环,不在判断执行条件是否成立
continue; //只结束本次循环
函数调用:(函数就是功能 )
定义无参函数:
类型标识符 函数名()
{
声明部分
语句部分
}
定义有参函数
类型标识符 函数名(形式参数表列)
{
声明部分
语句部分
}
定义空函数
类型说明符 函数名()
eg:
/*声明函数*/
void start();//声明无参函数
int max(int a,int b);//声明有参函数
void dummy();//声明空函数,等以后扩充使用
/*定义函数*/
void start(){ //定义无参函数
printf("请输入两个数字");
}
int max(int a,int b){ //定义有参函数 a b 为形参
int max;
max=a>b?a:b;
return(max);
}
void dummy();//定义空函数
/*主函数*/
int main(int argc, char *argv[]) {
int number1,number2,c;
start();
scanf("%d%d",&number1,&number2);
c=max(number1,number2);
printf("%d和%d中较大的数为:%d",number1,number2,c);
}
函数的嵌套调用
void start();//声明无参函数
int max_2(int a,int b);//声明有参函数
int max_4(int a,int b,int c,int d);//声明有参函数
/*主函数*/
int main(int argc, char *argv[]) {
int number1,number2,number3,number4,max;
start();
scanf("%d%d%d%d",&number1,&number2,&number3,&number4);
max=max_4(number1,number2,number3,number4);
printf("%d %d %d %d中最大的数为:%d",number1,number2,number3,number4,max);
}
/*定义函数*/
void start(){ //定义无参函数
printf("请输入四个数字");
}
int max_4(int a,int b,int c,int d){ //定义有参函数 a b c d为形参
int m;
m=max_2(a,b);m=max_2(m,c);
m=max_2(m,d);
return(m);
}
int max_2(int a,int b){ //定义有参函数 a b 为形参
int m;
m=a>b?a:b;
return(m);
}
函数的递归调用
Hanoi问题
/*函数声明*/
void hanoi(int n, char A, char B, char C);
/*主函数*/
int main(){
int n;
char A = 'A';//定义ABC表示三个柱子
char B = 'B';
char C = 'C';
printf("hanoi从A移动到B\n请输入你想移动的汉诺塔层数:\n\n");
scanf("%d", &n);
printf("从上到下圆盘编号依次为 1 到 %d :\n\n",n);
hanoi(n, A, B, C);
return 0;
}
/*定义函数*/
void hanoi(int n, char A, char B, char C){
if (n == 1) // 如果只有一个直接从A移到B{
printf("移动编号为 %d的圆盘: 从 %c 移动到 %c\n",n,A,B);
}
else{
hanoi(n - 1, A, C, B); //#把n-1个从A移到C借助B
printf("移动编号为 %d的圆盘: 从 %c 移动到 %c\n",n,A,B);
hanoi(n - 1, C, B, A); //#把n-1个从C移到B借助A
}
}
数组作为函数参数
数组元素作为函数实参
int main(int argc, char** argv) {
int large (int x,int y);
int a[10],b[10],i,n=0,m=0,k=0;
printf("请输入数组a内的元素:\n");
for(i=0;i<10;i++)
scanf("%d",&a[i]);
printf("请输入数组b的元素:\n");
for(i=0;i<10;i++)
scanf("%d",&b[i]);
//循环比较数组a和数组b内的元素
for(i=0;i<10;i++){
if(large(a[i],b[i])==1)
n++;
else if(large(a[i],b[i])==0)
m++;
else k++;
}
printf("数组a的元素比数组b的元素大的次数为: %d\n",n);
printf("数组a的元素和数组b的元素相等的次数为: %d\n",m);
printf("数组a的元素比数组b的元素小的次数为: %d\n",k);
}
//定义比较函数,a对应x,b对应y
large(int x,int y){
int flag;
if(x>y) flag=1;
else if(x=y) flag=0;
else flag=-1;
return (flag);
}
函数名作函数参数
int main(int argc, char** argv) {
float average(float array[10]);
float score[10],aver;
int i;
printf("输入10个元素\n");
for(i=0;i<10;i++)
scanf("%f",&score[i]);
printf("\n");
aver=average(score);
printf("平均数是%5.3f\n",aver);
}
float average(float array[10]){
int i;
float aver,sum=array[0];
for (i=1;i<10;i++)
sum=sum+array[i];
aver=sum/10;
return(aver);
}
多维数组名作函数参数
eg:
//有个3x4的二维数组,求二维数组中所有元素的最大值
int main(int argc, char** argv) {
/*
思路:max的初值为第一个元素
*/
int max_value(int array[][4]);
int a[3][4]={{1,3,5,7},{2,4,6,8},{3,51,48,511}};
printf("最大值是:%d\n",max_value(a));
}
int max_value(int array[][4]){
int i,j,max;
max=array[0][0];
for(i=0;i<3;i++){
for(j=0;j<4;j++)
if(array[i][j]>max)max=array[i][j];
}
return(max);
}
变量
静态存储方式:程序运行期间由系统分配固定的存储空间。
动态存储方式:程序运行期间根据需求进行动态的分配存储空间。
局部变量
**定义:**在函数内部定义的变量,变量的有效范围在函数内。
auto自动局部变量:函数调用结束后自动释放这些存储空间。(动态存储方式)
static静态局部变量:调用调用该函数时,该变量的值就是上一次函数调用结束时的值。(静态存储方式)
eg:
定义两个变量
#include <iostream>
/*
三次调用
*/
int variable(int a){
auto int b=0; //自动局部变量的值每次调用都是初始值。
static int c=3; // static静态局部变量的值就是上一次函数调用结束时的值。
b=b+1;
c=c+1;
return(a+b+c);
}
int main(int argc, char** argv) {
int variable(int);
int a=2,i;
for(i=0;i<3;i++)
printf("%d\n",variable(a));
}
register把局部变量放入寄存器中(现在很少这么做)
全局变量
定义:在函数外部定义的变量。变量可以被其他函数共用。(存放在静态存储区)
eg:
//在文件内使用extern扩展全局变量的作用域
#include <iostream>
int main(int argc, char** argv) {
int max();
extern int a,b,c; //扩展全局变量a,b,c的作用域
printf("请输入三个整数:\n");
scanf("%d%d%d",&a,&b,&c);
printf("最大的数字是%d\n",max());
}
int a,b,c;
max(){
int m;
m=a>b?a:b; //a>b为真。则选择:前的内容,否则选择:后的内容
if(c>m)
m=c;
return(m);
}
eg:使用extern将外部变量作用域扩展到其他文件
文件file1.c的内容:
#include <iostream>
int a,b,c;
int main(int argc, char** argv) {
int max();
extern int a,b,c;
printf("请输入三个整数:\n");
scanf("%d%d%d",&a,&b,&c);
printf("最大的数字是%d\n",max());
}
文件file2.c的内容:
#include <iostream>
extern int a,b,c;
max(){
int m;
m=a>b?a:b;
if(c>m)m=c;
return(m);
}
内部函数和外部函数
内部函数(静态函数)定义:一个函数只能被本文件中其他函数所调用。
**定义:**static 类型标识符 函数名(形参表)
外部函数定义:可供其他文件调用的(省略即为外部函数)
指针
指针变量:用来存放地址的变量
取地址:&
取该地址指向的变量值:*
&和*互为逆运算
首地址:一段内存空间中第一个存储单元的地址。
指针变量的加减是以指针所指向的类型空间为单位进行偏移。
eg:
//使用指针输出一维数组的值;
#include <iostream>
int main(int argc, char** argv) {
int a[5]={1,3,5,7,9};
int *p=a; //*p指向a[0] *p是指a[0]的值
for(int i=0;i<5;i++){
printf("%d\n",*p++); //指针的加减是所指向的空间为单位进行偏移
}
printf("%d\n",*p); //*P指向的是a[0]的值c
printf("%d\n",&p); //&P所指的是*p的地址
printf("%d\n",p); //p所指的是*p存储的值,也就是a[0]的地址
}
用户建立的数据类型
(1)C语言中结构体中只可以定义成员变量,如果你说你在结构体中可以定义成员函数和构造函数,那应该是C++而不是C语言,C语言作为面向过程的语言是要将数据和算法进行分离的。Java的类除了可以封装成员变量,还可以封装成员函数,也就是对于成员变量的操作。
(2)结构体中的成员变量都是可以直接访问的,而类则可以通过声明public、protected、private或者不加权限修饰符来进行访问权限的控制。另外类是可以继承的,子类可以通过继承获得父类的一些属性或者方法,这是结构体所不具有的。
(3)结构体仅仅是封装数据用的,也可以说仅仅是自定义的一种变量类型;而java作为一种纯面向对象语言,将所有东西都封装在类中,包括程序执行入口的Main方法。
(4)要单纯说Java的类相对于C语言结构体的优势,倒不如宏观上看面向对象编程思想和面向过程编程思想的区别,这是两种不同的思维方式,楼主可以看一下比较经典的斐波那契数列的面向过程解题方法和面向对象解题方法。
结构体定义:
定义:相当于一个公有的类
struct 结构体名{
成员表列
};
eg:
#include <stdio.h>
#include <stdlib.h>
struct date{
int month;
int day;
int year;
};
struct student{
int num;
char name[50];
char sex[50];
int age;
struct date birthday;
float score;
char addr[30];
}student2={10002,"罗京","男",24,8,12,1995,95.5,"湖北省黄冈市"}; //结构体初始化的方法
int main(int argc, char *argv[]) {
struct student student1;
student1.num=10001;
strcpy(student1.name,"吴彦祖");//strcpy为复制语句
student1.birthday.day=8; //结构体单独赋值的方法
student1.birthday.month=12;
student1.birthday.year=1995;
printf(" num:%d \n name:%s \n sex:%s \n age:%d \n birthday:%d %d %d \n score:%5.1f \n addr:%s \n",student1.num,student1.name,student1.sex,student1.age,student1.birthday.year,student1.birthday.month,student1.birthday.day,student1.score,student1.addr);
printf(" num:%d \n name:%s \n sex:%s \n age:%d \n birthday:%d %d %d \n score:%5.1f \n addr:%s \n",student2.num,student2.name,student2.sex,student2.age,student2.birthday.year,student2.birthday.month,student2.birthday.day,student2.score,student2.addr);
}