C语言基础

学习笔记,小白可以相互学习,大佬看到能告诉咱理解不对的地方就好了。

仅仅用来提醒自己那些需要注意的,自己没记好的;


计算机:

哈佛结构,哈佛结构是一种将程序指令存储和数据存储分开的存储器结构

冯诺依曼结构,是一种将程序指令存储和数据存储合并在一起的存储器结构


C语言

流程:   编辑   ----   编译、链接   -----  执行
   vim            gcc                a.out   //  gcc test.c -o test

构成

32个关键字:
存储类型: auto const extern register  volatile  static   signed  unsigned
数据类型:   char    short    int       long    float  double  
控制语句:   if   else  switch  case default  for  do   while  goto     
continue   break  return
空类型:   void  
构造类型: enum   union  struct 
求字节大小: sizeof
取别名:     typedef

标识符 程序员自己命的名字
运算符:算术运算符:关系运算符:逻辑运算符:位运算符:赋值运算符:三目运算符:
控制语句:顺序语句,分支,循环
标点符号: ,  ---> 间隔   ;  ---> 代表一个语句的结束

ASCII码表


字符表   用单引号括起来'a'  --- 97,'A'  --- 65,'0'  --- 48,'\0' --- 0  //空字符' '  --- 32,'\n' --- 10

// 数字和数字字符之间的转换!
//大小写转换
//字符比较 --->   比较的是ASCII码值
 / ---- 转义字符

计算机 最小的存储单位  ---  字节  byte ,1个字节 = 8位

计算机存储:  

二进制:   0   1   满2进制,十进制:  0 1 2 3 4 5 6 7 8 9  满10进1,八进制:  0 1 2 3 4 5 6 7,十六进制: 0 1 2 3 4 5 6 7 8 9 a b c d e f   // 0x


数据类型

signed:    有符号    (如果不写,默认都是有符号的)// 有符号数最高位 表示符号位!!!  0--->正数   1---->负数

unsigned:  无符号

char :   

字符类型  -----> 属于整型

1个字节 8位  --> 0000 0000 ~ 1111 1111  --->  0 ~ 2^8 - 1 ---> 0 ~ 255
signed  :   0 000 0000~0 111 1111 ----> 0 ~ 2^7 - 1 (0~127)
1 000 0000~1 111 1111 ----> -128 ~ -1 (-2^7 ~ -1)
  //存储过程中,正数,转换为2进制,原样存储(原码存储)
// 负数存储 -->  按补码的方式存储
补码 == 原码  按位 取反  +  1

unsigned:   0 ~ 2^8 - 1

short :   短整型    

2个字节 16位 --> 0000 0000 0000 0000 ~ 1111 1111 1111 1111 --> 0 ~ 2^16-1
signed :   0 ~ 2^15-1     -2^15 ~ -1
// (-2^15 ~ 2^15-1)
unsigned:0 ~ 2^16-1

int : 

4个字节 32位 --> 0 ~ 2^32 -1
signed  :  (-2^31) ~ (2^31-1)
unsigned: 0 ~ 2^32 -1

long: 长整型

4个字节 32位 --> 0 ~ 2^32 -1
signed  : (-2^31) ~ (2^31-1)
unsigned:0 ~ 2^32 -1

float

4个字节  32位
1位符号位
8位指数位
23位小数位
精度:   5-6

double

8个字节  64位
1位符号位
11位指数位
52位小数位
精度:  15-16

标识符

程序员自定义 的名字

规则:
1、只能由 字母 数字 下划线组成
2、只能以 字母 下划线开头
3、不能与关键字相同
//严格区分大小写     Ab  AB  ab  aB   四个不同的标识符

常量

   //不会更改的

整型常量: 10  076 0x76 0b1010101  -2 -9
浮点型常量: 1.23 3.14  -6.28   1234.5678 -0.001234
指数常量:     1.2345678e+3          -1.234e-3
字符常量:   'a'  'A' '0'   ---> ASCII码表中的字符
字符串常量:  多个字符串在一起  "hello"  "张三"  "0288888"
标识常量:  #define N 10

变量

<存储类型> <数据类型> <变量名>;
每一个变量都有属于自己的存储空间   空间大小  由 数据类型决定

