[C语言] 基础知识

2020-05-13  本文已影响0人  半为花间酒

内容是以前的学习笔记,内容不全,主观性较大,部分基础知识未展示

基础知识

固定格式

#include<stdio.h>
int main(void)
{ 
    
    return 0;
}

// 自定义文件,在当前目录下,则库名不用<>而用""
#include<stdio.h>
int main()
{
    char a='B',b='O',c='Y';
    a=a+32;   //字符型可以加上数字,表示ASCII码变化 字符型+字符型为ASCII码相加
    b=b+32;
    c+=32
    printf("BOY的小写是%c%c%c\n",a,b,c);  //最后一次输出加上\n换行
    return 0;
}
int a;
double b;
char c;
scanf("%d,%lf,%c",&a,&b,&c);   //输入的表示 double需要输入时表示成long float,输出时只要%f即可
// 上述写法不会读入空格
scanf("%c%c%c",&a,&b,&c) // 这种写法会读入空格

getchar(), putchar()

#include<stdio.h>
#define PI 3.1415926  // 定义宏常量
int main()
{
    char a,b,c;
    const double AI=3.1415926; // 定义为不可修改的变量,实际不是常量
    a=getchar(); //getchar()为逐字获取键盘输入,返回值是ASCII码
    b=getchar();
    c=getchar();
    a+=32;
    b+=32;
    c+=32;
    putchar(a); //putchar()输出单字符 a为字符则输出,为数值则表示ASCII码输出对应字符
    putchar(b);
    putchar(c);
    putchar("\n");  //最后一次输出加上\n换行
    return 0;
}

类型修饰符

内容 定义
unsigned int 最高位也是数位,正数范围扩大一倍
signed int 即int

常量及变量

china在内存在占6个字节,即c h i n a NULL,最后一位内存中为\0

\a 响铃; \ddd 三位八进制数; \xhh 两位十六进制数

常量最好使用宏定义

C语言中两个操作数都是整数则结果向下取整 30/4=7

前置和后置的区别

int x,y,i=25;
x=--i;
y=i;
// 前置 x=24,y=24

int x,y,i=25;
x=i--;
y=i;
// 后置 x=25,y=24

赋值嵌套:x=(y=(z=100))

位运算

a=01,b=10
位与 a&b=0
位或 a|b=11
位异或 a^b=11
位反  ~a=10
右移位  a>>n 除于2的n次幂
左移位  a<<n 乘于2的n次幂

sizeof 长度运算 取数据类型或变量的储存长度,字符串要+1

取值类型小的数会自动向取值范围大的数靠

对异常输入的处理

#include<stdio.h>
int main()
{
    int r;
    float x,y,z,t;
    r=scanf("%f %f %f %f",&x,&y,&z,&t);
    if(r==4&&(x>0&&y>0&&z>0&&t>0)) // 关键地方
    {
        printf("%.2f",x+y+z-t);
    }
    else
    {
        printf("error");
    }
    return 0;
}

数学运算

#include<stdio.h>
#include<math.h> //涉及数学运算需加上
int main()
{
    int a=2,b;
    double c=5.02,d,e;
    b=abs(a); //整数求绝对值专用
    c=fabs(a); //任何数求绝对值
    e = pow(c,a); //指数
    return 0;
}
  1. %m.nf

m为总长度,n为小数位数,m为正则向前补空,为负向后补空 如果m前有0则补零

如果m或n是*表示需再赋值或给予变量 printf("%*.*d",7,2,i)

如果是输入中 scanf("%*d%d",&i,&j) 则表示跳过第一个输入值

  1. %e(%m.ne)

科学计数表示,未限定m和n时e前6位,e+三位共5位

  1. (int)(x) 强转 y=(float)(x)

强制转整数,抹去而不是四舍五入

  1. 输入

输入中带有空格,则会跳过输入流中所有空格字符,在多个输入且输入字符时需要注意

scanf("%d%d",&i,&j) 和scanf("%d,%d",&i,&j) 输入不一样,要考虑输入流中不可打印字符

选择语句

#include<stdio.h>
int main()
{
    int a;
    scanf("%d",&a);
    if(a>=60)
    {
        printf("High\n");
    }
    else
    {
        printf("low\n");
    }
    return 0;
}

//if else后面不接分号,且后续就一句或接一个选择语句 大括号可以省略

#include<stdio.h>
int main()
{
    int a;
    scanf("%d",&a);
    if(a>=60)
        printf("High\n");
    else
        printf("low\n");
    return 0;
}

#include<stdio.h>
int main()
{
    int a;
    scanf("%d",&a);
    if(a>=60)
        printf("High\n");
    else
        if(a>=40)
            printf("Middle\n");
        else
            printf("low\n");
    return 0;
}

|| 或 && 且

# 判断一个字母是否为大写

