C语言基础语法

基础语法

理解int main(int argc,char const *argv[])

https://blog.csdn.net/weixin_68123569/article/details/126349348

https://blog.csdn.net/yang_chengfeng/article/details/49406443

malloc函数

  • 函数原型:extern void *malloc(unsigned int num_bytes); // 意为分配长度为num_bytes字节的内存块

    • malloc是动态内存分配函数,用于申请一块连续的指定大小的内存块区域以void*类型返回分配的内存区域地址

    • #include<malloc.h>

    • 如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。

    • malloc函数的返回的是无类型指针,在使用时一定要强制转换为所需要的类型。

    • 在使用malloc开辟空间时,使用完成一定要释放空间,如果不释放会造内存泄漏。

    • mallo函数返回的实际是一个无类型指针,必须在其前面加上指针类型强制转换才可以使用
      指针自身 = (指针类型*)malloc(sizeof(指针类型)*数据数量)

    • 	int *p = NULL;
        	int n = 10;
        	p = (int *)malloc(sizeof(int)*n);
      
  • free函数: 释放malloc(或calloc、realloc)函数给指针变量分配的内存空间。

前言

从b语言发展 <== BCPL<== FORTRAN

  • 程序框架
#include <stdio.h>

int main()
{

return 0;
}

/*多行注释*/  
// 单行注释是C99独有的

输入输出

printf("%d", 12+35);
printf("12+35=%d", 12+35);
scanf("%d", &price); // “格式字符串”,&取地址
const int AMOUNT = 100;//常量不可修改
//一次性输入输出多个
scanf("%d %d", &Amount, &price);
scanf("%d, %d", &Amount, &price);
printf("找您%d-%d = %d元。\n", Amount, price, Amount - price);

变量

  • eg:int mount, price;

标志符构造规则:子母、数字、下划线,数字不能在第一位。

  • 浮点数,定点数

    double price;
    double Amount; //双精度浮点数,float 单精度"%f"
    scanf("%lf ,%lf", &Amount, &price);
    int foot = 100*cm/0.3048;//int自动把浮点变成整形
    printf("%x", x);//输出为12进制
    
  • 计算:

    a = 10; a++ = 10; a = 11;
    ++a = 12; a = 12;
    单目运算符:a*-b ==> a*(-b)
    

交换变量的值

int a = 6, b = 5, c;
c = a;
a = b;
b = c;
printf("a = %d, b = %d", a, b);

判断

if(){ ;}
else if(){;}
else{;}
=====================
case是一个路牌,不会阻止程序往下继续执行,break才可以。
int type;
    scanf("%d", &type);
    switch(type) //type是一个表达式
    {
    case 1:
        printf(".\n");
        break;
    case 2:
        printf("..\n");
        break;
    case 3:
        printf("...\n");
    case 4:
        printf("....\n");
        break;
    }
  • 比较运算符:printf(“%d\n”, 5==3); //输出0

    • 例如 != 此类关系运算符的优先级比算数运算符低,比赋值运算符高。 eg:int r=a>; 7 >= 3+4;

      eg:6>5>4 运算6>5结果是1,再判断1>4,最终结果是0
      

循环

while(条件){循环体;}
  • do-while 循环

    //先进循环体,再判断条件
    do{循环体;} while();
    
  • for 循环

    for(i=1;i<n;i++){;}
    
  • break :打破这个循环

    continue :把这一轮没做的步骤放弃直接进入下一轮循环

  • goto 与out连用,goto out 跳到 out 所在的锚点,用于直接跳出多重循环

    int main()
    {
    	int x;
    	int one, two, five;
    
    	scanf("%d", &x);
    	for ( one = 1; one < x*10; one++ ) {
    		for ( two = 1; two < x*10/2; two++ ) {
    			for ( five = 1; five < x*10/5; five++ ) {
    				if ( one + two*2 + five*5 == x*10 ) {
    					printf("可以用%d个1角加%d个2角加%d个5角得到%d元\n", one, two, five, x);
    					goto out;
    				}
    			}
    		}
    	}
    out:
    	return 0;
    }
    

输出n以内的素数

int main(){
    int x, n, amount = 0;
    scanf("%d", &n);
    int i;
    for(x=2;x<n;x++){
        int isPrime = 1;
        for(i=2;i<x;i++){
            if(x%i == 0){
                isPrime = 0;
                break;
            }
        }
        if(isPrime){
            amount++;
            printf("%d ", x);
            if(amount%5 == 0) printf("\n"); //每隔5个数换行
        }
    }
}
int isPrime(int n)
    {
        int i, isPrime = 1;
        for(i=2;i<n;i++){
            if(n%i == 0){
                isPrime = 0;
                break;
            }
        }
        return isPrime;
    }