存储类型: auto const extern register  volatile  static
auto :  自动类型   (默认状态下就是自动类型)
自动在栈区中开辟 (数据类型)

register: 寄存器类型
在CPU上有很多很珍贵的寄存器(数量很少)
如果使用 register ,申请把这个变量放到寄存器中去

//不一定申请的到(不代表没有)  申请不到 会转化为自动类型

static : 静态类型

static作用(限定作用域,改变存储区)
修饰全局变量限定作用域,只用于当前文件
修饰局部变量存储区发生改变,由栈区变为静态区
修饰函数同上上



volatile:  防优化   //每一次读值,都会从内存中重新读取!

全局变量与局部变量

全局变量

(全局变量区)

局部变量

(栈区)

定义在所有模块外定义在模块内部

适用范围:

整个文件中

用extern声明可用于

整个程序

适用范围:

当前模块


生命周期:

从定义开始到程序

结束

生命周期:

从定义到模块结束



4g虚拟内存图

虚拟内存图
4gkernel内核
3g环境参数 
 命令行参数main的参数
 栈区操作系统自动
开辟或者释放
 mmp内存映射
 堆区手动开辟释放
malloc,free
也叫全局
变量区
(静态区)
.bass
.data
未初始化全局变量
初始化全局变量
 字符串常量区 
0代码段 

运算符

算数运算符(浮点型不能取余%),关系运算符(0为假,非0为真),逻辑运算符(&&,!,||),位运算符(&与,|或,~取反,^异或,>>右移,<<左移)

printf修饰符

printf修饰符
m输出数据域宽,数据长度<m,左补齐空格
.n对实数,指定的小数点后位数(四舍五入)
对字符串,指定实际输出位数
-输出数据左对齐(缺省是右对齐的)
+指定在有符号数的整数前面显示正号(+)
0输出数值是指定左面不使用的空位置自动填0
#在8,16进制数前面显示前到0,0x
l在d,o,x,u前,指定输出精度为long型
l在e,f,g前,指定输出精度为double型


scanf:
*抑制符:指定输入项读入后不赋值给变量,例如scanf(“%*c%c”,&a);
ch = getchar()可用来清除输入的换行
scanf(“  %c”,&a);%前面有一个空格可以用来滤除所有的空白字符


指针:

*解引用,&取地址符,这2个互为逆运算
const int a;int const a;表示a不可更改(常量化)
const int *p=&a;不可更改*p,但是可更改a和p//可以修改原来的值,也可以修改指针变量里存放的地址,但是不能通过间接访问去改变原来的值
int const *p=&a;同上
int * const p=&a;p不可更改

指针变量:int *p=&a;p就是指针变量,类型为int *;指针变量中装的是地址,大小是固定的32位系统中是4个字节

指针数组:(本质是数组)
int *n【10】={&a,&b,&c……};n有10个元素,每个元素都是一个指针(这个指针是指向一个整型数组的)

数组指针:(本质是指针)
int (*p)【10】=&a;指向一整个数组的指针,这个数组有10个元素,每个元素都是int类型,数组首地址是a

二维数组指针:
(*p)[i] = *((*p)+i);p[i][j] = *((*p)+i+j)

函数

特点:1.功能的封装(重复利用,模块化)
2.函数在使用之前必须声明
3.main和普通函数一样,没有任何差别
4.头文件基本上都是函数的声明或者全局数据


定义宏:
头文件格式:例如:maopao.h
#ifndef MAOPAO_H    //如果没有H这个宏一般所有字母大写中间用_代替
#define MAOPAO_H  //那么就定义这个宏
/*具体内容*/
#endif     //表示结束

归纳分析:
1.一个表达式分析从标识符入手
2.分析:标识符左右两边找到可以结合的部分
3.从结合后整体的左边开始分析(*左结合)//*a[10]   --->a[10]是一个有10个元素的数组--->每个元素都是一个指针
4.整个表达式(语句)--->把分析出来的去掉--->结合格式去看
//<数据类型><数组名>[元素个数]
//int *                 a            [10]
5.看剩下部分代表什么,在通过相同的方法分析剩下的部分
1.[]--->数组 *--->指针     尾巴上看到()--->函数
2.结合格式分析的类型
//<数据类型><变量名>
//<数据类型><数组名>[元素个数]
//<数据类型>*<指针变量名>
//<数据类型><函数名>(参数列表)
//变量名,数组名,指针变量名,函数名都是程序员自己定义的标识符
//去掉标识符,就是整个标识符的类型
// int (*p[10])(int n)
*p[10]--->p[10]是一个有十个元素的数组,每个元素都是一个指针
用m取代p[10]   --->int(*m)(int n)-->*m就是一个指针变量
int (int n)--->参数类型为int,返回值为int的一个函数--->m就只一个指向函数的指针

