C语言

在Linux操做系统下C语言程序开发的步骤

1.使用vi编写C语言源文件
2.使用命令gcc <源文件名>获得最终的可执行文件
3.使用命令./a.out执行获得的可执行文件数组

#include <stdio.h> /*导入stdio.h文件(在/usr/include目录下)*/
int main(){ /*int为main函数的返回类型*/
    printf("hello world!\n");
    return 0;
}

说明:C语言中以#开头的指令叫作预处理指令,#include用于把一个文件的内容加入到当前源文件中
        <>包括的文件名不会查找当前目录,用""包括的文件名会查找当前目录.只能使用#include包含.h文件而不该该包含.c文件函数

gcc编译工具的介绍

gcc:GNU(开放源代码组织) Copmiler(编译器) Collection(一套)工具

gcc经常使用选项
 -v:显示各类相关信息
 -E:只完成预处理指令的工做(#开头的代码)
 -std=c89/-std=c99:指定采用的C语言标准版本(用c89标准制做出来的的必定适用于c99,反之不行)
 -S:转化成汇编语言源程序,hello.c ->hello.s
 -O:优化(1,2,3,三种不一样的优化级别)
 -c:只对源程序进行编译工做,不连接(hello.o)
 -o:用于指定结果执行文件的名字(默认为a.out)
 -Wall:把全部的警告都打印出来 性能

C语言程序的处理过程:
 1.预处理,完成预处理指令要求的工做
 2.编译,把C语言源程序翻译成计算机认识的格式
 3.连接,把程序中各个部分连接起来优化

注释

注释用来在程序中加入文字信息,分单行注释(//注释内容)和多行注释(/*注释内容*/)>    两种.注释中的内容会被计算机忽略编码

 变量

变量用来记录数字,在使用变量以前必须声明,声明语法以下:
  变量类型 变量名,好比:int price
在未赋值以前变量内部有数据,可是具体数字不肯定.使用=(赋值操做符)对变量进行赋值,第一次给变量赋值叫作变量初始化.能够在一行语句中声明多个同类型的变量spa

变量与内存的关系:计算机内存由大量的字节构成,内存中的数字必须记录在一个或多个相邻的字节中.变量是这些字节的表明操作系统

经过&符号能够得到变量的字节地址,经过*符号得到字节地址对应的变量开放源代码

#include <stdio.h> 
int main(){ 
    int num = 0;
    printf("&num是%p\n", &num);
    *(&num) = 10;
    printf("num是%d\n", num);
    return 0;
}

如今有两个变量,实现两个变量之间的交换翻译

#include <stdio.h>
int main(){
    int num1 = 7, num2 = 3, temp = 0;
    //使用临时变量完成两个变量内容的交换
    printf("num1:%d\nnum2:%d\n", num1, num2);
    /*temp = num1;
    num1 = num2;
    num2 = temp;*/

    //不使用临时变量完成两个变量内容的交换
    num1 = num1 + num2;
    num2 = num1 - num2;
    num1 = num1 - num2;
    printf("交换后num1:%d\nnum2:%d\n",num1,num2);
    return 0;
}

全局变量,局部变量和块变量

  定义在函数以外的变量叫作全局变量,
  定义在函数内部的变量叫作局部变量,
  定义在函数内部的大括号里边的变量叫作块变量
  生存周期表示一个变量在什么时间范围内是可使用的.
  做用域表示一个变量在什么代码范围内是可使用的.
  全局变量的生存周期是整个程序的运行时期,局部变量的生存周期是所在函数的执行过程,块变量的生存周期是所在块的执行过程.
  全局变量的做用域是整个程序代码范围,局部变量的做用域是所在函数的执行体代码,块变量的做用域是所在块的代码.
  不一样层次的变量能够重名,在使用的时候变量名称匹配的是全部做用域包括使用语句的变量中层次最深,而且在这条语句以前声明的那个变量
  没有被初始化的全局变量会被自动初始化成0.

#include <stdio.h>
int shu_zi = 0;
int main(){
    printf("shu_zi:%d\n", shu_zi);//0
    int shu_zi = 1;
    //int shu_zi = 2; // 错误,重复定义
    {
        {
      int shu_zi = 2;
      printf("shu_zi:%d\n", shu_zi);//2
      }
    printf("shu_zi:%d\n", shu_zi);//1
    }
    printf("shu_zi:%d\n", shu_zi);//1
    return 0;
}

使用全局变量实现一个栈

#include <stdio.h>
#include <stdbool.h> //用于导入bool类型的数据
int last = -1; //表示栈中最后一个数据所占的位置
//定义一个全局数组用来表示一个大小为20的栈
int stack[20];
//判断栈是否为空
bool empty(){
    if(last < 0){
        return true;
    }
    else{
        return false;
    }
}
//判断栈是否满了
bool full(){
    if(last == 19){
        return true;
    }
    else{
        return false;
    }
}
//向栈中添加数据,当栈满的时候添加失败
bool push(int num){
    if(!full()){
        stack[++last] = num;
    return true;
    }
    else{
        return false;
    }
}
//取出最后一个数据
bool pop(){
    if(!empty()){
        last--;
    return true;
    }
    else{
        return false;
    }
}
//获取最后一个数据,并不取出
int peak(){
    return stack[last];
}
//使用四则运算2+3*5表达式,验证结果是否正确
int main(){
    int num1 = 0, num2 = 0, operator=0;
    push(2);
    push('+');
    push(3);
    push('*');
    push(5);
    num2 = peak();
    pop();
    operator = peak();
    pop();
    num1 = peak();
    pop();
    num2 *= num1;
    operator = peak();
    pop();
    num1 = peak();
    pop();
    num2 += num1;
    printf("计算结果是%d\n", num2);
    if(empty()){
        printf("栈正常\n");
    }
    return 0;
}

标识符命名规则

1.必须以字母或下划线开头
2.后面的能够是字母,数字或下划线
3.大小写不一样的字母被认为不一样
4.不能和C语言关键字冲突
5.长度没有限制,可是只有前面的是有效的(c89取前31位,c99取前63位)

C语言的代码规范

1.一条语句能够放在多行内,可是多条语句不该该放在一行里
2.在合适的地方添加空格,这有助于提升程序可读性
3.不一样层次的代码要用缩进区分开
4.适当使用空行和注释区分不一样的逻辑单元
5.标识符名称采用驼峰方式或下划线方式

printf与scanf函数

使用C语言提供的printf函数实现把信息打印在屏幕上的功能,须要包含一个stdio.h文件.第一个参数是一个字符串,用来表示要打印的信息.
格式:
  %d:用不带小数点的数字替换,%md表示数字占用的宽度
  %c:用单个字符替换,单引号表示字符
  %s:用一个字符串替换
  %f:用一个带小数点的数字替换
  %g:也能够用一个带小数点的数字替换,输出是后面没有多余的0
  %p:用一个地址数据替换

#include <stdio.h>
int main(){
    printf("Hello World!\n");//\n表示换行
    printf("Hello \rWorld\n");//\r表示从行首开始,World
    printf("Hel\\lo World!\n");//\\表示单个斜杠
    printf("Hello Wor\"ld\n");
    int num;
    printf("整数是%d\n", num);//num表示随机的整数
    printf("整数是%5d\n", 1);//表示整数占用的宽度
    printf("字符是%c\n", 'a');//单引号表示字符
    printf("字符串是%s\n", "abc");
    printf("数字是%f\n", 3.5f);//3.500000
    printf("数字是%0.2f\n", 3.5f);//保留2位小数
    printf("数字是%lf\n", 3.5);
    printf("数字是%g\n", 3.5f);//3.5
    printf("地址是%p\n", &num);//0x7ffd9e933af4
    return 0; 
}

scanf函数用于从屏幕上读取信息并记录到变量中,格式字符串与printf函数相似,后面的参数必须是变量的地址,不然会致使段错误.格式串中的类型必须和后面给定地址的变量类型一致

练习:让用户从屏幕上输入圆的半径,而后打印圆的面积和周长

#include <stdio.h>
#include <math.h>
int main(){
    float r = 0.0f;
    printf("请输入圆的半径:");
    scanf("%f", &r);
    printf("圆的周长是%g\n", 2 * 3.14 * r);
    printf("圆的面积是%g\n", 3.14 * r * r);
    return 0;
}

 数据类型

ASCII码表记录字符和编码之间对应关系
char数据类型来表示字符编号数据,占一个字节,表示范围-128到127
unsiged char类型也占有一个字节,表示范围从0到255

short类型占有两个字节,使用%hd匹配,范围在(-32768~32767)
unsigned short类型占有两个字节,使用%hu匹配,范围在(0~66535)
long类型占有4个字节使用%ld匹配,范围在(-2**31~2**32-1)
unsigned long类型占有4个字节,使用%lu匹配,范围在(0~2**32-1)
int类型的大小取决于计算机的单次处理能力,在使用32位计算机上与long相同.
float(浮点类型)用来表示带小数点的数字,因为精度缘由计算中要考虑偏差,占有4个字节使用%f或%g(省略后面的0)匹配,没有取值范围
double(双精度浮点数)用来表示更高精度的浮点数,也存在偏差问题.占有8个字节使用%lf匹配,没有取值范围

有符号数字的二进制表示形式中最高位是0则表示这个数必定是非负数,若是是1则必定是负数,咱们把这个最高位的二进制为称为符号位

在printf和scanf函数中使用%hhd与char类型变量匹配,使用%hhu与unsigned char类型变量匹配
sizeof关键字能够用来计算某个数据类型或某个变量所占空间的大小,以字节为单位.它不会计算小括号中的表达式.

#include <stdio.h>
#include <limits.h>
int main(){
    char aChar = 'a';
    unsigned char uChar = 0;
    printf("aChar是%c,aChar的编号是%d\n", aChar, aChar);
    aChar = 98;
    printf("aChar是%c,aChar的编号是%d\n", aChar, aChar);
    printf("sizeof(char)是%d字节,sizeof(aChar)是%d字节\n",sizeof(char),sizeof(aChar));
    printf("sizeof(aChar=99)是%d字节\n", sizeof(aChar=99));
    printf("aChar是%d\n", aChar);
    printf("最大字符编码是%d,最小字符编号%d\n", CHAR_MAX, CHAR_MIN);
    printf("sizeof(unsigned char)是%d字节,size(uchar)是%d字节\n", sizeof(unsigned char),sizeof(uChar));
    printf("最大字符编码是%d\n", UCHAR_MAX);
    aChar = 191;
    uChar = 191;
    printf("aCHar:%hhd\n", aChar);
    printf("uCHar:%hhu\n", uChar);
    return 0;
}
/*aChar是a,aChar的编号是97
aChar是b,aChar的编号是98
sizeof(char)是1字节,sizeof(aChar)是1字节
sizeof(aChar=99)是1字节
aChar是98
最大字符编码是127,最小字符编号-128
sizeof(unsigned char)是1字节,size(uchar)是1字节
最大字符编码是255
aCHar:-65
uCHar:191*/

小写字母转大写

#include <stdio.h>
int main(){
    char letter;
    printf("请输入一个小写字母:");
    scanf("%c", &letter);
    printf("%c对应的大写字母为%c\n",letter,letter - 'a' + 'A');
    return 0;
}

运算符

+, -, *, /分别表示加减乘除.
%表示取余操做,不能对浮点数进行取余操做

#include <stdio.h>
int main(){
    unsigned short num = 0;
    printf("请输入一个两位数:");
    scanf("%hu", &num);
    //%运算符取余数,/运算符取模
    printf("结果是:%d%d\n", num % 10, num / 10);
    return 0;
}

=表示赋值操做符,要求左边的部分必定要是一个左值.赋值操做符从右向左计算.
符合操做运算符指的是在赋值操做符前面加上其余的操做符并造成的,例如+=, *=
++表示自增运算,--表示自减运算,只能对左值进行计算
逻辑运算符计算结果只有两个,一个真(对)用1表示,另一个是假(错)用0表示.咱们也能够在代码中使用0表示错误,任何其余数值表示真(对).
==(相等), !=(不相等), >(大于), <(小于), >=(大于等于), <=(小于等于), !(求反) 

#include <stdio.h>
int num = 10;
int main(){
    int num1 = 0, num2 = 0;
    num1 = 8, 3;//8
    printf("num1:%d\n", num1);//逗号也是运算符优先级比=还低
    num2 = (8, 3);//3
    printf("num2:%d\n", num2);//逗号操做符返回最后一个表达式的计算结果
    num2 *= 2 + 3;// num2 = num2 * (2 + 3) = 15
    printf("num2:%d\n", num2);
    num2 ++;//num2 = num2 +1
    printf("num2:%d\n", num2);//16
    ++ num2;
    printf("num2:%d\n", num2);//17
    num1 = num2++;//先将num2赋值给num1而后在自加,17
    printf("num1:%d\n", num1);
    num1 = ++num2;//先将num2自加再赋值给num1,19
    printf("num1:%d\n", num1);
    num2 = num1++ + ++num1;
    printf("num1:%d\n",num1);//21
    printf("num2:%d\n",num2);//40
    num2 = num++ + ++num;
    printf("num2:%d\n", num2);//22,不一样的编译器结果可能不一样21
    printf("num:%d\n", num);//12
    return 0;
}

编写一个时钟程序

#include <stdio.h>
#include <time.h>
#include <unistd.h>//导入sleep函数
int main(){
    unsigned long total_seconds = 0;
    int hours = 0, minutes = 0, seconds = 0;
    while(1){
    total_seconds = time(0);
    seconds = total_seconds % 60;
    minutes= total_seconds % 3600 / 60;
    hours = total_seconds % (24 * 3600) / 3600;
    hours = (hours + 8) % 24;
        printf("%02d:%02d:%02d\r", hours, minutes, seconds);
    fflush(stdout);//强制把输出缓冲区清空到屏幕上
    //while(time(0) == total_seconds);//一直占用cpu影响计算机性能
        sleep(1);
    }
    return 0;
}

 数组

概念:程序中须要使用变量记录数字,若是数字的数量不少就须要使用多个变量.能够把多个同类型的变量合成一个总体,C语言里使用数组表明这个合并后的总体

数组须要先声明而后才能使用

数组一旦存在则面包含的变量个数就不能够改变

使用下标表示数组中每一个变量

可使用for循环依次处理数组中每一个变量

数组也应该先初始化而后在使用

#include <stdio.h>
#include <stdlib.h>
int main(){ 
    int arr[5] = {};//数组声明语句,并初始化为5个0
    //若是初始话的数组的长度小于5则用0补,不如大于5则截取
    arr[2] = 10;
    printf("arr[2]是%d\n", arr[2]);
    int num = 0;
    for(num = 0; num <=4; num++){
        arr[num] = num + 1;
    }
    for(num = 0;num <= 4;num++){
        printf("%d ", arr[num]);
    }
    printf("\n");
    return 0;
}

示例:编写程序产生一张彩票,彩票中包含7个1到36之间的随机数(不能重复)

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(){ 
    int arr[7] = {}, cnt = 0, num = 0;
    srand(time(0)); 
    do {
        //将数组的第一个位置赋值
        arr[cnt] = rand() % 36 + 1;
    //将后面的数字分别与前面的比较直到与前面的全不相等为止
        for(num=0; num <= cnt - 1; num++){
        if(arr[cnt] == arr[num]){
            break;
        }
    }
    //判断上述循环是否为正常结束
        if(num == cnt){
            cnt++;
        }
    }while(cnt < 7);
    for (num = 0; num <= 6; num++){
        printf("%02d ",arr[num]);
    }
    printf("\n");
    return 0;
}

数组的优缺点:

  优势:数组支持随机访问,数组中每个变量均可以直接使用,不须要依赖其余变量

  缺点:数组不适合进行插入删除操做

编写程序向一个有序数组中插入一个新数字,插入后整个数组仍然是有序的,而后再删除一个数字

 

#include <stdio.h>
int main(){ 
    int arr[9] = {1, 3, 5, 7, 9, 11}, num = 0;
    for (num = 5; num >= 0; num--){
        if(arr[num] > 4){
        arr[num + 1] = arr[num];
    }
    else{
        break;
    }
    }
    arr[num + 1] = 4;
    for(num = 0; num <= 6; num++){
        if(arr[num] > 7){
        arr[num -1] = arr[num];
    }
    }
    for (num = 0; num < 6; num++){
        printf("%2d ",arr[num]);
    }
    printf("\n");
    return 0;
}

 流程控制语句

分支语句:if语句和switch语句

if语句格式:
if(条件1){//若是 每一个分之语句if只能出现1次
     //知足条件1时执行的语句
 }else if(条件2){//或者 出现0~n次
     //知足条件2时执行的语句                                                                                                                         
 }else{//不然 出现0~1次
     //以上条件否不知足是执行的语句
 }
switch语句格式:

switch(控制表达式){
     case 常量表达式:语句;
     ...
     default:语句;
 }
 控制表达式被当作整数处理,能够是字符,但不能是浮点数
 常量表达式必须是常量,如3 'A' 2+5
 语句能够是0到多条                                                                                                                                   
 不容许重复重复分支,default不必定在最后
 break用于退出switch,switch语句遇到break后或执行完最后一条语句才退出

#include <stdio.h>
int main(){ 
    int score = 0;
    printf("请输入1~100的整数:");
    scanf("%d", &score);
    switch(score / 10){
        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;
    default:
        printf("E\n");
    }
    return 0;
}

循环语句
  for循环格式:
  for(表达式1;表达式2;表达式3){
      循环体语句;
  }
  执行顺序:表达式1 -> 表达式2(为假则退出循环) -> 循环体语句(遇到break可则退出循环) -> 表达式3
  示例:打印99乘法表

#include <stdio.h>
int main(){ 
    int i = 1, j = 1;
    for(i = 1; i < 10; i++){
        for(j = 1; j <= i; j++){
        printf("%d*%d=%2d ", j, i, i*j);
    }
    printf("\n");
    }
    return 0;
}

while循环格式
  while(表达式){
     语句;
  }
 do ... while循环格式                                                                                                                                                 
  do{
      语句;
  }while(表达式);
循环内部经常使用的关键字

  break用于退出循环,能够到达循环的外部下一行语句

  continue用于终止本次循环,继续下一次循环

相关文章
相关标签/搜索