整数分解正序输出

int main()
{
    int x;
    scanf("%d", &x);
	int mask = 1;
	int t = x;
    //计算所给x的位数对应的mask值(123对应100)
    while(t>9){
        mask *= 10;
        t /= 10;
    }
	printf("x=%d, mask=%d\n", x, mask);
	while(mask>0){
        int d = x/mask;
		printf("%d ", d);
		x %= mask;
		mask /= 10;
	}
	return 0;
}

最大公约数(辗转相除法)

int main()
{
    int m, n, t, sum;
    scanf("%d %d", &m,&n);
    sum = m*n;
    while(n>0){
        t = m%n;
        m = n;
        n = t;
    }
    printf("最大公约数:%d", m\n);
    printf("最小公倍数:%d", sum/m);
	return 0;
}

水仙花数(n位正整数每个位上的n次幂之和等于其本身)

int main()
{
    int n;
    scanf("%d", &n);
    int t=1, j=1;
    while(j<n){
       t *= 10;
       j++;
    }
    printf("%d\n", t);
    //遍历10^n-1到10^n
    int i;
    for(i=t;i<t*10;i++){
        int x = i, sum = 0, d;
        while(x>0){
            d = x%10;
            x /= 10;
            int k=1;
            int b = d;
            while(k<n){
                b *= d;
                k++;
            }
            //printf("%d\n", b);
            sum += b;
        }
        if(sum == i){printf("%d\n", i);}
    }
	return 0;
}

数据类型

  • sizeof :

    • 是静态运算符(结果在编译时决定)

    • sizeof括号里的运算不会做

      long a = 9;
          printf("%d\n", sizeof(int));
          printf("%d\n", sizeof(++a));
          printf("%d\n", sizeof(a+1.0)); //判断a+1.0结果的类型但不会做计算
          printf("%d\n", a);
      
  • 整形

在这里插入图片描述

  • 数的范围:
char c = 255;
int i = 255;
printf("%d  %d\n", c, i);
  • unsigned – 无符号整数

    unsigned char c = 255; //0-255
    int i = 255;
    printf("%d  %d\n", c, i);
    
  • 0 – 八进制 0x – 十六进制

    char c = 012;
    int i = 0x12;
    printf("%o  %x\n", c, i); //八进制、十六进制输出
    
  • 浮点数

在这里插入图片描述

%e – 科学计数法表示

float有效位7位, double有效位15位。

  • 浮点的范围和精度

在这里插入图片描述

printf("%f\n", 12.0/0.0);
printf("%f\n", -12.0/0.0);

float a,b,c;
a = 1.235f;  //加f表示float,不加默认double
b = 1.236f;
c = a+b;
if(c == 2.471) printf("相等\n");
else printf("不相等,c=%f\n", c);
  • 字符

    char a;
    a = 49; //49代表字符'1'
    printf("%c\n", a);
    

在这里插入图片描述

char i= 'C'+'a'-'A';
printf("%c", i);

scanf(“%d %c”);//若中间没有空格,那么整数只读到整数结束为止。

  • 逃逸字符

在这里插入图片描述

printf("123\t456\n");
printf("12\t456\n");
  • 类型转换

在这里插入图片描述

  • 强制类型转换

在这里插入图片描述

  • bool

    #include  <stdbool.h>
    bool a = 4>5;
    printf("%d\n", a);
    
  • 优先运算

在这里插入图片描述

  • 条件运算符

逗号运算符:i = (3+4, 5+6); //此时i = 11

函数

在这里插入图片描述

  • 本地变量

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

一个例子:

int isPrime(int n)
    {
        int i, isPrime = 1;
        for(i=2;i<n;i++){
            if(n%i == 0){
                isPrime = 0;
                break;
            }
        }
        return isPrime;
    }


int main()
{
    int n;
    scanf("%d", &n);
    printf("是否质数:%d", isPrime(n));
	return 0;
}

数组

  • 定义:

    int numble[100]; //定义数组 ,100int。
    

    长度为0的数组可以创建但没意义。

    一个例题:统计每一种数字出现的次数。

    int main()
    {
        const int number = 10;
        int x;
        int count[number];
        int i;
        for(i=0;i<number;i++){
            count[i] = 0;
        }
        scanf("%d", &x);
        while(x!=-1){
            if(x>=0 && x<=9){
                count[x]++;
            }
            scanf("%d", &x);
        }
        for(i=0;i<number;i++){
            printf("%d:%d\n", i, count[i]);
        }
    	return 0;
    }
    

