C语言基础知识手册(自用)


前言

  本文主要是对作者学到的知识进行的一个总结,方便以后遗忘时可以回来看看。如果帮助到大家,实属荣幸,如果有不足之处大家也可以在评论中提出来,互相学习互相增长,随时更新,谢谢大家。


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

一、C代码的基础框架

  .c 结尾的是C语言的源程序。

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

  .h 译为head,表示头文件。stdio.h表示standard input output是标准输入输出头文件。对于头文件与函数的关系,我们可以联想成工具箱与工具,方便记忆。
  “< >”是Linux系统自带的头文件,而自己的写的头文件用 " “,比如"my.h” 。
  “;”代表一句话的结束,其功能是在屏幕上打印输出字符串。
  int是整型,一种C语言的数据类型,后面会详细说明。
  main是函数函数体开始,函数的返回值类型是int,() 里面放的main函数的参数列表。需要注意的是一个程序只能有一个入口函数main。
  “printf”是一个函数,格式化输出函数。
  “\n”是一种换行符。
  " "表达的是字符串, " "之间写什么,屏幕上就原封不动打印输出什么。
  return是返回值的意思,返回值是0,是main函数体的结束。

二、变量与常量

1.数值类型

1.1-基本类型

1.1.1-整型int

  (unsigned-无符号) (short int)/short:占用字节2,比特数16,取值范围:

-32768-32767,带unsigned:0-32767*2=65535。

  (unsigned-无符号)int:占用字节4,比特数32,取值范围:

-2147483648-2147483647,带unsigned:0-2147483647*2=4294967295。

  (unsigned-无符号)long int(long):占用字节8,比特数32,取值范围:

-2147483648-2147483628,带unsigned:0-2147483628*2=4294967295

以上类型,对应输出符号都为%d。

1.1.2-浮点型float

  float:所占字节4,比特数32,有效数字6~7,对应输出符号为%f。
  double:所占字节8,比特数64,有效数字15~16,对应输出符号为%lf。
  long double:所占字节16,比特数64,有效数字18~19,对应输出符号%lf。
  .2f:结果保留两位小数。

1.1.3-字符型char

  (unsigned-无符号)char:所占字节1,比特数8,取值范围-128127,无符号0255,对应输出符号%c。
  string:字符串类型,可理解成字符型数组,内部容量根据实际需求确定,对于输出符号%s。
  字符串常量与静态变量类似,都是程序结束时才被释放。
  同时,字符有其对应的ASCII码,
  ‘0’ -‘9’~48-57
  ‘A’-‘Z’~65-90
  ‘a’-‘z’~97-122

1.1.4-枚举型enum

  enum:枚举变量只能被赋予枚举值。枚举值会被默认标号,从0开始,依次递增。

enum 枚举名
{
  枚举值1,
  枚举值2,
  枚举值3,
  …………
}枚举变量表列(a,b,c……);
1.1.5-指针型

  *+any(例:int *a),指针类型包含很多,常见的有int型、char型、struct型等。指针常量只有唯一的一个空地址NULL。

1.2-构造类型

1.2.1-数组

一维数组:
  最简单的数组,语法为“数组类型 数组名[数组内容个数]”由一个集合构成,标号从0开始。
  例:int a[3],则调用数组内部成员分别通过a[0]、a[1]、a[2]调用。
二维数组:
  多维数组中,最简单的数组,内部结构可理解成矩阵,语法为“数组类型 数组名[行数][列数]”,调用内部成员方式与一维数组类似,只不过多了描述行和列的位置。
  :int a[2][2],内部结构为两行两列的二维数组,调用第一行第二列的语法为a[0][1]。

1.2.2-结构体

  用户自定义数据类型的一种,语法结构为:

struct 结构体名
{
  数据类型  成员名1;
  数据类型  成员名2;
  …………
}结构体变量表列;(可写可不写,与普通变量一起定义也可以)
例:
struct Stu
{
  int age;
  char sex;
  char* name;
}e1,e2;struct Stu
{
  int age;
  char sex;
  char* name;
};
struct Stu s1;
1.2.3-共用体

  用户自定义类型的另一种,与语法结构为:

union  Stu
{
  int age;
  char sex;
  char *name;
};

  创建变量的方法与结构体相同,唯一不同的是,共用体内存由其最大的成员决定。

2.常量

  多指存在于代码中的内容不固定的一个类型的数值名。
  例:int a;——定义了一个整型变量a。
    char b=‘c’;——定义了一个字符型’’变量b,其值为‘c’。

3.变量

3.1-const

   使用const定义的常量,之后不能被改变,做参数也是。
  语法规则:int const a;
     或:const int a;
对于指针
   int * const a;与const int *a/int const *a;是不同的,前者是指针常量,不能改变a的值;后者是常量指针,可改变其指向,但不能改变其指向的变量的值。

3.2-define

  一种进行符号替换的关键字,通常与头文件放在一起。
语法结构:
#define A 10 ——让代码中,所有的A的值都为10

3.3-typedef

  用于给一种数据类型定义新名字的关键字。
  :typedef signed char s8——给有符号字符型取名为s8
    之后便可使用新名字命名:s8 a;——定义了一个有符号字符型变量a。
  当对结构体使用typedef时,需要注意。

typedef struct Stu
{
    成员表列
    ……
}STU,*PSTU;

  此时,在主函数中可以通过STU定义普通结构体变量,使用*PSTU定义指针结构体变量。

3.4-static

  static关键字声明的静态变量存储在数据段(也称全局区)。未初始化时其值为0存储在数据段的未初始化区,初始化时存储在数据段的初始化区。
修饰局部变量,称静态变量,作用域不变,生命周期被延长,直至整个程序结束,如果被调用多次执行的是同一个变量,值初始化一次,未初始化默认值为0。
  修饰全局变量,变量只能在本文件调用,不能被其他文件调用。
  修饰函数,只能在本文件中使用,不能被其他文件调用。
  若想在其他文件中调用,就需要使用extern进行外部声明。
  静态变量在声明后,除非在外部文件中使用extern声明后可以调用,其余情况下只能在本文件中使用,并且在程序结束时才被销毁。
  例:

static int a = 10;static void add()
{
  printf(1+1=2);
}

  使用static声明后也可以看作将该块内容保护起来,不能被其他文件调用或修改。

4.作用域

4.1-局部变量

  在主函数内部定义的变量都属于局部变量,仅在主函数内部有效。每个函数的参数也属于局部变量,作用域仅限于当前函数内。

4.2-全局变量

  (extern可加可不加。)在任何函数外部定义的变量都是全局变量,在整个代码中都有效。

5.存储模型

5.1-自动

  一般没有特别声明的变量,都属于自动型变量,auto可写可不写。同时具有动态存储期、代码块的作用域、空连接。
  例:int a; auto int a; 二者是一样的。

5.2-寄存器

  使用修饰符register声明的变量属于寄存器存储类。具有自动存储器、代码块作用域和空连接。
  需要注意的是,不能对该类性的变量使用“&”,因为他存储在cpu的寄存器中。

5.3-静态、空连接

  使用static修饰的变量属于静态空连接存储类,使用静态存储方式。所有全局变量都是静态变量,而局部变量只有定义时加上类型修饰符static,才为局部静态变量。
  空连接指该变量的作用域是定义它的代码块。
  使用static定义的全局变量属于静态全局变量。
  使用static定义的局部变量属于静态局部变量,生存期与为整个程序执行期间,作用域与局部变量相同,只能在定义该变量的函数内使用该变量。

5.4-静态、外部链接

  未使用static描述的的全局变量属于静态、外部链接存储类,具有静态存储时期、文件作用域和外部链接。在使用外部变量的函数中使用extern关键字来再次声明,若在其他文件中定义的,则必须使用extern。
  外部链接:外部链接的变量可以在多个文件中使用。

5.5-静态、内部链接

  使用static描述的全局变量属于静态、内部链接存储类,仅能被与他在同一文件的函数使用。
  内部链接:内部链接的变量只能在一个文件中使用。

6.预处理

