c语言的语句语法
1. 条件分支结构if
if ( ) { } else { } (如果不加{},if/else 的作用域只有后面的一句代码)
#include<stdio.h>
int main()
{
int i=1;
if(i != 0)
{printf("i is not equal to 0!\n");
}
else
{
printf("out");
}
return 0;
}
2. 多分支结构 switch case
Switch (a)
{
case 1:
case2:
.....
default:
}
#include<stdio.h>
int main()
{
int a=1;
// char a= 'a'; char也是可以的 字符串不可以
switch (a)
{ //因为字符型也是整数类型,char和int可以互相转换
case 1: //case 'a': 如果是char则这样写
printf("is 1!\n");break; //不加break的话会一直输出每个case
case 2:
printf("is 2!\n");break;
case 'a' :
printf("a!\n");break; //如果输入97,则输出:a!
default:
printf("your print is wrong\n" );
}
}
3. 循环结构
1)for循环
for(初始条件;循环条件判断;循环步长)
{
} 输出0-100的非零偶数
#include<stdio.h>
int main()
{
for(int i=0;i<=100;i++) //int i=0可以写在上面 for(;i<1;i++)
{ //for(i=0;;i++)永真循环,无限循环
if(i%2==0&&i!=0)
{
printf("i:%d ",i);
}
}
printf("\n");
return 0;
}
2)while循环
while()
{
}
#include<stdio.h>
int main()
{
int i=100;
while(i)
{
printf("%d",i);
i--;
}
}
3)do while循环
do while循环与while/for区别:do while先执行循环指令,再进行判断,至少执行一次
while,for是先判断,满足条件才执行
do
{
}while();
4) 例题
例题: 输出这样一个式子的结果 a+aa+aaa+...... n个a
#include<stdio.h>
int main()
{
int a=0,n=0;
scanf("%d %d",&a,&n); //&取地址符 不加\n
int s=0;
int value=0;
for(int i=0;i<n;i++)
{
value=10*value+a; //表示出a;aa;aaa
s=s+value; //将表示出的各个数累加
}
printf("s= %d\n",s); //输入:1 3 输出:123
return 0;
}
例题: 找到所有三位数的水仙花数 函数 pow(2,3) x的y次方
如:153 1^3+5^3+3^3=153
#include<stdio.h>
#include<math.h>
int main()
{
for(int i=100;i<=999;i++)
{
int units=i%10;
int hundreds=i/100;
int decade=i/10%10;
if(pow(units,3)+pow(decade,3)+pow(hundreds,3)==i)
{
printf("%d\n",i);
}
}
return 0;
}
例题: 输出三行六列的点集
#include<stdio.h>
int main()
{
for(int row=0;row<3;row++)
{
for(int column =0;column<6;column++)
{
printf(" * ");
}
printf("\n"); //打完6个*就换一行
} //外循环控制行,内循环控制每行打几个
return 0;
}
例题: 打印九九乘法表
#include<stdio.h>
int main()
{
for(int row=1;row<=9;row++)
{
for(int column =1;column<=row;column++) //第一行一列,第二行两列以此类推
{ //所以column<=row
printf("%d * %d=%d ",column,row,column*row);
}
printf("\n");
}
return 0;
}
二、 函数
- 封装
函数:封装重复使用的代码
int add(int a) { }
返回值类型 函数名 (变量){ 函数主体内容 }
#include<stdio.h>
int test(int a)
{
printf("helloworld: a : %d\n",a);
return 10;
}
int main()
{
int m= test(20);
printf("m: %d\n",m);
return 0; //输出:helloworld: a : 20
m: 10
}
例题:哥德巴赫猜想:任何一个大于6的偶数都可以拆分成两个(不同)素数和
#include<stdio.h>
#include<math.h>
int IsPrime(int a) //判断一个数是不是素数
{
if(a==2)return 1;
for(int i=2;i<=sqrt(a);i++) //i<a也行,但是这样可以优化循环,减少检索范围
{
//如果a在大于根号a的范围内有因子,那他一定有一个小于根号a的因子
if(a % i == 0) //例如100不可能有两个大于10的因子,11*11=121>100
{
return 0;
}
}
return 1;
}
int main()
{
int a;
scanf("%d",&a);
if(a<=6)
{
printf("please input a number bigger than 6 \n");
return 0;
}
for(int i=1;i<a/2;i++) //拆成两个数,必定有一个小于一半
{
if(IsPrime(i)==1 &&IsPrime(a-i)==1)
{
printf("first :%d second : %d\n",i,a-i);
}
}
return 0;
}
2. 宏函数
用宏定义函数
#include<stdio.h>
#define A(a) (a)>0 ? (a):(-a) //绝对值函数
#define MAX(a,b) (a)>(b) ? (a):(b) //比大小函数
int main()
{
int a,m,n;
scanf("%d %d %d",&a,&m,&n);
printf("A(a): %d\n",A(a));
printf("MAX(a,b): %d\n",MAX(m,n));
return 0;
}
宏函数定义的变量为什么要加()?
#include<stdio.h>
#define M(x,y,z) x*y+z
int main()
{
int a=1,b=2,c=3;
printf("%d\n",M(a+b,b+c,c+a)); //输出:12
return 0; //计算变成a+b*b+c+c+a,*抢了优先级
}
3. 写日志函数
头文件 1.h
#ifndef _MYHEAD_H_
#define _MYHEAD_H_
//放头文件内容或者声明主函数要调用的函数
#define LOG(log) Write_Log(__FILE__,__func__,__LINE__,log);//用宏来替换
void Wirte_Log(char* FileName,char* FuncName,int line,char* log);
#endif //这三个是头文件固定开头,避免头文件内容重复定义
1.c 用于创建一个输出函数
#include<stdio.h> //只要有printf就得有<stdio.h>头文件
#include "1.h"
void Write_Log(char* FileName, char* FuncName, int line, char* log)
{
printf("FileName : %s \n FuncName : %s\n Line : %d\n Log : %s\n",
FileName,FuncName,line,log);
}
日志 main.c
#include<stdio.h>
#include"1.h"
int main()
{
printf("%s\n",__FILE__); //文件宏 这些宏都是系统宏,固定用法
printf("%s\n",__DATE__); //日期宏 这些宏无需定义因此前面就不用定义变量
printf("%s\n",__TIME__); //时间宏
printf("%d\n",__LINE__); //行数宏
printf("%s\n",__func__); //函数宏
LOG("this is a date!"); //函数初始化
return 0; main.c
Jul 17 2023
15:41:36
10
main
FileName : main.c
FuncName : main
Line : 13
Log : this is a test Log!
}
//上述宏用于写日志
4. 指针
在x64系统中,指针占8个字节,指针是指向一块内存的箭头(本质是地址)
&:取地址符号 *:取值符号(取地址里面的值)
在定义变量中,int* a,*指的是定义指针变量
在运算中,*是取值
int a=5;
int* m=&a; //int* m,int*是定义一个int型的指针,m
printf("m: %d\n",m); //m是指针 7f4319ec
printf("m: %d\n",*m); //*m才是值
#include<stdio.h>
void swap(int* a,int* b) //变量是指针
{
int c=*a; //此时c=1
*a=*b;
*b=c;
printf("swap *a: %d *b: %d\n",*a,*b);
}
int main()
{
int a=1;
int b=2;
int* ptr_a = &a; //定义一个int型指针,取a的地址给到这个指针
int* ptr_b = &b;
swap(ptr_a,ptr_b);
printf("a: %d b: %d\n",a,b); //输出swap *a: 2 *b: 1
a: 2 b: 1
}
const int* ptr_a = &a; 常量指针 值不可以改
int* const ptr_a = &a; 指针常量 指针(地址)不可改
5. 数组
数组:一组相同数据类型的元素,地址是连续的
写法:int a[10];
#include<stdio.h>
int main()
{
int a[10]={0}; //数组初始化
for(int i=0;i<10;i++)
{
a[i]=i+1;
printf("%d ",a[i]); //输出数组的值
printf("a[%d] is %x\n",i,&a[i]); //输出,每个的地址
}
printf("array is %d\n",sizeof(a)); //输出数组的内存大小
return 0;
}
#include<stdio.h>
#define ArrayLen(a) sizeof(a) / sizeof(a[0])
void print(int* a,int len) //数组的名字可以当作指针使用,理解成指针
{
printf(" print array size : %ld \n",sizeof(a)); //输出数组a的所占内存大小,8字节(指针8字节)
//数组在作为函数参数被传递时,会被弱化成指针
for(int i=0; i<len; i++)
{
printf("%d ",a[i]); //输出数组a
} //数组中本身就有a[0],a[1],,,,a[9]的概念只是用i将其表现出来
printf("\n");
}
int main()
{
int a[]={1,2,45,63,15,62}; //定义
print(a,ArrayLen(a));
printf("array size: %ld\n",sizeof(a)); //输出整个数组的内存大小
printf("\n");
return 0;
}
三、表达式与运算符
例题:交换两变量值
法一:借助中间变量 法二:数轴法
法三: 位操作
与 & 或 | 非 ~(取反,不等于取反码)
取反需要反符号位 取反码不需要反符号位
-1取反 补码1111 1111 取反是0所有的数,在计算机中的表示都是 补码
异或 ^:相异为1;相同为0
#include<stdio.h>
int main()
{
int a=1; //001
int b=2;
//010
a=a^b; //a=011
b=a^b; //b=001(原a)
a=a^b; //a=010(原b)
printf("a: %d\nb: %d\n",a,b); //输出:a=2;b=1
}
单目运算符(只操作一个参数):++ --
双目运算符:+ - *
三目运算符: ? : 是否满足条件,满足就是:左边,不满足就右边