在这里插入图片描述

int a[10] = {0}; //都是0
int a[] = {0,1,2,3,4,5,6,7,8,9}; //单位10
int a[10] = {[1]=2,4,[5]=7}; //位置1为2后面接着4

int main()
{
    int a[10] = {0}; //都是0
    int i;
    for(i=0; i<10; i++){
        printf("%d\t", a[i]);
    }
	return 0;
}
  • sizeof:占据多少字节

    int a[10] = {[1]=2,4,[5]=7}; //位置1为2后面接着4
    int i;
    printf("%lu\n", sizeof(a));
    printf("%lu\n", sizeof(a[2]));
    for(i=0; i<sizeof(a)/sizeof(a[2]); i++){
        printf("%d\t", a[i]);
    }
    
  • 数组赋值:

在这里插入图片描述

筛选法求素数

int isPrime(int x,int KnownPrime[],int numberOfKnownPrimes)
{
    int ret=1,i;
    for(i=0;i<numberOfKnownPrimes;i++){
        if(x%KnownPrime[i]==0){
            ret = 0;
            break;
        }
    }
    return ret;
}
int main()
{
    const int number = 100;
    int prime[number]; //储存所有的素数
    prime[0] = 2; //定义第一个素数是2
    int count=1,i=3; //从3开始看是否素数
    while(count<number){
        if(isPrime(i,prime,count)){
            prime[count++] = i;
        }
        i++;
    }
    for(i=0;i<number;i++){
        printf("%d\t", prime[i]);
        if((i+1)%5==0) printf("\n");
    }
	return 0;
}

选择法排序

int main()
{
    int a[10];
    int i;
    int j,min,t;
    for(i=0;i<10;i++){
        scanf("%d", &a[i]);
    }
    //交换
    for(i=0;i<9;i++){
        min = i;
        for(j=i+1;j<10;j++){
            if(a[j] < a[min])min = j;
        }
        t = a[i];
        a[i] = a[min];
        a[min] = t;
    }
    //输出
    for(i=0;i<10;i++){
        printf("%d\n", a[i]);
    }
	return 0;
}

插入一个数字排序

int main()
{
    int a[10];
    int i;
    for(i=0;i<9;i++){
        scanf("%d", &a[i]);
    }
    int x;
    scanf("%d", &x);
    for(i=0;i<9;i++){
        if(x<=a[i]){
            int j,t1,t2;
            t1 = x;
            for(j=i;j<10;j++){
                t2 = a[j];
                a[j] = t1;
                t1 = t2;}
            break;
        }
    }
    for(i=0;i<10;i++){
        printf("%d\n", a[i]);
    }
	return 0;
}

3*3的转置数组

#include <stdio.h>
#include  <stdbool.h>
#include  <math.h>

int T(int a[3][3])
    {
        int i,j,t;
        for(i=0;i<3;i++){
            for(j=0;j<i;j++){
                t = a[i][j];
                a[i][j] = a[j][i];
                a[j][i] = t;
            }
        }
        return a[3][3];
    }
int main()
{
    int a[3][3];
    int i;
    for(i=0;i<3;i++){
        scanf("%d %d %d", &a[i][0],&a[i][1],&a[i][2]);
    }
    T(a);//转置
    for(i=0;i<3;i++){
        printf("%d %d %d\n",a[i][0],a[i][1],a[i][2]);
    }

	return 0;
}

字符串逆序输出

#include  <string.h>

void f(char str[])
{
    int i,j,t;
    for(i=0,j=strlen(str)-1; i<strlen(str)/2; i++,j--){
        t = str[i];
        str[i] = str[j];
        str[j] = t;
    }
}
int main()
{
    char str[10000];
    scanf("%s", str);
    f(str);//逆序函数
    printf("%s", str);
	return 0;
}

统计各种字符个数

void f(char str[])
{
    int i,Ec=0, num=0, tab=0, oth=0;
    for(i=0;str[i]!='\0';i++){
        if((str[i]>='a' && str[i]<='z') || (str[i]>='A' && str[i]<='Z')) Ec++;
        else if(str[i]>='0' && str[i]<='9') num++;
        else if(str[i]==' ') tab++;
        else oth++;
    }
    printf("%d %d %d %d", Ec,num, tab, oth);
}
int main()
{
    char str[10000];
    gets(str);
    f(str);
	return 0;
}

