C语言之初识C语言(点到为止,两万字文章详细解读!)(一)

简介: C语言之初识C语言

前言

提示:/*该文章作为个人学习且分享使用,若有侵权,请联系我删除*/

本文章起名为初识C语言,顾名思义,即简单地、浅显地知晓一下C语言,大概需要学到哪些知识,不做深层的解读,本文章适合初学者进行学习,有错误还请私信我纠正。

提示:以下是本篇文章正文内容,下面案例可供参考


一、什么是C语言?

语言我们大家都知道,像我们现实生活中交流都需要用汉语语言来沟通学习交流,那什么是C语言?C语言通俗来讲,就是人与计算机进行交流,是一门通用的计算机编程语言,广泛应用于底层的开发,像底层的软件开发,如操作系统、驱动层软件的开发。


计算机C语言的发展历史:最初的计算机语言是利用2进制(机器语言)来编写,用2进制来编写太复杂了,于是人们便采用了助记符来编写程序,以此发展到汇编语言,而后发展到B语言,最后发展成现在的C语言。


C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。


C语言是一门面向过程的计算机编程语言,与C++,Java等面向对象的编程语言有所不同。


其编译器主要有Clang(MacOS系统)、GCC(Linux系统)、WIN-TC、SUBLIME、MSVC(Microsoft Visual C++,用于Windows系统 )等


二、第一个C语言程序

#include <stdio.h>
int main()
{
    printf("hello world\n");
    return 0;
}

程序的运行从main函数开始,在整个工程中,main函数只存在一个。


三、基本数据类型

char //字符数据类型

short //短整型

int //整形

long //长整型

long long //更长的整形

float //单精度浮点数

double //双精度浮点数


基本的数据类型会被分为有符号(signed)和无符号(unsigned)两大类。一般写的数据类型没有在前面注明(unsigned char)的情况下,默认为有符号类型。

那么有符号的数据类型和无符号的数据类型有什么区别?

区别就是在内存的存储中,符号位是1还是0,具体的还请翻阅数据存储及内存相关的知识。在这个章节咱们先了解即可。


1. 有符号整型家族

image.png

咱们试着在编译器中用**sizeof()**(sizeof()是一个关键字,它是一个编译时运算符,用于判断变量或数据类型的字节大小。)来打印各种基本数据类型的大小。

image.png

2. 无符号整型家族

image.png

3. 浮点类型家族

image.png

以上基本数据类型的单位都是字节(byte),数据存储中是以“字节”(Byte)为单位,数据传输大多是以比特(bit)为单位,一个位就代表一个0或1(即二进制),每8个位(bit,简写为b)组成一个字节(Byte,简写为B),是最小一级的信息单位。


4.C语言基本单位的换算

那么C语言中,有哪些单位,这些单位之间又是如何转换运算呢?


Byte -->1 Byte = 8 bit

KB --> 1KB = 1024Byte

MB --> 1MB = 1024KB

GB --> 1GB = 1024MB

TB --> 1TB = 1024GB

PB --> 1PB = 1024TB

……


四、变量和常量

1.变量

定义格式:数据类型+变量名 = 字面值(XXX) ;


int age = 50;
float weight = 130.5f;
char name = “张三”;


(局部)变量在创建时未初始化一般会给随机值,但是有的编译器会报错。为了避免这样的错误,我们一般会在创建时就给初始值。

int main()
{
    int a = 0; // 在定义变量的同时,我们给上初始值,一般给上0
return 0
}

image.png

变量的命名规则


只能由字母(包括大写和小写)、数字和下划线( _ )组成。

不能以数字开头。

长度不能超过63个字符。

变量名中区分大小写的。

变量名不能使用关键字

注意:在起变量名时不能太随意,变量名最好见名知意。


变量的分类


全局变量

局部变量

局部变量:局部变量是在函数内部定义的变量,只能在函数内部或者局部变量所在的局部范围内使用。

全局变量:是在函数外部定义的变量(没有定义在某一个函数内),适用于整个工程,所有函数内部都可以使用这个变量。