6.1-预定义

  一些之前定义好的一些符号,用于表示各种信息。
例:
  FILE 表示正在与编译的源文件名
  LINE 表示文件当前行的行号
  FUNCTION 表示当前所在的函数名
  DATE 表示预编译文件的日期
  TIME 表示预编译文件的时间
  STDC 如果编译器遵循ANSIC,则值为1

6.2-宏定义

  define的具体应用。
  无参数宏定义:
  例:#define M (y + 3),代码中的“(y+3)”都可由M代替。
  有参数宏定义:
  例:#define M(y) y+3,代码中的“y+3”都可由M(x)代替,使用时必须传参。
  需要注意的是,宏定义无脑替换,定义的什么,表达式就是什么,没有需要自己加括号的情况。

#define X 2
#define Y X+1

printf("result is %d\n",Y*Y);
//结果为2+1*2+1 = 5

6.3-条件编译

  语法结构为:
#if 条件
………
#endif
  例:

#ifdef DEBUG
	int i;
	for ( i = 0 ; i < 5 ; i++ )
	{
		printf("%d\n",a[i]);
	}
#endif

7.进制转换

  简单方法:
  八进制-%o、十进制-%d、十六进制-%x/%X,若在八进制与十六进制前加“#”,则在每个数前显示“0”。
  复杂方法:
  十进制转二进制——先跟2取余,再除2,直至除的结果为0
  十进制转八进制——先跟8取余,再除8,直至除的结果为0
  十进制转十六进制——先跟16取余,再除16,直至除的结果为0
  二进制转八进制——三个一组,每组按421算值,  例:010001->010 001->021
  二进制转十进制——从最右侧开始以0开始依次递增1到最左端结束,然后2取标号的幂相加,例:10001100->22+23+2^7
  二进制转十六进制——四个一组,每组按8421算值,
  :10100010->1010 0010->0xA2

8.获取随机值

  语法结构
  头文件:#include<time.h> ——只为能使用time(NULL);
  语句:srand(time(NULL));
   int z=rand()%n;——对n取余表示随机获取n之前的值。
  原理
  time()是获取1970年至今的差数,srand()是获取一组随机数,srand(1)是一组,srand(2)又是一组。
  而rand()从刚才获取的一组随机数。

三、运算符

1.算术运算符

  “+”加法运算符 int a = 3 + 5; //a = 8;
  “-”减法运算符 int b = 3 - 5; //b = -2;
  “*”乘法运算符 int c = 3 * 5; //c = 15;
  “/”除法运算符 int d = 5 / 3; //d = 1;
  “%”模运算符(求余运算) int e = 5 % 3; //e = 2;
  “,”逗号运算符
  例:s=2; d=3; a=12+(s+2,d+4);先算括号内的值:s+2=4,d+4=7;括号内应为(4,7),括号内取值只取最后一个,如果没有括号则取第一个;a=12+7=19。

2.关系运算符

  “<”小于
  “<=”小于等于
  “>”大于
  “>=”大于等于 //(1)(2)(3)(4)优先级相同(高)
  “==”等于
  “!=”不等于 //(5)(6)优先级相同(低)

3.逻辑运算符

  “&&”逻辑与 // (a>b)&&(x>y)
  “||”逻辑或 // (a>b)||(x>y)
  “! ”逻辑非 // ! (a > b) ###举例:if(!a)
  对于“&&”,当第一个条件表达式成立时,需要看第二个,第二个也正确,结果为1否则为0;当第一个不成立时,不需要再看第二个,结果为0。
  对于“||”,当第一个条件不成立时,需要看第二个,第二个也不成立,结果为0否则为1;当第一个条件成立时,不需要看第二个,结果为1。

4.sizeof()

  作用:求变量或数据类型所占内存空间的大小,以字节为单位。
  若为字符串测量,包含了‘\0’。

5.优先级

  算数运算符>移位运算符>条件运算符>按位运算符>赋值
  括号成员第一:()、[]、->、.、
  全体单目(操作数只有一个)第二:!、~、++、–、-、(类型转换)、、&、sizeof()
  乘除余三:
、/、%
  加减四:+、-
  移位五:>>、<<
  关系六:<、<=、>、>=
  等于不等排第七:=、!=
  位与、异或、和位或“三分天下”八九十:第八“&”、第九“^”、第十“|”
  逻辑或跟与十二和十一:第十一“&&”、第十二“||”
  条件高于赋值:十三“ ? : ”、十四“=、+=、-=、*=、/=、%=、>>=、<<=、&=、^=、|=”
  逗号运算级最低。:“,”

四、程序结构与控制语句

1.输出语句

1.1-格式化输出

int printf( const char *fort mat,……);

  在代码中,我们直接用

printf(“变量输出符   转义字符……杂七杂八……”,变量表列);

  例:

printf(%d , %f \n……”,a,b,……)

1.2-字符输出函数

int putchar(int c);

  在标准输出上显示一个字符,putchar(……);
例:

putchar(a);putchar(‘\n’);

2.输入语句

2.1-格式化输入函数

  按照自己设置的输出格式输出。

scanf(“变量输出符……”,&(取地址符)参数表列……);

例:

scanf(%d %f……”,&a,&c……);scanf(%d:%f……”,&a,&c……);

  在输入时需要按照引号内部的格式输入。

2.2-字符输入函数

int getchar(void);

  在键盘上都一个字符,包括\n(enter)。
  例:

getchar();

3.选择语句

3.1-if、else if、else

  语法格式

if(判定条件)
{
    
}
else if(判定条件)
{
   
}
else if(判定调价){
   
}
……(等等else ifelse{
  
}

  不写花括号,if只识别其下面第一条语句。

3.2-switch

  语法格式

switch(整形表达式)
{
    case 目标值1(变量):
      操作语句;
    break;
    case 目标值2:
      操作语句;
    break;
    …………
    default:
      操作语句;
    break;
}

  default是都不满足才执行。
  当case没有break时,switch里的条件会从满足往后都会执行一遍,包括了default。

4.循环语句

4.1-while

  先判断在操作。

while(条件语句)
{
    
}
只要满足条件就一直执行。
例:
while(a<5)while(1)
{                         {
   a++;                         //死循环
}                         }

4.2-do-while

  先操作,在判断。

do
{
    
}while(条件语句);
例:
do
{
   
}while(a<3);

4.3-for

  语法结构

for(变量或直接赋初值;条件语句;执行后需要的操作)
{
    
}
例:
for(int a; a<5;a++)
{
    printf(%d \n”,a);
}

  for的无限循环——for( ; ; ){}。

5.转向语句

5.1-continue

  用于跳过本次循环,进入下一次循环。

5.2-break

  用于循环语句或switch中,用于结束循环或选择。
  跳出循环还可以用return、goto等。当处于多层循环中,使用一次break只跳出最内层循环,以此类推。

五、数组

1.一维数组

1.1-语法结构

  存储类型 数据类型 数组名[数组下标]

例:int a[10]char c[10]、……

1.2-内存分配

  占用连续空间,数组名是起始地址,对数组名使用sizeof可得出数组占用的总空间。
地址      数组
0XB8F00000  a[0]
0XB8F00004  a[1]
0XB8F00008  a[2]
0XB8F0000C  a[3]
0XB8F00010  a[4]
………… ……
  对于数组长度,可以通过“sizeof(数组名)/sizeof(数组类型)”或“sizeof(数组名)/sizeof(数组的第一个元素)”求得。在这里,sizeof(数组名)求得的是整个数组的大小。

1.3-初始化

  1) 直接初始化:如int a[5]={1,2,3,4,5},当所有变量都被赋值“[]”内的数可以不写。
  2) 部分初始化:int a[5]={1,2},其余值会被赋值为0
  3) 库函数初始化:memset(a,0,sizeof(a));,将数组用0填充。
  4) 循环初始化:for(int i;i<3;i++){ scanf(“%d”,&a);}。

1.4-引用

  数组名 [下标]

例:a[5]=3;

1.5-应用