指针

  • 取运算的地址:&后必须是个明确的变量(十六进制)

    int i=1;
    int a;
    printf("%p\n", &i); //取地址
    printf("%p\n", &a); //自上向下分配地址
    
    int a[10];
    printf("%p\n", &a); //0060FED8
    printf("%p\n", a); //0060FED8
    printf("%p\n", &a[0]); //0060FED8
    printf("%p\n", &a[1]); //0060FEDC
    
  • 指针:

    保存地址的变量

    int *p=&i; //*表示p是指针,保存i的地址。
    int *p,q; //只有p是指针。
    

在这里插入图片描述

void f(int *p)
{
    printf("p=%p\n", p);
    printf("*p=%d\n", *p);
    *p = 26; //通过p的地址改变了p的值
}
//通过指针交换变量
void swap(int *a,int *b)
{
    int t;
    t = *a;
    *a = *b;
    *b = t;
}
int main()
{
    int a=2,b=3;
    swap(&a,&b);
    printf("a=%d b=%d", a,b);
	return 0;
}
  • 用于有多个返回值的函数

    void minmax(int a[], int len, int *max, int *min)
    {
        int i;
        *min = *max = a[0];
        for(i=1;i<len;i++){
            if(a[i]<*min){*min = a[i];}
            if(a[i]>*max){*max = a[i];}
        }
    }
    int main()
    {
        int a[] = {1,65,21,8,9,6,23,49,56,7,54,32,12,8};
        int min,max;
        minmax(a, sizeof(a)/sizeof(a[0]), &min, &max); //传入地址
        printf("max=%d min=%d", max,min);
    	return 0;
    }
    
  • 结果用指针返回,函数返回运行的状态(返回特殊的不属于有效范围内的值表示出错)。

    int divide(int a, int b, int *result)
    {
        int ret = 1;
        if(b==0) ret = 0;
        else *result = a/b;
        return ret;
    }
    int main()
    {
        int a=5, b=2;
        int c;
        if(divide(a,b,&c)){
            printf("%d", c);
        }
    	return 0;
    }
    
  • 在函数参数表中出现数组指的是指针:(一下四种等价) 数组变量是特殊的指针,是常量指针不能两个数组间直接赋值。

    • int sum(int*a, int n);
    • int sum(int*, int );
    • int sum(int a[], int n);
    • int sum(int a[], int );
    int a[10];
    int *p = a; //不需要&取地址符 &a[1]需要的
    a = &a[0];
    
    
    一个例子:
    void f(int *b)
    {
        printf("f b %u\n", sizeof(b));
        printf("f b %p\n", b);
    }
    int main()
    {
        int a[5] = {1,2,3,4,5};
        printf("main a %u\n", sizeof(a));
        printf("main a %p\n", a);
        f(a);
        int x = 5;
        int *p = &x;
        printf("*p = %d\n", *p);
        printf("p[0] = %d\n", p[0]); //p可以看成p[1]数组
    	return 0;
    }
    
  • const 指针:

    int *const p = &i; //p是const,即永久指向i的地址。
    *p = 20; //可行
    p++; //不可行,p不可改变。
    
    const int *p = &i;
    *p = 20; //不可行,不能通过p给所指的对象赋值。
    i = 20; //可行,i不是const。
    p = &j; //可行,p可以指向别的变量。
    

在这里插入图片描述

在这里插入图片描述

int main()
{
    char ac[] = {1,2,3,4,5};
    char *p = ac;
    printf("%p\n", p);
    printf("%p\n", p+1); //char一个字节
    int ai[] = {1,2,3,4,5};
    int *q = ai;
    printf("%p\n", q);
    printf("%p\n", q+1);  //int四个字节
    printf("%d\t", *p+1);
    printf("%d\t", ac[1]); //ac[1]与*p+1等价
	return 0;
}

指针减法是减的字节数/sizeof()

  • 0地址

在这里插入图片描述

  • 不同类型指针不能相互赋值

在这里插入图片描述

字符串

结构

结构类型

  • 枚举:在这里插入图片描述
enum color{red, yellow, green};

void f(enum color c)
    {
        printf("%d\n", c);
    }
int main()
{
    enum color t = yellow;
    scanf("%d", &t);
    f(t);
	return 0;
}

在这里插入图片描述

  • 结构体:

    struct date{  //声明了一个叫date的结构类型
        int month; //成员
        int day;
        int year;
    }; //记得有分号
    
    int main()
    {
        struct date today;
    
        today.month = 02;
        today.day = 14;
        today.year = 2022;
    
        printf("%i-%i-%i\n", today.year,today.month,today.day);
    	return 0;
    }
    

