C语言基础语法
#include <stdio.h> int main() { int age; printf("input your age"); scanf("%d",&age); if(age>22) { printf("you have become old"); } else if(age < 18) { printf("you are too young"); } else { printf("you are strong"); } }
C语言基础语法
-
变量,输入输出
-
判断
-
循环
-
函数
-
数据类型
-
数组
-
指针
- 结构体
-
链表
-
搜索
C注释
单行注释//
多行注释/* */
判断语句:
if()
{
}
else if()
{
}
else
{
}
switch case 语句
#include <stdio.h> int main() { int grade; scanf("%d",&grade); grade/=10; switch(grade) { case 10: case 9: printf("A"); break; case 8: printf("B"); break; case 7: printf("C"); break; case 6: printf("D"); break; } }
循环while
#include <stdio.h> int main() { int n=0; int sum=0; while(n<=100) { sum+=n; n++; } printf("%d",sum); return 0; }
for循环
#include <stdio.h> int main() { int n; int sum = 0; for(n=1;n<=100;n++) { sum+=n; } printf("%d",sum); return 0; }
do while循环
int main() { int i = 0,sum = 0; int n; scanf("%d",&n); do{ sum+=i; i++; }while(i<=n); printf("%d",sum); return 0; }
while语句是先检票后上车,do while语句是先上车后检票,dowhile语句至少会被执行一次。
数据类型
C语言中的变量必须先定义,并且明确数据类型
C语言中的数据类型有
- 整数型
- char、 short、 int、 long、 long long
- 浮点型
- float 、 double 、 long double
- 逻辑
- bool
- 指针
- 自定义类型
类型名称, int、long、double、
输入输出时格式化%d、%ld、 %lf、
所表达的范围
char<short<int<float<double
sizeof
是一个运算符,给出某个数据类型或者变量在内存中所占据的字节数
比如:
sizeof(int)
sizeof(i)
#include<stdio.h> int main(void) { int a[]={1,2,3,4,5,6,78,0}; printf("%d\n",sizeof(a)/sizeof(a[0])); long i; double f; printf("i=%d\n",sizeof(char)); printf("f=%d\n",sizeof(double)); }
运行结果
字符类型
char 是一种整数,也是一种特殊的类型:字符。这是因为:
字符是一种整数,可以进行整数的运算。
#include<stdio.h> int main(void) { char c='1'; char d=1; c++; printf("c=%c",c); }
用单引号表示的字符字面量:‘a’,'1'
''''也是一个字符
printf 和scanf里要用%c来输入输出字符
每一个字符都有一个对应的ASCII码值,
在ASCII码表中数字0-9是依次排列的
字母是顺序排列的,大写字母和小写字母是分开排列的,但大写字母A-Z是连续排列,小写字母也是。
大小写字符转换
#include<stdio.h> int main(void) { char c='a'; char d='B'; c=c+'A'-'a'; //将小写字母变成大写; d=d+'a'-'A'; printf("大写c=%c\n",c); printf("小写d=%c\n",d); }
函数定义调用
#include <stdio.h> int getmax(int x,int y) { int result; return x>y ? x:y; } int main() { int x,y,s; scanf("%d %d",&x,&y); s=getmax(x,y); printf("%d",s); return 0; }
C语言的函数都是从main函数开始执行的
函数定义时的参数称为形式参数,(parameter)
函数调用时的参数称为实际参数,(argument)
指针
#include <stdio.h> void swap(int *x,int *y); int main() { int a=4; int b=1; swap(&a,&b); printf("a=%d,b=%d",a,b); return 0; } void swap(int *x,int *y) { int temp; temp=*x; *x=*y; *y=temp; }
指针的概念
指针是一种数据类型
指针就是保存地址的变量
指针类型的变量称为指针变量
指针不是一个地址,指针变量的值是一个地址。
访问那个地址上的变量*
*是一个单目运算符,用来访问指针的值所表示的地址上的变量,
可以做右值,也可以做左值
int k = *p
*p = k+1
想让指针变量指向哪个存储单元,就让其保存哪个单元的地址。
- 保存一个变量的地址
- 保存一个数组的首地址
- 保存一个字符串的首地址
- 保存一个函数的首地址
使用指针变量的基本原则
明确指针指向了哪里--指针初始化
明确指针指向单元的内容是什么?---基类型
只能指向同一基类型的数据。
指针的重要应用
作函数参数,向函数传递变量或函数地址
动态分配内存,实现动态数组和动态数据结构
指向函数的指针做函数参数。
被调函数根据传入的不同地址调用不同的函数。
#include <stdio.h> void f(int *p);//声明函数原型 int main(void) //void 表明是无参函数 ,返回值为int { int i=6; printf("&i=%p\n",&i); //打印i的内存地址 f(&i); //将I的地址传给f函数 return 0; } void f(int *p) { printf("p=%p\n",p); //打印P的值 }
运行结果如下:
取地址运算符&
& 取变量的内存地址,& 后面必须跟的是变量
取内存地址必须要用%p
#include <stdio.h> int main(void) { int i=0; int p; printf("%p\n",&i); printf("%p\n",&p); printf("%lu",sizeof(&i)); return 0; }
可以发现内存地址之间差4个字节,而且i变量处于高位。因为C语言的内存管理是用一种堆栈,stack
查看数组的内存地址
#include <stdio.h> /* 取数组的内存地址,查看有什么变化*/ int main(void) { int a[10]; //定义一个数组,长度为10 printf("%p\n",&a); printf("%p\n",a); printf("%p\n",&a[0]); printf("%p\n",&a[1]); printf("%p\n",&a[2]); }
运行结果如下:
我们可以发现&a=a=&a[0] a[0] 和a[1]之间差4个字节
指针的应用,
数组与指针,
数组变量是特殊的指针
数组a==&a[0]
[]运算符可以对数组做,也可以对指针做
数组变量是const指针,不能被赋值
#include <stdio.h> void max_min(int a[],int *p1,int *p2) ;//声明函数原型 int main(void) //void 表明是无参函数 ,返回值为int { int a[]={1,2,3,4,7,45,76,24,2}; int min; int max; printf("&a=%p\n",a); max_min(a,&max,&min); printf("max=%d\n",max); printf("min=%d\n",min); printf("a[0]=%d",a[0]); return 0; } void max_min(int a[],int *p1,int *p2) { int i; *p1=a[0]; *p2=a[0]; a[0]=1000; printf("&a=%p\n",a); for (i=0;i<9;i++) { if (a[i]>*p1) {*p1=a[i]; } if(a[i]<*p2) { *p2=a[i]; } } }
运行结果如下
int divide(int a,int b,int *ret); /*用指针写一个除法运算*/ int main(void) { int a=20; int b=0; int ret; if(divide(a,b,&ret)) { printf("ret=%d",ret); } else printf("b 不能为 0"); return 0; } int divide(int a,int b,int *ret) { if(b !=0) { *ret=a/b; return 1; } else { return 0; } }
结构体
struct是一种数据类型
语法格式为struct 结构体名{
type var;
type var;
};
比如定义一个学生的结构体
见代码
int main(void) { typedef struct student{ int id; char name[20]; float score[4]; }STUDENT; STUDENT stu[4]= //STUDENT 与struct student是等价的,STUDENT相当于struct student 的别名 { {1,"于洋",{92,87,65,73}}, {2,"王洋",{91,85,97,73}} }; STUDENT *p; //定义一个STUDENT类型的指针p p=stu;//初始化这个指针,将指针指向stu的首地址,p=stu 与p=&stu[0]是等价的 printf("p->%s\n",p->name); //p->name 与(*p).name 是等价的 p++; //相当于p=&stu[1],改变p指向的内存地址 printf("*p%s\n",(*p).name); printf("%f\n",stu[0].score[1]); printf("这个数字是?:%f\n",p--->score[1]); }
运行结果
字符串
深入理解字符串,数组字符串 http://blog.csdn.net/lqxandroid2012/article/details/51721061
在C语言中字符串常量本质上代表的是一个地址
所以下面的语句是成立的
char *p;
p="hello world";
#include<stdio.h> #include<math.h> int main(void) { char *a[]={"shandong","hu","shanghai","beijing"};/*[]运算的优先级高于*,所以先执行a[],k可以得出定义了一个数组, 数组的元素的数据类型是char *指针*/ printf("%p %p %p %p\n",a[0],a[1],a[2],a[3]); //打印数组a的每一个元素。 printf("%p %p %p %p\n",&a[0],&a[1],&a[2],&a[3]);//打印 数组中的每个元素的地址 printf("a:size=%d",sizeof(a));//数组a的长度 return 0; }
可以看出char *a[]={"shandong","hu","shanghai","beijing"};
是一个数组,数组的每个元素是一个char * 的指针,每个指针保存的是内存地址,固定为4个字节(32位电脑),8个字节(64位电脑)。
链表
有单链表,双链表
链表是有一个个节点串起来的,
创建一个单链表
#include<stdio.h> #include<stdlib.h> typedef struct node{ int num; struct node *next; }NODE; int main(void) { NODE *head=NULL; int n; int i; do{ scanf("%d",&n); if(n!=-1){ NODE *p=(NODE*)malloc(sizeof(NODE)); p->num=n; p->next=NULL; NODE *last=head; if(last){ //find last node while(last->next){ last=last->next; } //attach last->next=p; }else{ head=p; } } }while(n!=-1); //创建完,查看一下链表中的数据 NODE *q=head; printf("%d",q->num); return 0; }
运行结果
查找
1遍历搜索,从第一个搜索到最后一个
#include<stdio.h> int search(int *p,int len,int key); int main(void) { int a[]={1,4,8,34,67,83,25,74,21}; int key; int ret; scanf("%d",&key); ret=search(a,sizeof(a)/sizeof(a[0]),key); printf("%d\n",ret); return 0; } int search(int *p,int len,int key) { int ret=-1; int i; for(i=0;i<len;i++) //i最好只干一件事,不要一专多能 { if(key==*p) { ret=key; break; } p++; } return ret;//最好程序有一个入口 }
是出口,不是入口
二分查找
二分查找极大的提高了效率,但数据必须是有序的
#include<stdio.h> #define MAXNUM 100 int main(void) { int a[]={1,2,4,13,17,25,45,48,61,74}; int len=sizeof(a)/sizeof(a[0]); int left,right,middle; left=0; right=len-1; int key; //要找的key printf("请输入要查找的整数"); scanf("%d",&key); int ret=-1; while(right>=left) { middle=(left+right)/2; if(key==a[middle]) { ret=middle; break; } else { if(key>a[middle]) { left=middle+1; } else{ right=middle-1; } } } printf("ret=%d\n",ret); return 0; }
排序
冒泡排序:相邻两个元素之间进行比较
#include<stdio.h> #define MAXNUM 100 int main(void) { int a[]={32,12,34,56,32,67,43,96,5,83}; int len=sizeof(a)/sizeof(a[0]); int i,j; int t; int max; for(j=len;j>0;j--) { for(i=0;i<j;i++) { if(a[i]>a[i+1]) { t=a[i+1]; a[i+1]=a[i]; a[i]=t; } } }
选择排序
#define MAXNUM 100 int main(void) { int a[]={32,12,34,56,32,67,43,96,5,83}; int len=sizeof(a)/sizeof(a[0]); int i,j; int t; int maxid; for(j=len;j>1;j--) { maxid=0; for(i=1;i<j;i++) { if(a[i]>a[maxid]) { maxid=i; } } t=a[maxid]; a[maxid]=a[j-1]; a[j-1]=t; } for(i=0;i<len;i++) { printf("%d\n",a[i]); } }