当局部变量和全局变量同名的时候,则局部变量优先。

用代码说明如下:

#include <stdio.h>
int gl_val = 123;//全局变量
int main()
{
    int local = 234;//局部变量
    //下面定义的global会不会有问题?
    int gl_val = 456;//局部变量  与全局变量不冲突
    printf("gl_val = %d\n", gl_val); // gl_val = 456
    return 0;
}

变量的作用域和生命周期


作用域:


作用域(scope)是程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效可用的而限定这个名字的可用性的代码范围就是这个名字的作用域。


局部变量的作用域是变量所在的局部范围。

全局变量的作用域是整个工程。

这里就出现报错,局部变量b,出了所在的局部范围再打印b,程序会报错,出现在44行。

image.png

生命周期:

变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段

  1. 局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。
  2. 全局变量的生命周期是:整个程序的生命周期。
int main()
{
  {
    int a = 10;
    printf("%d\n", a); //仅在局部范围内打印
  } 
  printf("%d\n", a);//出了局部范围,变量a生命周期结束。
  return 0;
}

2.常量

  • 字面常量
  • const 修饰的常变量d(本质还是一个变量,相当于用const给上了一把锁,不能直接被修改)
  • #define 定义的标识符常量
  • 枚举常量
int main()
{
  //1.字面常量
  //100;//整型字面值
  //'w';//字符字面值
  //3.14;//浮点型的字面值
  //"abcdef";//字符串常量
  //2. const 修饰的常变量
  //const 是常属性的
   const int num = 10;//num本质上是个变量,但是具有常属性,不能被修改
   printf("%d\n", num);//10
    num = 20;//这里会报错,不能直接被修改
   //printf("%d\n", num);//20
    /*
    //数组
    //const int n = 10;
    //int arr[n] = {0};//n虽然被const修饰,具有了常属性,不能被修改,
    //但是本质上还是变量,所以不能用来指定数组的大小
    //下面的代码在支持C99的编译器上可以编译的
    //C99中,引入了:变长数组的概念,变长数组的大小是可以使用变量来指定的,但是数据不能初始化。
    //VS2019是不支持C99中的变长数组的,所以没法验证
      //int n = 10;
    //int arr[n];
    */
//int main()
//{
//    int n = 10;
//    int arr[n];//变长数组
//    int i = 0;
//    for (i = 0; i < n; i++)
//    {
//        arr[i] = i;   //向arr数组放进i的值
//    }
//    for (i = 0; i < n; i++)
//    {
//        printf("%d ", arr[i]); //打印arr数组的值
//    }
//
//    return 0;
//}
}
int main()
{
  //3.define 定义的标识符常量
  #define MAX 10000  ///可以写在源文件顶部,也可以写在函数内部
  MAX = 20000;//这里也不能做修改
  printf("MAX = %d\n",MAX);
  return 0;
}
  //4.枚举常量
  enum RGB // 声明一个三原色的枚举常量red,green,blue
  {
    //red, //此时没给值的话,系统会自动分配为0
    //green,//1
    //blue //2
    red = 10,
    green,
    blue
  };
int main()
{
  enum RGB r = red;
  printf("%d\n",red); //10
  printf("%d\n",green);//11
  printf("%d\n",blue);//12
  return 0;
}

五、字符串+转义字符+注释

1.字.符串

“hello world”

这种由双引号(Double Quote)引起来的一串字符称为字符串字面值(String Literal),或者简称字符串。

'\0'是字符串的结束标志

int main()
{
    char arr1[] = "abcde";//用字符数组存一组字符串
    char arr2[] = {'a','b','c','d','e'};//以另一种方式表达字符数组
    printf("%s\n",arr1);//打印abcde
    printf("%s\n",arr2);//打印abcde+随机值
    //为什么呢?
    //arr1里存的是字符串,而字符串末尾隐含一个‘\0’,这个‘\0’是字符串结束的标志,所以会直接打印abcde
    //arr2存放的是字符,它需要在内存中去寻找‘\0’,直到寻找到‘\0’才结束打印,所以在打印abcde之后会随机打印一些随机值,所以会出现乱码
}

