3.29笔记

数组: 数组中的元素为同一类型。
在使用数组的时候,必须对数组进行定义,再初始化,初始化时[]内可以不写,若写必须为常量而不能为变量。求一个数组的长度时可用:sizeof(arr) / sizeof(arr[0]);来求,一般后面的为arr[0],这一样可以避免数组中只有一个元素时求解出错。访问数组的每一个元素称为遍历。
操作符:

  1. 算数操作符:+ - * / %(求余运算符)
  2. 移位操作符:>>和<<,向右移位和向左移位(按二进制移位)。如:
	int x = 10;              //二进制为1010
	printf("%d\n", x >> 1); //x向右移1个单位,二进制为0101,此时结果为5
	printf("%d\n", x << 1); //x向左移一个单位,二进制为10100,此时结果为20
	printf("%d\n", x);  //对x移位,但未改变其本身的值

结果为:
在这里插入图片描述
将整数进行右移1位,相当于对整数除2取整。

  1. 位操作符:
	&    按位与运算,1&1=1 1&0=0 0&1=0 0&0=0
	|    按位或运算,1|1=1 1|0=1 0|1=1 0|0=0
	^    按位异或运算,相同为0,相异为1
  1. 赋值操作符:= += -= *= /= &= ^= |= >>= <<=
    定义变量:
    ①开辟地址空间,大小由类型决定。
    ②向空间放置数据内容。
    初始化和赋值的区别:
    初始化:定义一个变量的同时,给定一个值。
    赋值:给一个已经存在的变量再给其一个值。
    5.单目操作符:
	!             逻辑反操作
	-             负值
	+             正值
	&             取地址
	sizeof        操作数的类型长度
	~             对一个数的二进制按位取反
	--            前置--,后置--
	++            前置++,后置++
	*             间接访问操作符(解引用操作符)
	(类型)        强制类型转换

++i和i++的区别: i++是先执行程序再自增。而++i是自增完再执行程序。 如:

	int i = 10;
	int x = 0;
	x = i++;
	printf("%d %d\n", i, x);

结果为:
在这里插入图片描述

	int i = 10;
	int x = 0;
	x = ++i;
	printf("%d %d\n", i, x);

结果为:
在这里插入图片描述

6.关系操作符:

>
>=
<
<=
!=
==

7.逻辑操作符:&& 和 ||
逻辑与与逻辑或,是判定两个表达式真假时的结果。
在逻辑与中,必须两个表达式同时为真才为真,当第一个表达式为假时则不执行后面的表达式,因为它第一个为假,则结果必然为假,就不会继续执行下去。
在逻辑与中,一个表达式为真则为真,但当第一个表达式为真时,就不会执行后面的表达式,因为它第一个为真,则结果必然为真,就不会继续执行下去。如对逻辑与测试:

	int x = 1;
	x && printf("%d\n", x);

结果为:

	int x = 0;
	x && printf("%d\n", x);

结果为:
在这里插入图片描述
对逻辑或测试:

	int x = 0;
	x || printf("%d\n", x);

结果为:
在这里插入图片描述

int x = 1;
x || printf("%d\n", x);

结果为:
在这里插入图片描述

  1. 条件操作符(三目运算符):exp1 ?exp2:exp3
    如求一个最大值:
int x = 10;
int y = 20;
printf("%d\n", x > y ? x : y);

条件成立,则输出前者,条件不成立,则输出后者。
结果为:
在这里插入图片描述
关键字: c语言中定义的有32个关键字:

auto                       声明自动变量
break                      跳出当前循环
case                       开关语句分支
char                       声明字符型变量
const                      声明只读常变量
continue                   结束当前循环并开启下一轮循环
default                    开关语句中的默认分支
do                         循环语句的循环体
double                     声明双精度变量
else                       条件分支语句的分支
enum                       声明枚举常量
extern                     声明变量是从其他文件中引用来的
float                      声明浮点型变量
for                        循环语句
goto                       无条件跳转语句
if                         条件语句
int                        声明整形变量
long                       声明长整型变量
register                   声明寄存器变量
return                     子程序返回语句(参数可有可无)
short                      声明短整型变量
signed                     声明有符号类型变量
sizeof                     计算对象所占内存空间大小(字节)
static                     声明静态变量
struct                     声明结构体变量
switch                     开关语句
typedef                    给数据类型取别名
union                      声明联合体(联合数据)变量
unsigned                   声明无符号类型变量
void                       声明函数无返回值或无参数,声明空类型指针
volatile                   说明变量在程序执行中可能会被隐式地改变
while                      循环语句

1.auto:通常情况下,都可以无视,而且平常不是特别常见,(不常见只是我们看不到,不代表不常用的意思)。c语言作为一个面向过程的语言必然会出现许多函数块。在每个函数模块中声明的变量为局部变量,也有另一个名字:自动变量。
如在一个函数中:

int x=10;
auto int x=10;这两者是相等的

auto的出现就代表着当前的变量为一个局部变量,会在内存栈上分配(目前还不明白这一点),从而更高效的利用内存。