1.5.1-冒泡排序

  第一轮先将第一个数与第二个数进行比较,若大于或小于则进行换位,否则不操作,接着将第二个数与第三个数进行比较,以此类推,第一轮结束,最大或最小的值会被放在最后。随后一直进行至最后一位开始即可。

//x指数组总大小。
 for (int i = 0; i < x; i++)
    {
        for (int j = 0; j < x-(i+1); j++)
        {
            if(a[j]>a[j+1])
            {
                t=a[j];
                a[j]=a[j+1];
                a[j+1]=t;
            }
        }
    }
1.5.2-选择

  先将首位依次与其他位比较,如果大于或小于则进行换位,否则不操作,比较完成再将下一位依次与其他位比较。

//x指数组总大小。
 for (int i = 0; i < x-1; i++)
    {
        for (int j = i+1; j < x; j++)
        {
            if(a[i]>a[j])
            {
                t=a[i];
                a[i]=a[j];
                a[j]=t;
            }
        }
}

2.多维数组

  多维数组以二维数组为例,多维数组用法可由二维数组类推而得。

2.1-语法结构

  存储类型 数据类型 数组名[数组行下标][数组列下标]

2.2-内存分配

  二维数组由多个一维数组组成,在内中存放时:
以a[1][3]为例
地址        数组
0XBFF58A90    int a[0][0]
0XBFF58A94    int a[0][1]
0XBFF58A98    int a[0][2]
0XBFF58A9C    int a[1][0]
0XBFF58AA0    int a[1][1]
0XBFF58AA4    int a[1][2]
  而我们理解二维数组时,通常通过矩阵加深理解。
以a[3][3]为例。
A[0]  A[0][0] A[0][1] A[0][2]
A[1]  A[1][0] A[1][1] A[1][2]
A[2]  A[2][0] A[2][1] A[2][2]

2.3-初始化

  降维按行初始化

int a[2][3] = {{1,2,3},{4}};
//只初始化了部分数据,其余都是0

  按线性存储初始化

int a[2][3] = {1,2,3,4};
//没有初始化的,都是0

  可省行数初始化

int a[][3] = {{1,2,3},{4,5,6}};

3.字符数组

  大多数情况下与一维数组、二维数组相同,但需要注意的是,字符数组未初始化的值会被赋为‘\0’,而且当使用“”来定义一个字符数组时,一个字符数组以‘\0’结尾。比如,“abcde”看似有五个字符,其实有6个。
  当前字符数组长为6,则a[5]是‘\0’,如果初始化或赋值时,最后一位被覆盖会出现内存访问越界的错误。

4.字符串

  是以‘\0’为结束字符的一组字符。

4.1-定义

  定义

char name[]= “akai”;——长度为5,因为有结束字符\0,。
char name[] = {“apple”};

4.2-输入输出

  除了基本的,通过循环输入输出,还可通过scanf和printf进行输入输出,使用“%s”作为标识符,使用字符串名字为数组首地址。

例:scanf(%s”,&name);
    printf(%s”,name);

  使用循环遍历时,可以把“a[i]!= ‘\0’”作为结束条件。
  还可以通过“gets(name);/puts(name);”进行输入输出。直接对字符串进行输入输出。

4.3-字符串处理函数

4.3.1-strcpy-字符串拷贝函数
strcpy(dest,src);//将src拷贝至dest中,返回值是目标串的起始地址。
4.3.2-strcat-字符串连接
strcat(dest,src);//将src的内容加至dest末尾,
                //要注意dest的空间需要足够大。
4.3.3-strcmp-字符串比较
strcmp(s1,s2);//比较s1和s2,二者相等返回值=0;
              //s1大于s2返回值>0;s2大于s1返回值<0。
4.3.4-strlen-字符串长度
strlen(s1);//测s1字符串长度,不含结束标志。
4.3.5-strtok-字符串分解
strtok(s,delim);//以delim的字符串作为分隔符,分割s,
                //返回值为分解出的字符串地址。
4.3.6-atoi-转换数字字符串
int num = atoi(a);//将数字字符串转换成数字。

总结

2022.08.12——本次更新了控制语句和数组,下一次会更新指针,敬请期待。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值