image.png

image.png

如果我们在arr2数组的后面添加个‘\0’,这时在‘e’后面找到了\0,就会结束打印

image.png

\0不占据字符串长度,但占据内存空间长度

int main()
{
  //strlen 是一个库函数,专门用来求字符串长度的
  char arr1[] = "abc";
  char arr2[] = {'a', 'b', 'c'};
  int len = strlen(arr1);
  printf("%d\n", len);//这里长度是3, 在计算字符串长度的时候 \0 是结束标志,不算作字符串长度
  len = strlen(arr2);
  printf("%d\n", len);//长度不是15,而是一个随机值
  //sizeof 是一个运算符,用来获取某个数据类型或者变量所占用空间的字节数
  printf("arr1的长度是%d",sizeof(arr1));//arr1的长度是4个字节,'\0'占据一个字节的空间
return 0;
}

转义字符

int main()
{
printf("abcd\0ef");
  return 0;
}

什么是转义字符,其实我们在上面就讲过,‘\0’ 就是一个转义字符,在0的前面添加一个反斜杠,就会改变它原有的含义,此时它的含义就不是0这个单纯的值了,而是作为结束符来使用,此时的“abcd\0ef”打印出来就是abcd

image.png

打印出单引号和双引号

#include<stdio.h>
int main()
{ /*这样写就会报错
  printf(""");\\前两个双引号成对,而后面那个引号则落单了
  printf(''');\\前两个单引号成对,而后面那个引号则落单了
  */
  printf("\""); 
  printf("\n"); //转义字符换行
  printf("\'");
  return 0;
}

image.png

更多常见转义字符,详细见表格。

image.png

\ddd\xhh表示什么意思呢?

转换它为十进制,所对应的ASCII码表中的字符。

int main()
{
  /*
  \ddd
   d是一个0~7的八进制数字(但不能超过ACII码表所表示的范围),ddd表示是三位八进制数字
   比如说\130 算出它的十进制为88,88所对应的ACII码表的字符为X
  \xhh
  h是一个0~f的十六进制的数字,hh表示两个十六进制数字
  比如说\x30 算出它的十进制为48,48所对应的ASCII码表的字符为0
  */
    printf("%c",'\130'); //x
    printf("%c",'\x30'); //0
return 0;
}

注释


哪些情况下我们可以使用注释呢?


代码中有不需要的代码可以直接删除,也可以注释掉

代码中有些代码比较难懂,可以加一下注释文字来解释它

注释有两种风格:

C语言风格的注释 /xxxxxx/

缺陷:不能嵌套注释

C++风格的注释 //xxxxxxxx

可以注释一行也可以注释多行

六、选择语句

1.if语句和switch语句

if语句的语法格式为:

if(条件判断)

{


条件判断为真,就执行该大括号里的内容


}else

{

条件判断为假,执行此括号里的内容

}

#include<stdio.h>
int main()
{
      printf("好好努力敲代码吗?(1/0)\n");
      int a;
      scanf("%d",&a);
      if(1 == a)
      {
        printf("未来拿到高薪offer");
      }else
      {
        printf("未来吃土");
      }
return 0;
}

if……else多分支语句

if(条件判断1)

{

条件判断1为真执行此大括号内的语句;

}else if(条件判断2)

{

条件判断2为真执行此大括号内的语句;

}else if(条件判断3)

{

条件判断3为真执行此大括号内的语句;

}else{

以上条件判断皆为假则执行此大括号内的语句

}

#include<stdio.h>
int main()
{
  printf("请输入你的成绩(0-100)\n");
  int score;
  scanf("%d", &score);
  if (score == 100)
  {
    printf("恭喜你获得了满分,奖励你100人民币!");
  }
  else if (score >= 80 && score < 100)
  {
    printf("成绩优异,奖励你50人民币!");
  }
  else if (score >= 60 && score < 80)
  {
    printf("成绩合格,继续努力。");
  }
  else if (score >= 0 && score < 60)
  {
    printf("成绩不合格,需要重修!");
  }
  else
  {
    printf("输入有误,请重新输入!");
  }
  return 0;
}

