C语言基础知识简摘

C语言基础知识简摘,第1张

C语言基础知识简摘
    • 数据类型
      • 数据类型决定:
      • 常用的数据类型
        • 整型
        • 实型(浮点型)
        • 字符型
        • 其他
    • 运算符及其表达式、语句
      • 运算符和表达式
      • 语句
    • 循环
      • goto(无条件转移语句)
      • while
      • do~while(区别于while,先执行一次循环体语句)
      • for
    • 分支与跳转
      • if语句
        • 两个条件以上时用else if
      • switch 多重选择
      • break和continue
    • 函数
      • 函数的分类
      • 函数的定义
      • 函数的调用
        • 函数的声明
        • 函数的嵌套调用
      • 函数的递归调用
      • 函数的变量
        • 变量的存储类型
          • static关键字的作用
          • extern关键字的作用
    • 指针
      • 指针变量
      • 指向关系的建立
      • 指针变量做函数形参
      • 指向函数的指针
      • 指向函数的指针变量
      • 返回指针值的函数
      • 二级指针
    • 宏定义
      • 不带参数的宏定义
        • 终止宏定义命令
      • 带参数的宏定义
      • 带参数的宏定义与函数的区别
    • 数组
      • 一维数组
      • 多维数组
    • 结构体与联合体
      • 结构体的初始化
      • 联合体、共用体
        • 共用体变量的初始化

数据类型 数据类型决定:
  • 数据占内存字节数 ;
  • 数据 取值范围 ;
  • 其上可进行的 *** 作;
