一、概述
最近家里有点事,趁在家的这段时刻,温习一下C言语中心常识,后的底层开发、音视频开发、跨渠道开发、算法等方向的进一步研讨与学习埋下伏笔
咱们在前面一篇文章已经对C言语有了初步的知道,咱们从本篇文章开端学习C言语的中心常识
二、C 言语中心语法|数据类型、常量与变量、存储类
1. 底子语法
上一末节咱们知道了一个简略的小应用由哪些部分组成,这将有助于咱们了解 C 言语的其它底子的构建块。
C 程序由各种Token组成,Token可所以 关键字
、标识符
、常量
、字串符值
、或许是一个符号
。
下面咱们来看一下 C 中的关键字,这些关键字不能作为常量名,变量名或许其它标识符称号:
关键字 | 阐明 |
---|---|
auto | 声明主动变量 |
break | 跳出当前循环 |
case | 开关句子分支 |
char | 声明字符型 变量或许函数回来值类型 |
const | 声明只具可读 变量 |
continue | 完毕当前循环,开端下一个循环 |
default | switch句子中的其它分支 |
do | do-while循环句子的循环体
|
double | 声明双进展浮点型 变量或许函数回来值类型 |
else | 条件句子否定分支 |
enum | 声明枚举类型
|
extern | 声明变量或函数是在其它文件或本文件的其他方位界说 |
float | 声明浮点型 变量或许函数回来值类型 |
for | 一种循环句子
|
goto |
无条件跳转 句子 |
if | 条件句子 |
int | 声明整型 变量或函数 |
long | 声明长整型 变量或函数回来值类型 |
register | 声明寄存器变量
|
return | 子程序回来句子
|
short | 声明短整型 变量或许函数 |
signed | 声明有符号类型 变量或许函数 |
sizeof |
核算数据类型或许变量长度 (即所占字节数) |
static | 声明静态变量
|
struct | 声明结构体类型
|
switch | 用于开关句子 |
typedef | 用以给数据类型取别号
|
unsigned | 声明无符号类型 变量或函数 |
union | 声明共用体类型
|
void | 声明函数无回来值或无参数,声明无类型指针
|
volatile | 阐明变量在程序履行中可被隐含地改动 |
while | do-while/while 循环句子的循环条件 |
2. 数据类型
在 C
言语中,数据类型指的是用于声明不同类型的变量或函数的一个广泛的体系。变量的类型决议了变量存储占用的空间,以及怎么解释存储的位模式。
C
中的类型可分为以下几种:
类型 | 阐明 |
---|---|
底子类型 | 它们是算术类型,包括两种类型:整数类型 和 浮点类型 。 |
枚举类型 | 它们也是算术类型,被用来界说在程序中只能赋予其必定的离散整数值得变量。 |
void 类型 | 类型阐明符 void 表名没有可用的值 |
派生类型 | 它们包括:指针类型 、数组类型 、结构类型 、共用体类型 和 函数类型
|
(其它资料中看到相对更细致的划分: | |
) | |
整数类型 |
下表列出了关于标准整数类型的存储巨细和值规模的细节
类型 | 32 位 | 64 位 | 值规模 |
---|---|---|---|
char | 1 | 1 | -128 到 127 或 0 到 255 |
unsigned char | 1 | 1 | 0 到 255 |
int | 4 | 4 | -32,768 到 32,767 或 -2,147,483,648 到 2,147,483,647 |
unsigned int | 4 | 4 | 0 到 65,535 或 0 到 4,294,967,295 |
short | 2 | 2 | -32,768 到 32,767 |
unsigned short | 2 | 2 | 0 到 65,535 |
long | 4 | 8 | -2,147,483,648 到 2,147,483,647 |
unsigned long | 4 | 8 | 0 到 4,294,967,295 |
留意:
各种类型的存储巨细与体系位数有关,但目前通用的以 64 为体系为主。
浮点类型
类型 | 比特(位)数 | 有用数字 | 取值规模 |
---|---|---|---|
float | 4 | 6~7 | 1.2E-38 到 3.4E+38 |
double | 8 | 15~16 | 2.3E-308 到 1.7E+308 |
long double | 16 | 18~19 | 3.4E-4932 到 1.1E+4932 |
他们的字节,精度,取值规模都能够经过代码打印完成,如下:
//
// main.c
// 02-数据类型
//
// Created by VanZhang on 2022/5/16.
//
#include <stdio.h>
#include <float.h>
int main(int argc, const char * argv[]) {
/**
* 整数类型
*/
printf("\n\n 整数类型 \n");
//char 1 字节
printf("char 存储巨细: %lubyte \n", sizeof(char));
printf("unsinged char 存储巨细: %lu byte\n", sizeof(unsigned char));
//short 2 字节
printf("short 存储巨细: %lu byte\n", sizeof(short));
printf("unsinged short 存储巨细: %lu byte\n", sizeof(unsigned short));
//int 4 字节
printf("int 存储巨细: %lu byte\n", sizeof(int));
printf("unsinged int 存储巨细: %lu byte\n", sizeof(unsigned int));
//long 4/8 字节
printf("long 存储巨细: %lu byte\n", sizeof(long));
printf("unsinged long 存储巨细: %lu byte\n", sizeof(unsigned long));
/**
* 浮点类型
*/
printf("\n\n 浮点类型 \n");
//float 4 字节 ,精度 6 位小数
printf("float 存储最大字节数:%lu byte\n", sizeof(float));
printf("float 最小值:%e \n", FLT_MIN);
printf("float 最大值:%e \n", FLT_MAX);
printf("float 精度值:%d \n", FLT_DIG);
//double 8 字节
printf("double 存储最大字节数:%lu byte\n", sizeof(double));
printf("double 最小值:%e \n", DBL_MIN);
printf("double 最大值:%e \n", DBL_MAX);
printf("double 精度值:%d \n", DBL_DIG);
//long double 16 字节
printf("long double 存储最大字节数:%lu byte \n", sizeof(long double));
printf("long double 最小值:%Lg \n", LDBL_MIN);
printf("long double 最大值:%Lg \n", LDBL_MAX);
printf("long double 精度值:%d \n", LDBL_DIG);
return 0;
}
能够经过 sizeof
关键字来获取数据类型占用内存的巨细
。上面代码能够看到了打印中呈现了很多不识的 格局操控符
,我总结了一个表,能够参考下:
格局操控符 | 阐明 |
---|---|
%c | 读取一个单一的字符 |
%hd、%d、%ld | 读取一个十进制整数,并别离赋值给 short、int、long 类型 |
%ho、%o、%lo | 读取一个八进制整数(可带前缀也可不带),并别离赋值给 short、int、long 类型 |
%hx、%x、%lx | 读取一个十六进制整数(可带前缀也可不带),并别离赋值给 short、int、long 类型 |
%hu、%u、%lu | 读取一个无符号整数,并别离赋值给 unsigned short、unsigned int、unsigned long 类型 |
%f、%lf | 读取一个十进制方式的小数,并别离赋值给 float、double 类型 |
%e、%le | 读取一个指数方式的小数,并别离赋值给 float、double 类型 |
%g、%lg | 既能够读取一个十进制方式的小数,也能够读取一个指数方式的小数,并别离赋值给 float、double 类型 |
%s | 读取一个字符串(以空白符为完毕) |
3. 变量
变量其实只不过是程序可操作的存储区的称号。
C 中每个变量都有特定的类型,类型决议了变量存储的巨细
和布局
,该规模内的值都能够存储在内存中,运算符可应用于变量上。
变量的称号能够由字母
、数字
和 下划线字符
组成。它有必要以字母或下划线最初。大写字母和小写字母是不同的,由于 C 对巨细写灵敏的。
C 中的变量界说
变量界说就是告知编译器在何处创立变量的存储,以及怎么创立变量的存储。变量界说指定一个数据类型,并包括了该类型的一个或多个变量的列表,如下所示:
变量类型 变量称号;
如:
int a;
char c;
...
在这儿,变量类型 有必要是一个有用的 C 数据类型,可所以 char、w_char、int、float、double 或任何用户自界说的目标,变量称号 能够由一个或多个标识符称号组成,多个标识符之间用逗号分隔。下面列出几个有用的声明:
int a,b,c;
char c1,c2,c3;
float f,f1,f2;
double d1,d2,d3;
C言语 中变量的 声明
变量声明向编译器保证变量以指定的类型
和称号
存在,这样编译器在不需求知道变量完整细节的状况下也能持续进一步的编译。
变量声明只在编译时有它的含义,在程序衔接时编译器需求实际的变量声明。
变量的声明有两种状况:
- 1、一种是
需求树立存储空间
的。例如:int a 在声明的时候就已经树立了存储空间。 - 2、另一种是
不需求树立存储空间
的,经过运用 extern 关键字声明变量名而不界说它。 例如:extern int a 其间变量 a 能够在别的文件中界说的。 - 除非有 extern 关键字,不然都是变量的界说。
extern int i;//声明,不是界说
int a;//声明,也是界说
比如
#include <stdio.h>
//函数外界说变量
//假如需求在一个源文件中引证另外一个源文件中界说的变量,咱们只需在引证的文件中将变量加上 extern 关键字的声明即可
int x;
int y;
int sum() {
//函数内声明变量 X , Y 为外部变量
x = 10;
y = 15;
return x + y;
}
//入口函数
void main() {
//打印变量相加
int result;
result = sum();
printf("x + y = %d",result);
}
输出:
4. 常量
常量是固定值,在程序履行期间不会改动。这些固定的值,又叫做字面量。
常量可所以任何的底子数据类型,比方整数常量、浮点常量、字符常量,或字符串字面值,也有枚举常量。
整数常量
整数常量可所以十进制
、八进制
或十六进制
的常量。前缀指定基数:0x 或 0X 表明十六进制,0 表明八进制,不带前缀则默许表明十进制。
整数常量也能够带一个后缀,后缀是 U 和 L 的组合,U 表明无符号整数(unsigned),L 表明长整数(long)。后缀可所以大写,也可所以小写,U 和 L 的次序恣意。
212 /* 合法的 */
215u /* 合法的 */
0xFeeL /* 合法的 */
078 /* 不合法的:8 不是八进制的数字 */
032UU /* 不合法的:不能重复后缀 */
浮点常量
浮点常量由整数部分、小数点、小数部分和指数部分组成。您能够运用小数方式或许指数方式来表明浮点常量。
当运用小数方式表明时,有必要包括整数部分、小数部分,或同时包括两者。当运用指数方式表明时, 有必要包括小数点、指数,或同时包括两者。带符号的指数是用 e 或 E 引进
的。
3.14159 /* 合法的 */
314159E-5L /* 合法的 */
510E /* 不合法的:不完整的指数 */
210f /* 不合法的:没有小数或指数 */
.e55 /* 不合法的:缺少整数或分数 */
界说常量
在 C 中,有两种简略的界说常量的方式:
- 运用 #define 预处理器。
- 运用 const 关键字。
下面是运用 #define 预处理器界说常量的方式:
#define identifier value
比如:
#define name 10L
#define age 27U
void main() {
int person;
person = name + age;
printf("values :%d",person);
}
const 关键字
您能够运用 const 前缀声明指定类型的常量,如下所示:
const type variable = value;
比如:
void main() {
const int LEGTH = 10;
const int WIDTH = 5;
const char NEWLINE = '\n';
int area;
area = LEGTH * WIDTH;
printf("value of area: %d", area);
}
三、C 言语中心语法|存储类
1. 存储类
存储类界说 C 程序中变量/函数的规模(可见性)和生命周期。这些阐明符放置在它们所润饰的类型之前。下面列出 C 程序中可用的存储类:
- auto
- register
- static
- extern
2. auto 存储类
auto 存储类时一切局部变量默许的存储类
。
int month;
auto int month;
上面界说了两个带有相同存储类,auto 只能用在函数内,即 auto 只能润饰局部变量
。
3. register 存储类
register 存储类用于界说存储在寄存器
中而不是 RAM 中的局部变量。这意味着变量的最大尺度等于寄存器的巨细(一般是一个词),且不能对它应用一元的 ‘&’ 运算符(由于它没有内存方位)。
register int miles;
寄存器只用于需求快速拜访的变量,比方计数器。还应留意的是,界说 register
并不意味着变量将被存储在寄存器中,它意味着变量或许存储在寄存器中,这取决于硬件和完成的约束。
4. static 存储类
static 存储类指示编译器在程序的生命周期内坚持局部变量的存在
,而不需求在每次它进入和脱离作用域时进行创立和毁掉。因而,运用 static 润饰局部变量能够在函数调用之间坚持局部变量的值。static 润饰符也能够应用于大局变量。当 static 润饰大局变量时,会使变量的作用域约束在声明它的文件内。
大局声明的一个 static 变量或办法能够被任何函数或办法调用,只需这些办法呈现在跟 static 变量或办法同一个文件中。
比如:
//函数声明
void func1(void);
static int count = 10; //大局变量 - static 默许的
void main() {
while (count--) {
func1();
}
}
void func1(void) {
// 'thingy' 是 'func1' 的局部变量 - 只初始化一次
// * 每次调用函数 'func1' 'thingy' 值不会被重置。
static int thingy = 5;
thingy++;
printf("thingy 为 %d, count 为 %d \n", thingy, count);
}
输出:
thingy 为 6, count 为 9
thingy 为 7, count 为 8
thingy 为 8, count 为 7
thingy 为 9, count 为 6
thingy 为 10, count 为 5
thingy 为 11, count 为 4
thingy 为 12, count 为 3
thingy 为 13, count 为 2
thingy 为 14, count 为 1
thingy 为 15, count 为 0
实例中 count 作为大局变量能够在函数内运用,thingy 在局部运用 static 润饰后,不会在每次调用时重置。
5. extern 存储类
extern 存储类用于供给一个大局变量的引证,大局变量对一切的程序文件都是可见的。当您运用 extern 时,对于无法初始化的变量,会把变量名指向一个之前界说过的存储方位。
当您有多个文件且界说了一个能够在其他文件中运用的大局变量或函数时,能够在其他文件中运用 extern
来得到已界说的变量或函数的引证。能够这么了解,extern
是用来在另一个文件中声明一个大局变量或函数。
extern
润饰符一般用于当有两个或多个文件共享相同的大局变量或函数
的时候,如下所示:
第一个文件 ndk_day1.c
/**
*存储类的几种方式:
* 默许:auto
* 静态存储:static
* 对外露出:extern
* (或许)存储在寄存器:register
*/
static float value = 37;
//函数声明
void func1(void);
static int count = 10; //大局变量 - static 默许的
#include "constant.h"
void test5(void) {
auto int a = 10;
register double b = 20;
printf("a:%p\n",a);
printf("b:%p\n",b);
printf("extern_int_value:%d\n",extern_int_value);
printf("value:%p\n",value);
while (count--) {
func1();
}
int res = addFunc(30, 7);
printf("res:%d\n",res);
}
void func1(void) {
// 'thingy' 是 'func1' 的局部变量 - 只初始化一次
// * 每次调用函数 'func1' 'thingy' 值不会被重置。
static int thingy = 5;
thingy++;
printf("thingy 为 %d, count 为 %d \n", thingy, count);
}
声明 constant.h 头文件
//
// constant.h
// 02-数据类型
//
// Created by VanZhang on 2022/5/16.
//
#ifndef constant_h
#define constant_h
#include <stdio.h>
extern int extern_int_value;
extern int addFunc(int a,int b);
#endif /* constant_h */
头文件的完成 constant.c
//
// constant.c
// 02-数据类型
//
// Created by VanZhang on 2022/5/16.
//
#include "constant.h"
int extern_int_value = 10;
int addFunc(int a,int b){
return a + b;
}
输出:
四、C 言语中心语法|运算与基础句子
核算机的底子才能就是核算,所以一门言语的核算才能十分重要。C言语之所以无所不能,很大原因在于它有强大的核算才能。
C言语一共有34种运算符,其间的大多数运算符跟在Java中的用法是相同的。下面做一个简略介绍。
1. 运算符
运算符是一种告知编译器履行特定的数学或逻辑操作的符号。C 言语内置了丰富的运算符,并供给了以下类型的运算符:
- 算术运算符
- 联系运算符
- 逻辑运算符
- 位运算符
- 赋值运算符
- 杂项运算符
1.1 算术运算符
下表显现了 C 言语支撑的一切算术运算符。假定变量 A 的值为 10,变量 B 的值为 20,则:
运算符 | 描绘 | 实例 |
---|---|---|
+ | 把两个操作数相加 | A + B 将得到 30 |
– | 从第一个操作数中减去第二个操作数 | A – B 将得到 -10 |
* | 把两个操作数相乘 | A * B 将得到 200 |
/ | 分子除以分母 | B / A 将得到 2 |
% | 取模运算符,整除后的余数(要求%两边均为整型 ) |
B % A 将得到 0 |
++ | 自增运算符,整数值增加 1 | A++ 将得到 11 |
— | 自减运算符,整数值削减 1 | A– 将得到 9 |
比如:
void main(){
int a = 21;
int b = 10;
int c;
c = a + b;
printf("a + b = %d \n", c);
c = a - b;
printf("a - b = %d \n", c);
c = a * b;
printf("a * b = %d \n", c);
c = a / b;
printf("a / b = %d \n", c);
c = a % b;
printf("a % b = %d \n", c);
c = ++a;
printf("++a = %d , %d \n", c, a);
c = b++;
printf("b++ = %d , %d \n", c, b);
c = b--;
printf("b-- = %d \n", c);
}
输出:
a + b = 31
a - b = 11
a * b = 210
a / b = 2
a b = 1
++a = 22 , 22
b++ = 10 , 11
b-- = 11
1.2 联系运算符
下表显现了 C 言语支撑的一切联系运算符。假定变量 A 的值为 10,变量 B 的值为 20,则:
运算符 | 描绘 | 实例 |
---|---|---|
== | 检查两个操作数的值是否持平,假如持平则条件为真。 | (A == B) 为假。 |
!= | 检查两个操作数的值是否持平,假如不持平则条件为真。 | (A != B) 为真。 |
检查左操作数的值是否大于右操作数的值,假如是则条件为真。 | (A > B) 为假。 | |
< | 检查左操作数的值是否小于右操作数的值,假如是则条件为真。 | (A < B) 为真。 |
>= | 检查左操作数的值是否大于或等于右操作数的值,假如是则条件为真。 | (A >= B) 为假。 |
<= | 检查左操作数的值是否小于或等于右操作数的值,假如是则条件为真。 | (A <= B) 为真。 |
- 联系运算的成果建立就为”真”(比方5>=4),不建立则为”假”(比方5<4)
- 在Java中,联系运算的成果为”真”就回来true,”假”则回来false,用boolean类型的变量来接收
boolean b1 = 5 > 4; // true boolean b2 = 5 < 4; // false
C言语中没有boolean类型
- 在C言语中,联系运算的成果为”真”就回来1,”假”就回来0
int a1 = 5 > 4; // 1 int a2 = 5 < 4; // 0
- 还需留意的是,在C言语中,任何非0值都为”真”,只有0值才为”假”
所以下面的做法是对的:
int a = 10;
if (a) {
printf("条件建立");
} else {
printf("条件不建立");
}
由于a不为0,所认为”真”,输出成果是:
若是在Java中,编译器直接报错了,由于if的括号()中只能放boolean类型的值。
以此类推,下面的写法也是对的:
int a = 10;
if (a = 0) {
printf("条件建立");
} else {
printf("条件不建立");
}
上述代码是完全合理的,编译器不会报错,仅仅个正告罢了。由于a为0,所认为”假”,输出成果是:
这样看来,C言语似乎比Java方便很多,其实有很大的圈套在这儿:
假定你本来是想判别a是否为0,那么本应该写if (a == 0),若你误写成了if (a = 0),那将是一件十分可怕的事情,由于编译器又不报错,这样的BUG就难找了。因而,像a==0这样的表达式,最好写成0==a,若你误写成0=a,编译器会直接报错的。
// 不引荐
if (a == 0) {
}
// 引荐
if (0 == a) {
}
- 在C言语中,能够不保存联系运算的成果
因而,下面的写法是合法的:1 int a = 10; 2 a > 10; 3 a == 0;
假如是在Java中,第2、3行编译器会直接报错,但在C编译器看来是合法的,仅仅个正告。
所以,这儿又是一个圈套,假定你的原意是想给a赋值为0,那么本应该写a = 0; ,若你误写成a == 0; ,那将又是一个十分难找的BUG,由于编译器底子不会报错。在1993年的时候,这个BUG差点让一桩价值2000万美元的硬件产品生意告吹,由于假如这个BUG不解决,这个产品就没办法正常运用。
1.3 逻辑运算符
下表显现了 C 言语支撑的一切联系逻辑运算符。假定变量 A 的值为 1,变量 B 的值为 0,则:
运算符 | 描绘 | 实例 |
---|---|---|
&& | 称为逻辑与运算符。假如两个操作数都非零,则条件为真。 | (A && B) 为假。 |
|| | 称为逻辑或运算符。假如两个操作数中有恣意一个非零,则条件为真。 | (A || B) 为真。 |
! | 称为逻辑非运算符。用来反转操作数的逻辑状况。假如条件为真则逻辑非运算符将使其为假。 | !(A && B) 为真。 |
//逻辑运算符
void test1(void){
int a1 = 5;
int b1 = 5;
int c1;
//假如两个操作数都非零,则条件为真。
if (a1 && b1) {
printf("a1 && b1 %d \n", true);
} else {
printf("a1 && b1 %d \n", false);
}
//假如两个操作数中有恣意一个非零,则条件为真。
if (a1 || b1) {
printf("a1 || b1 %d \n", true);
} else {
printf("a1 || b1 %d \n", false);
}
//改动 a1 b1 的值
a1 = 0;
b1 = 10;
//假如两个操作数都非零,则条件为真。
if (a1 && b1) {
printf("a1 && b1 %d \n", true);
} else {
printf("a1 && b1 %d \n", false);
}
if (!(a1 && b1)) {
printf("!(a1 && b1) %d \n", true);
} else {
printf("a1 || b1 %d \n", false);
}
}
int main(int argc, const char * argv[]) {
// test();
test1();
return 0;
}
输出:
1.4 位运算符
p | q | p&q | p|q | p^q |
---|---|---|---|---|
0 | 0 | 0 | 0 | 0 |
0 | 1 | 0 | 1 | 1 |
1 | 1 | 1 | 1 | 0 |
1 | 0 | 0 | 1 | 1 |
void main(){
//位运算符 & | ^ ~
int wA = 60; //0011 1100
int wB = 13; //0000 1101
int wC = 10;
//都为真,才是真 0000 1100
printf("wA & wB=?%d\n", wA & wB);
//其间一个为真,就为真 0011 1101
printf("wA | wB=?%d\n", wA | wB);
//一个为真则为真,2个为真这为假 00110001
printf("wA ^ wB=?%d\n", wA ^ wB);
printf("~wB=?%d\n", ~wB);
//二进制左移运算符 左 * 4 = 40
printf("wC<<2=?%d\n", wC << 2);
//二进制右移运算符 右 / 4
printf("wC>>2=?%d\n", wC >> 2);
}
输出:
wA & wB=?12
wA | wB=?61
wA ^ wB=?49
~wB=?-14
wC<<2=?40
wC>>2=?2
下表显现了 C 言语支撑的位运算符。假定变量 A 的值为 60,变量 B 的值为 13,则:
运算符 | 描绘 | 实例 | ||||
---|---|---|---|---|---|---|
& | 按位与操作,按二进制位进行”与”运算。运算规则:0&0=0; 0&1=0; 1&0=0; 1&1=1;
|
(A & B) 将得到 12,即为 0000 1100 | ||||
按位或运算符,按二进制位进行”或”运算。运算规则:`0 | 0=0; 0 | 1=1; 1 | 0=1; 1 | 1=1;` | (A | B) 将得到 61,即为 0011 1101 |
异或运算符,按二进制位进行”异或”运算。运算规则:0^0=0; 0^1=1; 1^0=1; 1^1=0;
|
(A ^ B) 将得到 49,即为 0011 0001 | |||||
~ | 取反运算符,按二进制位进行”取反”运算。运算规则:~1=0; ~0=1;
|
(~A ) 将得到 -61,即为 1100 0011,一个有符号二进制数的补码方式。 | ||||
<< | 二进制左移运算符。将一个运算目标的各二进制位悉数左移若干位(左面的二进制位丢弃,右边补0)。 | A << 2 将得到 240,即为 1111 0000 | ||||
>> | 二进制右移运算符。将一个数的各二进制位悉数右移若干位,正数左补0,负数左补1,右边丢弃。 | A >> 2 将得到 15,即为 0000 1111 |
1.5 赋值运算符
下表列出了 C 言语支撑的赋值运算符:
运算符 | 描绘 | 实例 | ||
---|---|---|---|---|
= | 简略的赋值运算符,把右边操作数的值赋给左面操作数 | C = A + B 将把 A + B 的值赋给 C | ||
+= | 加且赋值运算符,把右边操作数加上左面操作数的成果赋值给左面操作数 | C += A 相当于 C = C + A | ||
-= | 减且赋值运算符,把左面操作数减去右边操作数的成果赋值给左面操作数 | C -= A 相当于 C = C – A | ||
*= | 乘且赋值运算符,把右边操作数乘以左面操作数的成果赋值给左面操作数 | C *= A 相当于 C = C * A | ||
/= | 除且赋值运算符,把左面操作数除以右边操作数的成果赋值给左面操作数 | C /= A 相当于 C = C / A | ||
%= | 求模且赋值运算符,求两个操作数的模赋值给左面操作数 | C %= A 相当于 C = C % A | ||
<<= | 左移且赋值运算符 | C <<= 2 等同于 C = C << 2 | ||
>>= | 右移且赋值运算符 | C >>= 2 等同于 C = C >> 2 | ||
&= | 按位与且赋值运算符 | C &= 2 等同于 C = C & 2 | ||
^= | 按位异或且赋值运算符 | C ^= 2 等同于 C = C ^ 2 | ||
|= | 按位或且赋值运算符 | C | = 2 等同于 C = C | 2 |
比如:
//赋值运算符
void test3(void){
int wAA = 21;//0001 0101
int wBB;
wBB = wAA;
printf("= %d\n", wBB);
wBB += wAA;
printf("+= %d\n", wBB);
wBB -= wAA;
printf("-= %d\n", wBB);
wBB *= wAA;
printf("*= %d\n", wBB);
wBB /= wAA;
printf("/= %d\n", wBB);
wBB %= wAA;
printf("%= %d\n", wBB);
//wBB == wAA == 21
//wBB = wBB<<wAA
// = 21<<21
// 0001 0101
// wBB = 0
wBB <<= wAA;
printf("<<= %d\n", wBB);
// wBB = 0
wBB >>= wAA;
printf(">>= %d\n", wBB);
// wBB = 0
wBB &= wAA;
printf("&= %d\n", wBB);
wBB ^= wAA;
printf("^= %d\n", wBB);
wBB |= wAA;
printf("|= %d\n", wBB);
}
int main(int argc, const char * argv[]) {
// test();
// test1();
// test2();
test3();
return 0;
}
输出:
= 21
+= 42
-= 21
*= 441
/= 21
= 0
<<= 0
>>= 0
&= 0
^= 21
|= 21
1.6 杂项运算符: sizeof
、&
、*
、?:
下表列出了 C 言语支撑的其他一些重要的运算符,包括 sizeof 和 ? : 。
运算符 | 描绘 | 实例 |
---|---|---|
sizeof() | 用来核算一个变量或许一个常量、一种数据类型所占的内存字节数。 | sizeof(a) 将回来 4,其间 a 是整数。 |
& | 回来变量的地址。 | &a; 将给出变量的实际地址。 |
* | 指向一个变量。 | *a; 将指向一个变量。 |
? : | 条件表达式 | 假如条件为真 ? 则值为 X : 不然值为 Y |
sizeof一共有3种方式
- sizeof(变量\常量)
sizeof(10); char c = 'a'; sizeof(c);
- sizeof(数据类型)
sizeof(float);
留意:不能够写成sizeof float;
在64bit环境下的比如:
//杂项运算符
void test4(void){
int zxA = 4;
short zxB;
double zxC;
int *ptr;//指针
//sizeOf 运算符实例 ,lu 32位无符号整数
printf("zxA sizeOf = %lu \n", sizeof(zxA));
printf("zxB sizeOf = %lu \n", sizeof(zxB));
printf("zxC sizeOf = %lu \n", sizeof(zxC));
//& 和 * 运算符实例
ptr = &zxA; //将 zxA 的地址值仿制给 ptr 指针
printf("zxA 的值为:%d \n", zxA);
printf("*ptr 的值为:%d \n", *ptr);
//三元运算符/三目运算符
zxA = 10;
zxB = (zxA == 1) ? 20 : 30;
printf("zxb 的值为:%d \n", zxB);
zxB = (zxA == 10) ? 20 : 30;
printf("zxb 的值为:%d \n", zxB);
}
int main(int argc, const char * argv[]) {
// test();
// test1();
// test2();
// test3();
test4();
return 0;
}
输出:
zxA sizeOf = 4
zxB sizeOf = 2
zxC sizeOf = 8
zxA 的值为:4
*ptr 的值为:4
zxb 的值为:30
zxb 的值为:20
2. 基础句子
2.1 判别句子
C 言语把任何非零和非空的值假定为 true,把零或 null 假定为 false。
C 言语供给了以下类型的判别句子。点击链接检查每个句子的细节。
句子 | 描绘 |
---|---|
if 句子 | 一个 if 句子 由一个布尔表达式后跟一个或多个句子组成。 |
if…else 句子 | 一个 if 句子 后可跟一个可选的 else 句子,else 句子在布尔表达式为假时履行。 |
嵌套 if 句子 | 您能够在一个 if 或 else if 句子内运用另一个 if 或 else if 句子。 |
switch 句子 | 一个 switch 句子答应测验一个变量等于多个值时的状况。 |
嵌套 switch 句子 | 您能够在一个 switch 句子内运用另一个 switch 句子。 |
?:运算符
跟 Java 相同
void main(){
int pdNumber;
printf("输入一个数字:");
scanf("%d", &pdNumber);
(pdNumber % 2 == 0) ? printf("偶数") : printf("基数");
}
2.2 循环句子
C 言语供给了以下几种循环类型。点击链接检查每个类型的细节。
循环类型 | 描绘 |
---|---|
while 循环 | 当给定条件为真时,重复句子或句子组。它会在履行循环主体之前测验条件。 |
for 循环 | 屡次履行一个句子序列,简化管理循环变量的代码。 |
do…while 循环 | 除了它是在循环主体结尾测验条件外,其他与 while 句子相似。 |
嵌套循环 | 您能够在 while、for 或 do..while 循环内运用一个或多个循环。 |
2.3 循环操控句子
循环操控句子改动你代码的履行次序。经过它你能够完成代码的跳转。
C 供给了下列的循环操控句子。点击链接检查每个句子的细节。
操控句子 | 描绘 |
---|---|
break 句子 | 终止循环或 switch 句子,程序流将持续履行紧接着循环或 switch 的下一条句子。 |
continue 句子 | 告知一个循环体立刻停止本次循环迭代,重新开端下次循环迭代。 |
goto 句子 | 将操控转移到被符号的句子。可是不建议在程序中运用 goto 句子。 |
运用办法能够参考 Java ,下面给出循环的比如:
void main(){
//约束
for (int i = 0; i < 6; i++) {
printf("约束循环,%d \n",i);
}
//无限循环
for (;;) {
printf("该循环会一直履行下去!\n");
}
}
专题系列文章
温习C言语中心常识
- 01-温习C言语中心常识|综述
- 02-温习C言语中心常识|底子语法、数据类型、变量、常量、存储类、底子句子(判别句子、循环句子、go to句子)和运算
- 03-温习C言语中心常识|函数、作用域规则、数组、枚举、字符与字符串、指针
- 04-温习C言语中心常识|结构体、共用体、位域、输入&输出、文件读写
- 05-温习C言语中心常识|预处理、头文件、强制类型转换、错误处理、递归、内存管理