char ch;
scanf("%c",&ch);
if(ch>='A'&&ch<='Z')  //字母可以根据ASCII码比较大小

选择表达式

判断语句可以写成如下形式:

表达式1?表达式2:表达式3

#include<stdio.h>
int main()
{
    int a;
    scanf("%d",&a);
    a>=60?printf("High\n"):printf("low\n");
    return 0;
} 

switch语句

题目:输入成绩 90-100为A,80以上为B,70以上为C,60以上为D,小于60为E

#include<stdio.h>
int main()
{
    double score,a;
    scanf("%lf",&score);
    a=(int)(score/10)
    switch(a)
    {
      case 10: //重复可以放空
      case 9:printf("成绩等级为A\n");break;
      case 8:printf("成绩等级为B\n");break;
      case 7:printf("成绩等级为C\n");break;
      case 6:printf("成绩等级为D\n");break;
      case 5:
      case 4:
      case 3:
      case 2:
      case 1:
      case 0:printf("成绩等级为E\n");break;
      default:printf("输入不正确\n");break; //对异常值的处理
    }
    return 0;
}

循环语句

while循环

先判断再执行一次循环体

题目:2+4+6+…+100

#include<stdio.h>
int main()
{ 
    int n=1,sum=0,a=2;
    while(n<=50) //判断首尾循环以及等号是否成立
    {
       sum+=a;
       a+=2;
       n++;
    }
    return 0;
}

do...while循环

先执行一次循环体再判断

#include<stdio.h>
int main()
{ 
    int n=1,sum=0,a=2;
    do
    {
       sum+=a;
       a+=2;
       n++;
    }
    while(n<=50); //末尾有分号;
    return 0;
}

break/continue

#include<stdio.h>
int main()
{ 
    int n=1,sum=0,a=2;
    while(n<=50)
    {
       sum+=a;
       a+=2;
       n++;
       if(n>=30)
           break;
       if(n==18)
           continue;
    }
    return 0;
}


//也可写成如下
#include<stdio.h>
int main()
{ 
    int n=1,sum=0,a=2;
    while(n<=50&&sum<3000)  //将终止条件取反放到循环条件中
    {
       sum+=a;
       a+=2;
       n++;
       if(n==18)
           continue;
    }
    return 0;
}

for循环

//while循环:
语句1[定义+赋值]
while(语句2[循环条件])
{
    语句3[递进条件]
    循环体
}


//for循环
语句1[定义]
for(语句1[赋值];语句2[循环条件];语句3[递进条件])
{
    循环体
}

定义赋值可以放循环外,递进条件可以放循环内,类似while循环,但前后分号 ; 需保留

//for循环
语句1[定义+赋值]
for(;语句2[循环条件];)
{
    语句3[递进条件]
    循环体
}

数组

定义一维数组

题:输入10个整数

#include<stdio.h>
int main()
{ 
    int i,a[10]; //用一维数组连续定义10个数
    for(i=1;i<=10;i++)
    {
        scanf("%d",&a[i-1])
    }
    return 0;
}

如果是明确赋值可写为:

int a[10]={2,3,4};

上述式子等价于:

int a[10];

a[0]=2;

a[1]=3;

a[2]=4;

a[3]=0;

a[4]=0;

题:输入10个整数,并由小到大排序

//选择排序
#include<stdio.h>
int main()
{ 
    int i,j,k,a[10];
    for(i=0;i<=9;i++)
        scanf("%d",&a[i])
    for(i=0;i<=8;i++)  //循环内跟循环或者选择可以省略大括号
        for(j=i+1;j<=9;j++)
            if(a[i]>a[j])
            {
                k=a[i];
                a[i]=a[j];
                a[j]=k;
            }
    return 0;
}

定义二维数组

int a[2][3]={{1,2,3},{4,5,6}};
int a[2][3]={1,2,3,4,5,6}; //两种写法等同,取前三个为第一行a[0][0]/a[0][1]/a[0][2]

int a[2][3]={{1,2,3},{}}; //没给的数值默认为0,没给的字符默认为\0

输出字符数组

//整体输出 2种方法

// 1.用%s输出
#include<stdio.h>
int main()
{ 
    char c[3][3]={{'C','H','E'},{'N','X','I'},{'G','L','6'}};
    printf("%s\n",c);
    return 0;
}

// 2.puts()
#include<stdio.h>
int main()
{ 
    char c[3][3]={{'C','H','E'},{'N','X','I'},{'G','L','6'}};
    puts(c);
    printf('\n');
    return 0;
}

// \0后的不输出,可在定义数组时多定义一个字符,用\0占据末尾确保程序正确

输入字符数组

//用scanf()输入 "I am ChenXi"
#include<stdio.h>
int main()
{ 
    char c1[6],c2[6],c3[6]; //不足的用\0补齐
    scanf("%s%s%s",c1,c2,c3); //(1)提取的字符串不含空格 (2)c前不需要&存址
    return 0;
}