常用的数据类型 整型
类型关键字
有符号基本型(-32768~32767)[signed] int (16位)
有符号短整型(-32768~32767)[signed] short [int] (16位)
有符号长整型(-231~231-1)[signed] long [int] (32位)
无符号基本型(0~65535)[unsigned] int(16位)
无符号短整型(0~65535)[unsigned] short [int] (16位)
无符号长整型(0~232-1)[unsigned] long [int] (32位)
实型(浮点型)
类型关键字
单精度浮点型(3.4e-38~3.4e38)float (32位)
双精度浮点型(1.7e-308~1.7e308)double (64位)
字符型
类型关键字
有符号字符型[signed] char (8位)
无符号字符型(0~255)unsigned char (8位)
其他
无值类型void (用于描述无值函数)
指针类型占2个字节
构造类型包括数组、结构体、联合体
运算符及其表达式、语句 运算符和表达式
运算符表达式
算术:+ -(减法、取负) * / %(取余)由算术运算符、括号和任何有值的对象连接起来符合C语言的要求的式子
自增(减):++(- -)变量++(++变量单独使用前置后置算法相同;复合表达式中前置运算:先自增(减)后运算,后置运算:先运算后自增(减)
赋值:=;复合赋值:双目运算符=表达式变量=确定的值 ;+= -= *= /= %=
位与:&参与运算的两个二进位(补码)均为1,结果位为1,否则为0
位或:丨参与运算的两个二进位(补码)有一个为1,结果就为1
位异或:^参与运算的两个二进位(补码)对应的位相异结果位为1,相同为0
取反:~参与运算的数的各二进位按位取反
左移:<<把<<左边的运算数各二进位全部左移若干位,高位舍弃,低位补0
右移:>>把>>左边的运算数各二进位全部右移若干位,符号位随之移动
语句
  • 表达式语句:在表达式后加一个; 如 zc=606;
  • 流程控制语句:if switch for while do~while break continue goto return
  • 空语句:只有一个“;” 用于完善选择结构和循环结构
  • 复合语句:以花括号“{ }”括起来的功能相对独立的程序段
  • 函数语句:函数调用,如printf() scanf()
循环 goto(无条件转移语句)

一般形式: goto 语句标号;

while

用于实现当型循环结构,当逻辑量值为真时,执行循环体语句

  • 循环体有可能一次也不执行
  • 尽量避免while(1)死循环
  • 循环体内可以加入break、return、goto结束循环
  • 循环体内包含一个以上的语句,应用“{ }”括起来组成复合语句
do~while(区别于while,先执行一次循环体语句)

用于实现直到型循环结构,执行循环体语句,直到逻辑量为假结束
一般形式:do{ 循环体语句; } while(逻辑量);

for

一般形式:for{表达式1;表达式2;表达式3;} 循环体语句;
如 for(循环变量赋初值;循环条件;循环变量增量)

分支与跳转 if语句
if(条件语句)
{
    满足条件执行的语句;
}  //只有一条执行语句时{}可以省略
if(条件语句)
{
    满足条件执行的语句;
} 
else
{
   除了if以及else if执行条件外,剩下条件的执行语句;
}
两个条件以上时用else if
if(条件语句)
{
    满足条件执行的语句;
} 
else if(条件语句)
{
    满足条件执行的语句;
}
else if(条件语句)
{
    满足条件执行的语句;
}
...
else
{
   除了if以及else if执行条件外,剩下条件的执行语句;
}
switch 多重选择


break和continue


break能用于循环语句和switch语句
continue只能用于循环语句

函数 函数的分类
  • 标准函数:又称为库函数,由c系统提供,可直接使用,需要在程序开头包含原型声明的头文件。

  • 自定义函数:由程序员自己编写,要在程序中定义函数本身,在主函数中调用该函数。

  • 有参函数:函数定义中包含形式参数的函数。

    如sqrt()

  • 无参函数:函数定义中不包含形式参数的函数。

  • 有值函数:该函数在完成函数功能后会向主函数返回一个执行结果。

  • 无值函数:该函数在完成函数功能后无返回值。

函数的定义

函数一般的定义形式:
类型说明符 函数名(带类型说明的形式参数表列)
{
数据描述部分
算法描述部分
}

  • 函数定义相互独立,互不从属
  • 无参函数定义时函数名后的括号不能省略
  • 有参函数定义时,每个形参都必须独立声明类型
  • 函数值类型由函数原型中的函数类型来确定
  • 有值函数使用return语句时,应保证函数体所有分支都应给主调函数一个返回值
函数的调用 函数的声明
  • 库函数的声明使用文件包含命令实现:#include <头文件>
  • 自定义函数声明:
    (1)内部声明:在主调函数内声明被调函数(局部声明)
    (2)外部声明:在函数外声明被调函数(全局声明)----习惯上函数声明采用外部声明
函数的嵌套调用

在调用一个函数的过程中可以调用另外一个函数

#include "stdio.h"
fun2(int x,int y)
{
int z;
z=2*x-y;
return z;
}
 
fun1(int x,int y)
{
int z;
z=fun2(x,x+y);
return z;
}
 
void main()
{
int a,b,c;
printf("请输入两个整数: \n");
scanf("%d%d",&a,&b);
c=fun1(a,b);                // 调用fun1()函数
printf("%d\n",c);
}
函数的递归调用

一个函数在它的函数体内直接或间接调用自身

int fun(int a)
{
   int b=a-1;
   c=fun(b);
   return c;
}
函数的变量
  • 局部变量(内部变量):在定义它的函数内有效,但是函数返回后失效

  • 全局变量(外部变量):在所有源文件内均有效。

    在同源文件的函数中使用使用全局变量,需要将全局变量提前声明;同时在不包含全局变量定义的不同源文件需要用extern关键字再次声明。

  • 局部变量优先原则

  • 全局变量有默认值(数值型为0,字符型为空字符)

  • 全局变量可以在函数外定义并初始化,但不能进行赋值 *** 作

变量的存储类型
  • 动态存储变量:当程序运行进入定义它的函数或复合语句时才被分配存储空间,程序运行结束离开此函数或复合语句时,所占用的内存空间被释放。

    这是一种节省内存空间的存储方式(自动类型、寄存器类型)

  • 静态存储变量:在程序运行的整个过程中,始终占用固定的内存空间,直到程序运行结束,才释放占用的内存空间。

    静态存储类别的变量被存放在空间的静态存储区(静态类型、外部类型)

static关键字的作用
  • 在函数体中,一个被声明为静态的变量在这一函数被调用过程中只会被分配一次内存,且整个运行期间不会重新分配
  • 在函数体外、某个源文件内,一个被声明为静态的变量只可被该源文件内的所有函数访问,但不能被其他源文件的函数访问。

    它是一个本地的全局变量

  • 在某个源文件内,一个被声明为静态的函数仅仅只可以被这个源文件的其它函数调用。

    也就是说,这个函数被限制在声明它的源文件的本地范围之内使用

extern关键字的作用
  • 在本文件范围内扩展外部变量的作用域
  • 将外部变量作用域扩展到其他源文件中
指针

(变量的地址称为变量的指针)
专门用来存放其他变量地址的特殊变量称为指针变量(指针变量的值是指针)
*p=872; 等价于 a=872;(指针变量p指向变量a,p中存有a的地址)

指针变量

指针变量定义的一般形式:
类型说明符 *指针变量名;
指针声明符 * 在定义指针变量时被使用,说明被定义的那个变量是指针

int *p;     /* 定义一个指针变量P,指向整形变量 */
char *cp;		/* 定义一个指针变量cp,指向字符型变量 */
float * fp; 		/* 定义一个指针变量fp,指向实型变量 */
double *dp1, *dp2;		/* 定义两个指针变量dp1和dp2,指向双精度实型变量 */

定义多个指针变量时,每个指针变量前面都必须加上*
指针变量的类型不是指指针变量本身的类型,而是指定它所指向的变量的数据类型

  • 指针变量名是一个标识符,要按照C标识符的命名规则对指针变量进行命名
  • 指针变量的数据类型是它所指向的变量的类型,一般情况下一旦指针变量的类型被确定后,他只能指向同种类型的变量
  • 在定义指针变量时需要使用指针声明符 * ,但指针声明符并不是指针的组成部分。

    例如:定义int p;说明p是指针变量,而不是p

指向关系的建立
  • 将变量的地址初始化赋给指针变量
int a;
int *p=&a;
  • 用初始化了的指针变量给另一个指针变量做初始值
int x;
int *p=&x;
int *q=p;
  • 将一个指针变量初始化为一个零指针
int *p=NULL;
  • 指针变量中只能存放地址(指针),不能将一个非零常量赋值给某一指针变量
  • 指针变量中只能存放与其指向类型相同的变量的地址
指针变量做函数形参
  • 通过实参向形参的传递,使得形参指针变量和主调函数中的变量建立了指向关系
  • 由于被调函数的形参指针变量指向了主调函数中的变量,所以可以在被调函数中通过间接访问的方式访问主调函数中的变量
  • 主调函数中变量值的改变是在被调函数执行的过程中实现的,所以可以把主调函数中被改变的变量看作是函数的返回值,从而解决了函数使用return语句只能得到一个返回值的问题
  • C语言中函数参数的传递只有单向传递的概念,一是单向数据值传递,二是单向地址值传递。

    无论哪种单向传递方式的函数调用,形参的改变都不会影响实参

指向函数的指针

函数名也称为函数的指针,函数名代表的就是该函数的入口地址。

指向函数的指针变量

函数的指针能赋值给一个特定的指向函数的指针变量,并能通过指向函数的指针变量调用其所指向的函数

  • 指向函数的指针变量的定义
    类型说明符 (*指针变量名) (形参的类型表列);
int (*pf) (int);
float (*pf1) (float,float);
  • 用指向函数的指针变量调用函数
double (*pf)(int),fac(int),m;
pf=fac;
m=(*pf)(10);
m=pf(10);
//指向函数的指针pf和*pf是完全一样的
返回指针值的函数

定义形式:
类型说明符 *函数名(带类型说明的形参表列) {函数体}

int *fun(int *p)
{
  ...
  return p;
}

指针型函数与数值型函数的定义形式区别在于函数名前有"*",函数体中,使用return语句返回的可以是指针变量,也可以是变量的地址

二级指针

二级指针就是指向指针的指针,如 int **p;

int a=20;  int *ap=&a;
int **app;
app=&ap;
宏定义 不带参数的宏定义

#define 宏 字符序列

  • 为了与一般变量名、函数名区别,宏通常采用大写字母形式
  • 允许宏嵌套定义,可以使用定义过的宏定义新宏
  • 宏定义是用宏代替字符序列,宏展开时仅作简单替换,不要随意加括号
  • 宏定义不是C语句,宏定义后不要随意加分号;如果加,分号就是宏的组成部分
  • 程序中用双引号括起来的字符串或单引号括起来的单个字符中包含有与宏相同的符号时,宏展开时不置换
  • 在宏作用域范围内不允许重新定义宏
  • 不带参数的宏定义多用于定义符号常量
  • 不带参数的宏也可以表示数据类型
终止宏定义命令

#undef 宏
功能:从该命令开始,宏不再代表相应的字符序列

带参数的宏定义

#define 宏(形参表列) 字符序列
程序中使用带参数宏,称为宏调用:
宏 (实参表列);

#define PI 3.1415926
#define S(r) PI*r*r
#include 
void main()
{
  float a,area;
  a=3.6;
  area=S(a);
  prinf("r=%f\n area=%f\n",a,area);
}
  • 带参数宏的形参和实参仅仅是一个符号,没有类型
  • 宏定义时,宏名与参数表间不能有空格
  • 宏体中可以使用#
带参数的宏定义与函数的区别
函数
参数传递数据值或指针值传递给形参用实参替换字符序列中的形参
处理时刻及内存分配程序运行时处理,分配临时内存单元宏展开在预编译时处理,运行时不存在分配内存
对源程序的影响无影响宏展开后程序长度改变
时间占用占用程序运行时间占用编译时间
数组

数组:一组相同类型数据的有序集合
数组维数:表示数组元素时使用的下标个数

一维数组


一维数组的引用:
数组名[下标] []是变址运算符
一维数组的初始化:

(1)利用赋值语句初始化
	char str[26],ch;
	str[0]= 'A';
	str[1]= 'B'; 
	…
	str[25]= 'Z';

(2)利用赋值语句初始化
char str[26],ch;
     for(ch='A';ch<='Z';ch++)     
              str[ch-‘A’]=ch;    //将26个大写字母依次存放到str[0] 	                                   			    、 str[1]、 ……str[25]中

(3)利用输入语句初始化
char  str[26];    int i ;
    for(i=0; i<26; i++) scanf("%c",&str[i]);...

多维数组

定义:类型标识符 数组名[常量表达式1][常量表达式2]

二维数组的引用:
C 语言对数组元素的引用有以下几种规定:

行下标、 列下标均从 0 开始计算。

数组下标表示了数组元素在数组中的顺序号。

因此,如果定义:
float Num[2][4]={ 0,1,2,3,4,5,6,7 };
则可以访问的行下标为 0、1,可以访问的列下标为 0、1、2、3。

不能越界引用数组元素Num[1][8]、Num[5][3],因为 C 语言从不检查数组下标是否越界,程序员要自己确认数组元素的正确引用,不能越界访问。

在 C 语言中只能逐个引用数组元素,而不能一次引用整个数组。


例如,不能用一个语句输入整个数组: scanf("%f",Num);

必须使用循环语句逐个输入数据:

for(i=0; i<2; i++) 
    for(j=0; j<4; j++) 
         scanf("%f", &Num[i][j]); 

数组元素和普通变量一样,可以出现在任何合法的 C 语言表达式中。


例如,数组元素可以出现在函数调用:printf(“%d”, Num[i][j]);中。

定义数组时,方括号中出现的是某一维的长度,只能是常量或常量表达式;

引用数组元素时,方括号中出现的是该元素在数组中的位置标识,可以是常量,变量或任何合法的C 语言表达式

#include
void main(void)
{
int a[2][3]={{1,2,3},{4,5,6}};

printf("%d, %d\n",a[0][0],a[1][0]);

printf("%d, %d, %d, %d\n",a,a+1,&a[0][0],&a[1][0]);

}

结构体与联合体

关键字:struct

struct student
{
 
    long int id;
 
    int age;
 
    char name[8];
 
};

声明结构体变量

struct student
{
 
    long int id;
 
    int age;
 
    char name[8];
 
}stu1;      //在结构体定义时,同时声明一个这种结构体变量stu1
结构体的初始化
struct student stu1;
 
stu1.id = 12345;            //通过成员运算符'.'来访问结构体的成员变量
 
stu1.age = 20;
 
strcpy(stu1.age,"Liang");     //因为数组在非初始化时,不能直接通过数组名直接赋值,strcpy函数需要包含头文件string.h    错误的写法:stu1.name = "Liang";
 

结合使用typedef
使用typedef为自定义结构体定义别名,在声明变量时可以省略struct关键字

typedef struct student 
{
	long int id;
	int age;
	char name[8];
}Student,*StuPtr;
typedef struct student 
{
	long int id;
	int age;
	char name[8];
}
 
typedef struct student Student;     //(这两句可合并为一句:typedef struct student Student,*StuPtr;) 
typedef struct student* StuPtr;   
联合体、共用体

关键字:union
共用体也叫联合体,使几个不同类型的变量共占一段内存(相互覆盖),也就是说共用体的成员共用一片内存,后赋值的成员变量的数据才是共用体的生效数据,因为前面的赋值已经被覆盖了。

共用体所占内存至少能够容纳最大的成员变量所需的空间,应用场景,比如需要一种既可以存储int型数据也可以存储double型数据的变量
定义:

union uu
{
	int i;
	double db;
};

共用体的特点:

  • 所有成员引用的是内存中相同的位置
  • 共用体变量任何时刻只有一个成员存在
  • 共用体变量定义分配内存,长度取决于最长成员与最宽基本数据类型成员
共用体变量的初始化

union MyUnion
{
    int i;
    char chs[11];
}u = { 10 }, u2 = {.chs="niko"};

void main()
{
    union MyUnion mu = { 1 };  // 默认初始化第一个成员
    union MyUnion mu2 = { .chs = "hello" };  // 指定要初始化的成员
    printf("mu.i=%d,mu.chs=%s\n", mu.i, mu.chs);  // 一个成员最后被赋值,其他的会出现垃圾值
    printf("mu2.i=%d, mu2.chs=%s\n", mu2.i, mu2.chs);

    u2 = u; // 赋值初始化
    strcpy(u2.chs, "hello world");  // 给共用体变量成员赋值
    printf("u2.i=%d,u2.chs=%s\n", u2.i, u2.chs);
    printf("MyUnion = %d\n", sizeof(union MyUnion));

    union MyUnion *up = &u;  //定义指向共用体的指针
    up->i = 100;
    printf("%d\n", up->i);
    system("pause");
}

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/674630.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-04-19
下一篇2022-04-19

发表评论

登录后才能评论

评论列表(0条)

    保存