2. switch语句

switch语句的语法格式如下


switch(变量表达式){

case 常量表达式1:语句1;

case 常量表达式2: 语句2;

case 常量表达式3: 语句3;

case 常量表达式n: 语句n;

default: 语句n+1;

}

当变量表达式所表达的量与其中一个case语句中的常量相符时,就执行此case语句后面的语句,并依次下去执行后面所有case语句中的语句,除非遇到break;语句跳出switch语句为止。如果变量表达式的量与所有case语句的常量都不相符,就执行default语句中的语句

int main ()
{
   char grade = 'B';
   switch(grade)
   {
   case 'A' :
      printf("很棒!\n" );
      break;
   case 'B' :
   case 'C' :
      printf("做得好\n" );
      break;
   case 'D' :
      printf("您通过了\n" );
      break;
   case 'F' :
      printf("最好再试一下\n" );
      break;
   default :
      printf("无效的成绩\n" ); 
   }
   printf("您的成绩是 %c\n", grade ); // 做得好
                     // 您的成绩是B
   return 0;
}

七、循环控制语句

循环语句:


while语句

for语句

do……while语句


1.while语句

while循环的语法形式为

while (表达式)

{

执行内容(循环体);

}


当表达式为真,则执行下面的循环体;循环体执行完之后再判断表达式是否为真,如果为真,再次执行下面的循环体;然后再判断表达式是否为真……就这样一直循环下去,直到表达式为假,就跳出循环。

#include <stdio.h>
int main()
{
    /*假设你从今天开始,一直敲代码,直到总代码量达到5万行,你就可以拿到一个高薪offer
     这里我们用while语句实现*/
    printf("努力敲代码\n");
    int line = 0;
    while (line <= 50000)
    {
        line++;
        printf("%d:继续努力敲代码\n",line);
    }
    if (line >= 50000)
        printf("拿到高薪offer\n");
    return 0;
}

2.for语句

for 循环的一般形式为:

for(表达式1; 表达式2; 表达式3)

{

执行内容(循环体);

}

它的运行过程为:


先执行“表达式1”。 再执行“表达式2”,如果它的值为真(非0),则执行循环体,否则结束循环。


执行完循环体后再执行“表达式3”。


重复执行步骤 2和 步骤3,直到“表达式2”的值为假,就结束循环

#include <stdio.h>
int main(){
    int i, sum=0;
    for(i = 1/*表达式①*/; i <= 100/*表达式②*/; i++/*表达式③*/){
        sum += i;
    }
    printf("%d\n",sum);
    return 0;
}

3. do……while语句

do……while语句的语法格式为:

do

{

循环体;

}while(表达式);

do …… while 循环与 while 循环不同的是:先执行一次语句,再判断表达式是否为真,然后决定是否再执行一次语句或者表达式为假跳出循环。

#include <stdio.h>
int main()
{
   /* 局部变量定义 */
   int a = 10;
   /* do 循环执行,在条件被测试之前至少执行一次 */
   do
   {
       printf("a 的值: %d\n", a);
       a = a + 1;
   }while( a < 20 );
   return 0;
}

八、 控制语句

注:break不能用于除循环语句和switch语句之外的任何其他语句中


break 语句:终止循环或 switch 语句,程序会跳出循环体,将继续执行紧接着的语句或switch 的下一条语句。

continue 语句:结束本次循环,即跳过循环体中下面尚未执行的语句,接着进行下一次是否执行循环的判定。

goto 语句: 将控制转移到被标记的语句。但是不建议在程序中使用 goto 语句


九、函数

介绍两个常用的输入输出函数


1.scanf和printf函数

讲一讲scanf()函数和printf()函数,这两个函数是C语言中常用的函数,为输入输出函数,两个函数使用前均需要使用头文件#include <stdio.h>(standard input &output,意为标准输入输出)