//gets()
#include<stdio.h>
int main()
{ 
    char c[18];
    gets(c);  //提取的字符串含空格
    return 0;
}

题:输入一行由空格和单词组成的字符串(80个字符内),统计有多少单词

#include<stdio.h>
int main()
{ 
    char c[81];
    gets(c); 
    int sum=0,i;
    if(c[0]!=' ')
        sum=1;
    for(i=0;c[i]!='\0';i++)
        if(c[i]==' '&&c[i+1]!=' '&&c[i+1]!='\0')
            sum++;
    printf("合计有&c个单词\n",sum);
    return 0;
}

函数

调用有参函数

题:输入4个数,输出前两数最大值,后两数最大值,四个数最大值

#include<stdio.h>
int main()
{ 
    float max(float x,float y); //函数的声明,写在开头,加分号
    float a[4],i;
    for(i=0;i<=3;i++)
    {
        printf("请输入第%d个数",i+1);
        scanf("%f",&a[i]);
    }
    max_f=max(a[0],a[1]);
    max_b=max(a[2],a[3]);
    max_t=max(max_f,max_b);
    printf("前两数最大值为%f\n",max_f);
    printf("后两数最大值为%f\n",max_b);
    printf("四个数最大值为%f\n",max_t);
    return 0;
}

float max(float x,float y) //函数的解释,写在主体后面,不加分号
{
    if(x>=y)   //不需要再定义
        return(x);
    else
        return(y);
}

//函数的解释本题也可以写为
float max(float x,float y)
{
    return(x>=y?x:y);
}

调用无参函数

(指无返回值)

题:输入10个整数,输出升序排序

#include<stdio.h>
int main()
{ 
    void sort(int a[],int n);
    int a[10],i;
    for(i=0;i<=9;i++)
    {
        printf("请输入第%d个数",i+1);
        scanf("%d",&a[i]);  
    }
    sort(a,10);
    printf("排序后的整数依次是\n");
    for(i=0;i<=9;i++)   
        printf("%d",a[i]);
    printf("\n"); 
    return 0;
}

void sort(int a[],int n)
{
   int i,j,k;
    for(i=0;i<=n-1;i++)
        for(j=i+1;j<=n;j++)
            if(a[i]>a[j])
            {
                k=a[i];
                a[i]=a[j];
                a[j]=k;
            } 
}

函数嵌套

(最内层函数最后解释)

题:输入4个整数,输出最大数

#include<stdio.h>
int main()
{ 
    int max4(int a,int b,int c,int d);
    int a,b,c,d,max_t;
    scanf("%d,%d,%d,%d",&a,&b,&c,&d);
    max_t=max4(a,b,c,d);
    printf("最大数为%d\n",max_t);
    return 0;
}

int max4(int a,int b,int c,int d)
{
    return(max2(max2(max2(a,b),c),d));
}

int max2(int x,int y)
{
    return(x>=y?x:y);
}

函数递归

题:求n的阶乘

//判明递归函数相邻的关系和递归终止条件
#include<stdio.h>
int main()
{ 
    int jiecheng(int n);
    int n;
    scanf("%d",&n);
    printf("%d的阶乘为%d\n",n,jiecheng(n));
    return 0;
}

int jiecheng(int n)
{
    int results;
    if(n<0)
        printf("输入错误\n");
    else if(n==0||n==1)
        results=1;
    else
        results=jiecheng(n-1)*n;
    return(results);
}

指针

定义指针变量

int *p,a=5;
p=&a;

题:输入两个整数,先大后小输出

#include<stdio.h>
int main()
{ 
    int a,b,*p,*q,*r;
    scanf("%d,%d",&a,&b);
    p=&a;
    q=&b;
    if(a<b)
    {
        r=p;
        p=q;
        q=r;
    }
    printf("%d %d\n",*p,*q);
    return 0;
}

指针变量和一维数组

题:输入5个整数,2倍后输出

#include<stdio.h>
int main()
{ 
    int a[5];
    int *p,i;
    p=&a[0];
    for(i=0;i<=4;i++)   
    {
        scanf("%d",p+i);
        *(p+i)=*(p+i)*2;
    }
    for(;p<=&a[4];p++) //指针和数组已关联
        printf("%d\t",*p);
    printf("\n");
    return 0;
}

知识点

  1. &a[5]=a+5 (知识点1,2是指针变形的核心)
  2. a[5]=*(a+5)
  3. &a[0]=a

指针变量和一维数组相关函数

一、形参是指针变量

函数声明: a[]→*p

函数解释: a[i]→*(p+1)

二、实参是指针变量

函数使用: a→p (数组a是a[0]的指针q)


指针变量和二维数组