分析指针:
1.地址:地址的数据类型--->就是该数据元素的数据类型+*
2.指针变量的数据类型--->指向的数据元素类型+*
3.*--->解引用(后面必须跟地址)//指向后面的地址空间(取不取内容看左值还是右值)
4.* 和 &互为逆运算
//int a=10;int *p=&a;
a的类型为int ,p的类型为int *
&a的类型int *,&p的类型int **
*(&p)==p,*(int **)==int*
*(&a)==a,*(int*)==int

函数与指针
指针函数:
int *func(int n);//func是一个参数为int类型,返回值是int *类型的函数,func的类型为int * (int)

函数指针:
void func(int n);
void (*p)(int n) = &func;//定义一个指针指向一整个函数--->函数指针

void *p =NULL;
p = &func;//&func的类型为*(int *(int))
(*(int (*)(int ))p)(int n);//void(int n)强制转换p的类型与func一样


递归函数:
1.自己调用自己完成
2.递归必须要有结束条件,找到跳出口
3.递归代码很简洁(但是不提倡,能不用就不用,耗费内存)

结构体:(4字节对齐,一般同类型的写在一起)
struct stu{
成员信息;
}


/***************求素数***********************************************/
#include<stdio.h>
int ss();
int main()
{
    int p;
    p=ss();
    printf("******一共有素数%d个******\n",p);
    return 0;
}

int ss()
{
    int i,j;
    int a = 0,k = 0;
    for ( i = 101 ; i < 500 ; i++ )
    {
        for ( j = 2 ; (j < i); j++)
        {
            if(i%j == 0)
            {
                k =1;
            }
        }
        if ( k == 0)
        {
            printf("%d\n",i);
            a++;
        }
        k = 0;     
    } 
    return a;
}


/****************除法******************************************/
#include<stdio.h>
int my_div(float a,float b,float *s);
int main(void)
{
    float c;
    float a,b;
    float k;
    printf("请输入除数a:\n");
    scanf("%f",&a);
    printf("请输入被除数b:\n");
    scanf("%f",&b);
    if ( my_div(a,b,&k) )
    {
        printf("%3.2f\n",k);
    }
    else
    {
        printf("输入错误,被除数不能为零\n");
    }
    return 0;
}

int my_div(float a,float b,float *s)
{
    const float c = 0.00001;
    if ( b >= (-c) && b <= c )
    {
        return 0;
    }
    else
    {
        *s = a/b;
        return 1;
    }
}


/**************mystrcat**********实现函数strcat********************/
#include<stdio.h>
char *mystrcat(char *str1,char *str2);
int main()
{
    char str1[128] = {0};
    char str2[128] = {0};
    printf("请输入第1个字符串\n");
    gets(str1);
    printf("请输入第2个字符串\n");
    gets(str2);
  //  str3 = mystrcat(str1,str2);
    puts(mystrcat(str1,str2));

    return 0;
}

char *mystrcat(char *str1,char *str2)
{
    int i=0,j=0,k=0;
    static char str3[256] = {0};
    for( ;str1[i] != '\0'; )
    {
        str3[k++] = str1[i++];
    }
    for(; str2[j] != '\0' ;)
    {  
       str3[k++] = str2[j++];        
    } 
    str3[k++] = '\0';
    
    return str3;
}


/*************mystrcmp*************************************************/
#include<stdio.h>
int mystrcmp(char *str1,char *str2);
int main()
{
    char str1[128] = {0};
    char str2[128] = {0};
    printf("请输入第1个字符串\n");
    gets(str1);
    printf("请输入第2个字符串\n");
    gets(str2);
    printf("%d\n",mystrcmp(str1,str2));
    

    return 0;
}