2.const: 被const修饰的变量叫做常量。
这句话不准确的。该值在编译的时候不能被使用,因为这时的编译器并不知道它存储的内容。因此和常量还是有小小的区别。
“只读变量”:在内存中开辟一个地方来存放它的值,但是这个值被编译器限定不允许被修改。(编译期间的一个值),没有了存储和都内存的操作,效率变得很高。
const修饰的变量或许就可以叫为只读变量。

const int n=5int arr[n]

这串代码在c语言不能运行,证明了n不是一个“常量”,因为c语言中定义数组长度是必须为“常量”,"只读变量"也是不行的,“常量”不等于“不可变化的变量”。C++中,局部数组是可以使用变量作为其长度的,上述代码串可以运行。

const int *p;       p的指向可以改变,但p指向的目标不能改变
int const *p;       p的指向可以改变,但p指向的目标不能改变
int *const p;       p的指向不可以改变,但是指针p指向的目标可以改变。
const int *const p; p的指向和p指向的目标都不可改变。

3.extern:extern可以置于变量和函数之前,来表示这个函数或者变量有可能是来自别的文件的,在这里进行了引用。有一种特殊情况,在静态全局变量前的代码行若想使用这个变量,也得使用extern来引用。

4.enum枚举类型:enum中的常量可以赋值,但是如果你不给它赋值则会从被赋了初值的那个常量开始依次加1.如果没有给赋任何值,则从第一个值开始自动赋0,往后每个变量都自增1。
5.goto:建议禁用。虽然它可以灵活跳转,但它明显破坏了结构化的设计风格。

6.register:被register修饰的变量叫做寄存器变量,顾名思义,该变量是直接存储在CPU的内部寄存器中的,访问速度和内存中的数据必不可同日而语。具体应用场景比如有一个很大的循环,其中有几个需要频繁操作的变量,这时使用register进行修饰将大大提高效率。
但是即使强如register也是有着自己的限制的,必须是寄存器所接受的类型才能被修饰,即register变量必须是一个单个的值,而且他的长度也要小于等于整形的长度。register变量虽说并不是每时每刻都在寄存器中,最后也是要写入内存的,但是我们也并不能保证某个时刻它就在内存里,所以我们也不能对register变量取地址。

7.signed和unsigned:他们的中文名字是有符号类型和无符号类型。涉及到变量的正负问题。我们都知道一个变量的最高位是符号位,unsigned类型则是将这个最高位也用于表示数据了,所以unsigned类型都是从0开始到某个正数的范围。signed类型和auto类似,也是平常我们看不到但是默认缺省情况都认为一个变量是signed类型的。

8.sizeof:sizeof不是一个函数,它是一个关键字。
sizeof计算变量所占空间大小的时候可以去掉括号,但计算类型大小的时候不能省略,否则会出错。习惯上一般都把括号加着。

9.static:静态关键字static在c语言中主要有两个作用:
作用一:修饰变量
变量分为局部变量和全局变量,修饰后也就对应两种静态变量。他们都存储在内存的静态区。
静态局部变量:
在函数中定义的静态局部变量则只有该函数可以使用,其他函数不得使用。同时由于它和静态全局变量都存在于内存的静态区中而非栈中,所以函数结束之后值也不会销毁,函数下次运行时会继续使用这个值,这是非常重要的特性。修改了生命周期,但作用域未改变。
静态全局变量:
该种变量的作用域仅限于被定义的文件中(从定义之处开始到当前文件结尾),而且在其他文件中即使使用extern关键字也不能使用。在当前文件中,静态全局变量定义之处之前的代码行也同样不能直接使用它,需要使用extern关键字才能使用。所以一般我们都将静态全局变量定义在文件的顶端。但可以间接访问。如一文件中的函数使用了该静态全局变量,另一文件调用此函数就可以达到间接访问的目的。
作用二:修饰函数
在函数前面加上static使得函数成为静态函数。这时该函数的作用域则仅限于本文件中,所以又成为内部函数。这样做的好处是不同的人编写不同的函数时这样不用担心自己的函数与他人编写的重名。
(不全,后面会更新)。
全局变量和函数都支持跨文件访问。

10.typedef:给一个已经存在的数据类型(不是变量)取一个别名。它的主要用处就是,取了别名之后我们可以更清楚的一眼看懂这个数据类型的含义。常见的使用场合就是结构体定义的时候。

11.void:在c语言中如果定义一个函数,不给返回类型。
例如:
add (int a, int b)
{
return a+b;
}
这么做的结果是什么呢?返回值是不是void类型?还是说根本无法通过编译呢?
答案是,编译可以通过,但返回值类型并不是你所想的void而是int。
还有另一个问题:定义一个void类型的变量的话,编译器会给他分配多大的内存呢?(问题,后面更)

12.typedef:类型重命名,除非特殊需求,一般不适用。

本文的关键字部分,参考了这一篇博客:https://blog.csdn.net/czc1997/article/details/80766138

猜你喜欢

转载自blog.csdn.net/w903414/article/details/105178904