int *p,a[2][3]={{1,2,3},{4,5,6}};
p=&a[0][0];
p+5=&a[1][2]

知识点

  1. &a[i][j]=a[i]+j=a[0]+i*列数+j=p+i*列数+j
  2. a[i][j]=*(a[i]+j)

对二维数组而言,降维的元素为指针


指针变量和二维数组相关函数

一、形参是指针变量

函数声明: a[][某数]→*p

函数解释: a[i][j]→*(p+i*列数+j)

函数使用: a→*a

二、实参是指针变量

函数使用: a→*p (使用前先关联)


指针变量指向二维数组的行变量

int a[3][4]={{1,2,3,4},{4,5,6,7},{4,5,6,6}};
int (*p)[4];  //(*p)[某数] 该指针为指向数组的行变量

p=a; //指向数组的第一行
p=a+1; //指向数组的第二行

用指向二维数组行变量的指针变量做形参数

函数声明: a[][某数]→(*p)[某数]

函数解释: a[i][j]→*(*(p+i)+j)


指针变量和字符串相关函数

(字符串等同一维数组)

void dec(char old[],char new[])
{
    int i=0;
    for(;old[i]!='\0';i++)
        new[i]=old[i];
    new[i+1]='\0';
}

//形参改为指针变量
void dec(char *p,char *q)
{
    int i=0;
    for(;*(p+i)!='\0';i++)
        *(q+i)=*(p+i);
    *(q+i+1)='\0';
}

指针可以直接指向字符串

char *p;
p="ChenXi";

指针函数

题:输入两个整数,用指针函数输出两者大值

#include<stdio.h>
int main()
{ 
    int max(int x,int y);
    int a,b,max_t;
    int (*p)(int,int); //定义指针函数,注意格式
    p=max; //两个函数进行关联
    printf("请输入两个整数: \n");
    scanf("%d,%d",&a,&b);
    printf("两数中较大值为: %d",(*p)(a,b));
    return 0;
}

int max(int x,int y)
{
    return(x>y?x:y);
}

返回指针值的函数

题:3个学生1/2/3各四门成绩,输入学生序号后输出4门成绩

思路:

输入序号后调用函数返回行指针,另一个普通指针指向行指针初始值一次性输出

#include<stdio.h>
int main()
{ 
    float *search(float (*p)[4],int n);  //返回值是指针的函数标识方法
    float a[3][4]={{87,88,94,65},{74,86,93,81},{82,75,93,83}};
    float *p;
    int num,i;
    printf("请输入学生序号");
    scanf("%d",&num);
    printf("第%d名学生的成绩为: \n",num);
    p=search(a,num-1);   //调用时候放的是数组,声明的时候是行变量
    for(i=0;i<=3;i++)
        printf("%f\n",*(p+i));
    printf("\n");
    return 0;
}

float *search(float (*p)[4],int n)
{
    int *q;
    q=(p+n)[0];
    return(q);
}

结构体

定义结构体

struct student
{
  int student_id;
  char name[30];
  char sex;
  float score;
};  
struct student a={001,"ChenXi",'M',99.5};
//结构体的格式 末尾的大括号后面跟分号

//也可以写作如下
struct student
{
  int student_id;
  char name[30];
  char sex;
  float score;
}a={001,"ChenXi",'M',99.5};

题:学生信息放于结构体变量中,然后输出

#include<stdio.h>
struct student
{
  int student_id;
  char name[30];
  char sex;
  float score;
}a={001,"ChenXi",'M',99.5};
int main()
{ 
    printf("学号:%d\n姓名:%s\n性别:%c\n成绩:%f\n:",a.student_id,a.name,a.sex,a.score);
    //注意结构体内变量的写法
    return 0;
}

//结构体定义和赋值放在int main()以前
#include<stdio.h>
struct student
{
  int student_id;
  char name[30];
  char sex;
  float score;
}a;
int main()
{ 
    printf("%d,%s,%c,%f",&a.student_id,a.name,&a.sex,&a.score); //字符串的输入(数组)不需要&
    return 0;
}

结构体数组

struct student
{
  int student_id;
  char name[30];
  float score;
}students[3]={{001,"ChenXi",99.5},{002,"ChenX",99.7},{003,"Chen",89.5}};  

结构体变量和指针变量

#include<stdio.h>
struct student
{
  int student_id;
  char name[30];
  float score;
}a={001,"ChenXi",99.5};
int main()
{ 
    struct student *p;
    p=&a;
    printf("学号:%d\n姓名:%s\n成绩:%f\n:",(*p).student_id,(*p).name,(*p).score);
    return 0;
}

//也可以写作如下
printf("学号:%d\n姓名:%s\n成绩:%f\n:",p->student_id,p->name,p->score);
上一篇下一篇

猜你喜欢

热点阅读