int mystrcmp(char *str1,char *str2)
{
    int i=0,j=0,k=0;
    while(1)
    {
        if ( str1[i] > str2[j])
        {
            i++;
            j++;
            return 1;
        }
        else
        {
            return 0;
        
        }
    
    }
}


/**********************mystrcpy***************************************/
#include<stdio.h>
char *mystrncpy(char *str1,char *str2);
int main()
{
    int n;
    char a[128] = {0};
    char b[10] = {0};
    gets(a);
    gets(b);
    char *p = NULL;
    
    
    puts(mystrncpy(a,b));
    
    puts(a);


    return 0;
}
char *mystrncpy(char *str1,char *str2)
{

    int i = 0,j = 0;
    while ( str1[i++] )
    {
        if ( str2[j] == str[i])
        {
            while ( str2[j++] == str1[i++] && j<strlen[str2])
            {
                str1[i++] = str1[];
            }
        }
        
    }
    return str1;
}


/********************mystrncpy*******************************/
#include<stdio.h>
char *mystrncpy(char *str1,char *str2,int n);
int main()
{
    char a[128] = {0};
    char b[10] = {0};
    gets(a);
    char *p = NULL;
    
    
    puts(mystrncpy(b,a,5));
    
    puts(b);


    return 0;
}
char *mystrncpy(char *str1,char *str2,int n)
{
    int i = 0,j = 0;
    while ( (str1[i++] = str2[j++]) && (j < n) );
    return str1;
}

/***************mystrlen***************************************/
#include<stdio.h>
int mystrlen(char *a);
int main()
{

    char a[128] = {0};
    int b;
    //printf("请输入要获取的字符串个数\n");
    //scanf("%d",&b);
    //printf("请输入字符串\n");
    gets(a);
    printf("mystrlen(a) = %d\n",mystrlen(a));
    return 0;
}

int mystrlen(char *a)
{
    int i = 0,j = 0;
    while( a[i++] != '\0' )
    {
        j++;
    }
        return j;
    
}


/**********n个数移动m位依次替换**********************************/
#include<stdio.h>
int *move(int n,int m);
int main()
{
    int n,m,i;int *b;;
    printf("请输入数字个数:\n");
    scanf("%d",&n);
    printf("请输入移动位数:\n");
    scanf("%d",&m);
    b = move(n,m);
    printf("****%d个数字移动%d位后****\n",n,m);
    for(i = 0; i < n; i++)
    {
        printf("%d",b[i]);
    }
    puts("");
}


int *move(int n,int m)
{
    int i,j;static int a[]={0};int b[m];int c[n-m];
    printf("*********原来是**********\n");
    for(i=0;i<n;i++)
    {
        a[i]=i;
        printf("%d",a[i]);
    }
    puts("");
    for(j=0;j<m;j++)
    {
        b[j] = a[n-m+j];
    }
    for(j=0;j<n-m;j++)
    {
        c[j]=a[j];
    }
    for(i=0;i<n;i++)
    {
        if(i<m)
        {
            a[i]=b[i];
        }
        else
        {
            a[i]=c[i-m];
        }
    }
    return a;
}



/**********************删除特定字符串**************************************/
#include<stdio.h>
char *strdel(char *str1,char *str2);
int main()
{
    //原字符串
    char a[128] = {0};
    gets(a);
    //要删除的子串
    char b[128] = {0};
    gets(b);
    puts(strdel(a,b));
    puts(a);

    return 0;
}
char *strdel(char *str1,char *str2)
{
    
    int i = 0;
    while(str1[i])
    {
        int j = 0;
        if ( str1[i] == str2[j] )
        {
            int k = i;
            while(str2[j])
            {
                if ( str1[k] == str2[j] )
                {
                    k++;
                    j++;
                }
                else
                {
                    break;
                }
            }

            if ( str2[j] == '\0' )
            {
                while(str1[k])
                {
                    str1[i] = str1[k];
                    k++;
                    i++;
                }
                str1[i] = '\0';
                i = 0;
                continue;
            }
        }
        i++;
    }
    return str1;
}



/*****************删除特定字符***************************************/
#include<stdio.h>
char *strdel(char *str,char s);
int main()
{
    char a[256] = {0};char b;
    printf("请输入一个字符串:\n");
    gets(a);
    printf("请输入要删除的字符:\n");
    scanf("%c",&b);
    printf("删除后的字符串为:\n");
    puts(strdel(a,b));
    return 0;
}