在这里插入图片描述

  • 结构成员可以时不同类型,用.运算符和名字访问。eg:today.month,today时结构成员。
  • 结构名字不是地址,要用&取到地址。

在这里插入图片描述

struct date{  //声明了一个叫date的结构类型
    int month; //成员
    int day;
    int year;
}; //记得有分号

int main()
{
    struct date today;
    today = (struct date){2023,03,26}; //转换成该结构
    struct date day;
    day = today;
    printf("%i-%i-%i\n", today.year,today.month,today.day);
	printf("%i-%i-%i\n", day.year,day.month,day.day);
	return 0;
}

结构中的指针

在这里插入图片描述

在这里插入图片描述

struct point{
	int x;
	int y;
};

struct point* getStruct(struct point*);
void output(struct point);
void print(const struct point *p);

int main(int argc,char const *argv[]){
	struct point y={0,0};
	getStruct(&y);
	output(y);//output的参数是一个结构变量,它会输出结构变量的成员变量
	output(*getStruct(&y));//*getStruct(&y)相当于返回的是一个结构变量而不是结构变量的指针
	print(getStruct(&y));
}

struct point* getStruct(struct point *p){ //定义了一个名为getStruct的函数,该函数接受一个指向point结构体的指针作为参数,并返回一个指向point结构体的指针
	scanf("%d",&p->x);//指针所指结构变量的成员
	scanf("%d",&p->y);
	//printf("%d,%d\n",p->x,p->y);
	return p;
}

void output(struct point p){
	printf("%d,%d\n",p.x,p.y);
}

void print(const struct point *p){//const代表不改变这个指针
	printf("%d,%d",p->x,p->y);
}

结构中的结构

在这里插入图片描述

在这里插入图片描述

struct point{
	int x;
	int y;
};

struct rectangle{
    struct point p1;
    struct point p2;
};

void printRect(struct rectangle r)
{
    printf("(%d,%d),(%d,%d)\n", r.p1.x,r.p1.y,r.p2.x,r.p2.y);
}

int main(int argc,char const *argv[]){
    struct rectangle rects[] = { //结构数组struct rectangle rects[],结构中的结构
        {{1,2},{3,4}},
        {{5,6},{7,8}}
    };
    int i;
    for(i=0;i<2;i++){
        printRect(rects[i]);
    }
}

联合

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

typedef union{
    int i;
    char ch[sizeof(int)];
}CHI;

int main()
{
    CHI chi;
    int i;
    chi.i = 1234; //0x04d2是1234的16进制树
    for(i=0;i<sizeof(int);i++){
        printf("%02hhx\n", chi.ch[i]); //%02hhx输出的16进制字节
    }
}

在这里插入图片描述

全局变量

在这里插入图片描述

静态本地变量(全局生存期,本地作用域)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

编译预处理和宏和头文件

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

带函数的宏

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

头文件

在这里插入图片描述

在这里插入图片描述

#ifndef _MAX_H_ //避免重复定义
#define _MAX_H_


#endif

可变数组

const BLOCK = 20;
typedef struct {
    int *array;
    int size;
}Array; //自己创建的可变数组,大小和一个指针(用于储存数据)

Array array_creat(int init_size);//创建可变数组
void array_free(Array *a);
int *array_size(const Array *a);
int *array_at(Array *a,int index);
void array_inflate(Array *a,int more_size);

Array array_creat(int init_size)
{
	Array a;
	a.size = init_size; //数组a的大小
	a.array = (int*)malloc(sizeof(int)*a.size);
	return a;
}

void array_free(Array *a)
{
    free(a->array);//释放指针a指的数组
    a->array=NULL;
    a->size=0;
}

int *array_size(const Array *a)//封装
{
    return a->size;
}

int *array_at(Array *a,int index)
{
	if(a->size<=index)
		array_inflate(a,(index/BLOCK+1)*BLOCK-a->size);
	return &(a->array[index]);
}

void array_inflate(Array *a,int more_size)
{
	int *p=(int *)malloc(sizeof(int)*(more_size+a->size));
	int i;
	for(i=0;i<a->size;i++)//将之前的值逐一拷贝
	{
		p[i]=a->array[i];
	}
	free(a->array);
	a->array=p;
	a->size+=more_size;
}
int main()
{
    Array a = array_creat(100);
    printf("%d\n", array_size(&a));
    *array_at(&a,0) = 10;
    printf("%d\n", *array_at(&a,0));
    int number=0;
    int cnt=0;
    while(number != -1){
        scanf("%d",&number);
        if (number!=-1){
            *array_at(&a,cnt++)=number;
        }
        array_free(&a);
    }
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值