printf函数:用于向标准输出设备按规定格式输出信息。

scanf函数:是格式输入函数,即按用户指定的格式从键盘上把数据输入到指定的变量之中


scanf函数

# include<stdio.h>
int main()
{
  int x = 0;
  int y = 0;
  //在scanf函数中""后的数据为待输入的数据,""里的内容,为待打印格式
  //&为取地址符,表示变量存储的地址,即表示通过键盘输入的数据
  //"%d"和"%f"为输入打印格式字符,
  //%d表示十进制整型数据
  //%f表示浮点型数据
  scanf("%d %f",&x,&y) //x的输入为整型数据 , y的输入为浮点型数据
  return 0;
}

有关scanf函数的返回值问题

#include<stido.h>
int main()
{
      int a = 0;
      int b = 0;
      //读取到几个值就返回多少
      //这里读取到两个数据,返回值为2
    scanf("%d %f",&x,&y) //x的输入为整型数据 , y的输入为浮点型数据
  return 0;
}

scanf读取数据,如果返回正常的话,返回的是读取到的数据的个数 。

如果读取失败,那么返回的是EOF,全称为“End Of File”(文件的结束标志),

EOF对应的值是多少?在编译器中输入EOF并点击转到定义,可以看出它的值为-1。

image.png

那么scanf的返回值有什么用呢?

可以适用于多次输入、多组输入的标准,如何编写?以以下题目为例


据说智商140以上者称为天才,KiKi想知道他自己是不是天才,请帮他编程判断。输入一个整数表示一个人的智商,如果大于等于140,则表明他是一个天才,输出“Genius”


输入描述要求:多组输入,每行输入包括一个整数表示的智商。

输出描述要求:针对每行输入,输出“Genius”

#include<stido.h>
int main()
{
    int iq = 0;
    /*
    while( scanf("%d",&iq) == 1)  //每输入一次输入返回值为1
    {
    if(iq >= 140)
    printf("Genius\n");  
  } 
  */
   /*多组输入*/
   while( scanf("%d",&iq) != EOF)  //每输入一次输入返回值为1
    {
    if(iq >= 140)
    printf("Genius\n");  
  } 
  return 0;
}

printf函数

printf函数使用输出有两种格式,一种是直接引用字符串的形式输出,第二种类似于scanf函数,以格式化字符串的形式输出。

1.第一种,直接进行输出,不按需求格式化,引用格式为:printf(“输出数据\n”);

#include<stido.h>
int main()
{
     printf("Hello,World!")//这里字符串里的数据写的是什么屏幕就打印什么。
  return 0;
}

2.第二种格式化字符串进行输出,引用格式为:printf(" 格式化字符串 ", 待输出参数 )

#include<stido.h>
int main()
{
    /*以下printf中的%d和%f为输出打印格式字符,a和b为待打印的参数*/
    int a = 1;
       printf("%d\n",a); //1
      float b = 2;
      printf("%f\n",b);//2.000000
  return 0;
}

更多格式字符见以下表格

image.png

2. 自定义函数

/**仅先了解有返回值的函数&*/。

函数有什么用呢?

比如说:

求两个数的和,我们平常最直接的方法是按以下方法写

#include<stido.h>
int main()
{
    int m = 0;
    int n = 0;
    //输入
    scanf("%d %d",&m,&n);
    //求两个数之和
    int sum = m + n;
    //输出
    printf("%d",sum);
  return 0;
}

如果需要再写几个加法呢,我们需要再定义几个变量如以上方法去写吗?太过于麻烦了!

这时我们直接写一个函数,再需要几次,直接调用几次使用就行。

那么如何把加法的功能写成函数呢?