char *strdel(char *str,char s)
{
    int i=0,j;
    while(str[i])
    {
        if(str[i] == s)
        {
            j = i;
            while(str[j])
            {
                str[j] = str[j+1];
                j++;
            }
            str[j++] = '\0';
            //i = 0;
            i--;
        }
        i++;
    }
    return str;
    
}



/***********************十进制转换成任意进制数**********************************/
#include<stdio.h>
#include<string.h>
int *zh(int a,int b);
int main()
{
    int a,i,j;int b;
    printf("请输入一个10进制数字:\n");
    scanf("%d",&a);
    printf("请输入要转换成几进制:\n");
    scanf("%d",&b);
    int *p = zh(a,b); 
    printf("转换%d进制的数字为:\n",b);
    for(i = 1;i < p[0]; i++)
    {
        printf("%d",p[i]);
    }
    printf("\n");
    return 0;
}


int *zh(int a,int b)
{
    static int str1[1280];int d=1,j,i = 1,e=1;static int str2[1280];
    for(i = 0; ; i++)
    {
        str1[i] = a % b;
        a = a/b;
        e++;
        if (a == 0)
        {
            break;
        }
    }
    for(j = i; j>= 0; j--)
    {
        str2[d++] = str1[j];
    }
    str2[0] = e;
    return str2;
}


/*****************水仙花数************************************/
#include<stdio.h>
#include<stdlib.h>
int *sx(int low,int high);
int main()
{
    int *p = sx(100,1000);
    int i;
    for(i = 1; i <= p[0] ; i++)
    {
        printf("%d\n",p[i]);
    }
    return 0;
}


int *sx(int low,int high)
{
   static int buf[20];
    int a,b,c,i;
    int cnt = 1,st = 0;
    for(i = low; i < high; i++)
    {
        a = i/100;
        b = (i/10) %10;
        c = i%10;
        if( i == (a*a*a + b*b*b + c*c*c))
        {
            buf[cnt++] = i;
            st++;
        }
        buf[0] = st;
    }
    return buf;
}


/***************************冒泡排序*******************************************/
#include<stdio.h>
int main()
{
    int i,j,k;int a[10] = {0,2,9,5,6,1,3,8,7,4};
    for ( i = 0; i < 9 ; i++ )
    {
        for ( j = 0 ; j < 9-i ; j++)
        {
            if (a[j] > a[j+1])  //先吧大数字往后面排
            {
                k = a[j];
                a[j] = a[j+1];
                a[j+1] = k;
            }
        }
    }
    for ( i = 0; i < 10 ; i++ )
    {
        printf("%d  ",a[i]);
    }
    puts("");
    return 0;
}




/***************************插入排序*******************************************/
#include<stdio.h>
int main()
{
    int i,j,k;int a[10] = {5,6,2,4,9,8,7,1,0,3};
    for ( i = 1; i < 10 ; i++ )/*外循环控制趟数,n个数从第2个数开始到最后共进行n-1次插入*/
    {
        k = a[i];/*将待插入数暂存于变量t中*/
        for ( j = i-1 ; (j > -1) && (a[j] > k); j--) // 前面的为一个部分,把后面的元素往前插入
        {
            a[j+1] = a[j];/*若找到插入位置,则当前元素后移一个位置*/
        }
		a[j+1]=k;/*未找到插入位置,不变*/
        
    }
	for(i = 0; i < 10;i++)
	{
		printf("%d ",a[i]);
	}
	printf("\n");
    return 0;
}









/****************************选择排序******************************************/
#include<stdio.h>
int main()
{
    int i,j,k,min;int a[10] = {5,9,4,2,6,8,0,1,7,3};
    for ( i = 0; i < 10 ; i++ )
    {
        for ( j = i + 1 ; j < 10; j++) // 第i个数字与后面的所有比较,找出最小的排在第一个,然后找出第二小的...
        if ((a[j] < a[i]))
        {
            min = a[j];
            a[j] = a[i];
            a[i] = min;
        }
        
    }

    for(i = 0; i < 10; i++)
    {
        printf("%d ",a[i]);
    }

    printf("\n");
    return 0;
}




  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值