C语言基础

来源:互联网 发布:双色球数据分据库 编辑:程序博客网 时间:2024/06/16 16:19

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

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


计算机:

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

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


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,0xl在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;}


原创粉丝点击