#include<stido.h>
int Add(int a,int b) //创建函数
{
  int z = a + b; //计算
  return z;
}
int main()
{
   int m = 10;
   int n = 20;
   int sum = Add(m,n); //调用函数
   printf("%d",sum);
  return 0;
}
#include<stido.h>
int Add(int a,int b) //创建函数
{
  int z = a + b; //计算
  return z;
}
int main()
{
   int m = 10;
   int n = 20;
   int sum = Add(m,n); //调用函数
   printf("%d",sum);
  return 0;
}

如何理解这个加法计算的函数的过程呢?


观察以下流程图,我们可以把函数类比成工厂,工厂中的原材料A和原材料B看成函数中的传进的参数m与n,工厂里的加工操作则可以看成是函数中的计算,再经过加工处理之后,也就生产出可以售卖给自己的产品,同样如此,函数经过在内部的计算之后,得到的结果就是通过return返回z值,调用函数,才能将得到的结果传到sum中,再通过sum打印出来。


image.png

image.png

目录
相关文章
一篇文章让你看懂C语言字符函数和内存函数(上)
一篇文章让你看懂C语言字符函数和内存函数(上)
|
30天前
|
机器学习/深度学习 C语言
【c语言】一篇文章搞懂函数递归
本文详细介绍了函数递归的概念、思想及其限制条件,并通过求阶乘、打印整数每一位和求斐波那契数等实例,展示了递归的应用。递归的核心在于将大问题分解为小问题,但需注意递归可能导致效率低下和栈溢出的问题。文章最后总结了递归的优缺点,提醒读者在实际编程中合理使用递归。
60 7
|
1月前
|
存储 机器学习/深度学习 编译器
一篇文章,把你的C语言拉满绩点
一篇文章,把你的C语言拉满绩点
13 0
|
2月前
|
存储 C语言
【C语言基础】一篇文章搞懂指针的基本使用
本文介绍了指针的概念及其在编程中的应用。指针本质上是内存地址,通过指针变量存储并间接访问内存中的值。定义指针变量的基本格式为 `基类型 *指针变量名`。取地址操作符`&`用于获取变量地址,取值操作符`*`用于获取地址对应的数据。指针的应用场景包括传递变量地址以实现在函数间修改值,以及通过对指针进行偏移来访问数组元素等。此外,还介绍了如何使用`malloc`动态申请堆内存,并需手动释放。
|
3月前
|
存储 程序员 C语言
揭秘C语言:这些核心知识你掌握了吗?一篇文章带你突破编程基础,开启高效编码之旅!
【8月更文挑战第22天】C语言作为编程基石,以简洁高效著称,历经数十年仍备受欢迎。本文通过梳理C语言的核心概念,帮助读者深入理解并提升技能。适合各水平读者。基础语法从`main`函数开始,如示例中的“Hello, World!”程序所示。C语言强调头文件包含与语句结尾的分号。变量和数据类型丰富多样,如`int`、`float`、`char`等,合理选择可优化内存使用和性能。指针用于间接访问内存,是C语言的关键特性。控制结构如循环和分支使程序逻辑更灵活。函数支持代码复用与模块化。深入学习还需掌握预处理指令、文件操作等高级特性。通过系统学习与实践,你将能更熟练地使用C语言,构建高效稳定的应用。
61 4
|
3月前
|
C语言
【C初阶——指针5】鹏哥C语言系列文章,基本语法知识全面讲解——指针(5)
【C初阶——指针5】鹏哥C语言系列文章,基本语法知识全面讲解——指针(5)
|
3月前
|
C语言
【C初阶——指针4】鹏哥C语言系列文章,基本语法知识全面讲解——指针(4)
【C初阶——指针4】鹏哥C语言系列文章,基本语法知识全面讲解——指针(4)
|
3月前
|
存储 编译器 C语言
【C初阶——指针3】鹏哥C语言系列文章,基本语法知识全面讲解——指针(3)
【C初阶——指针3】鹏哥C语言系列文章,基本语法知识全面讲解——指针(3)
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的C语言在线评测系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的C语言在线评测系统附带文章源码部署视频讲解等
47 0
|
5月前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的C语言在线评测系统附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的C语言在线评测系统附带文章和源代码部署视频讲解等
30 0