一、数组
数组是一组相同类型元素的集合。
int arr1[10];
char arr2[5];
float arr3[2];
double arr4[5];
注:数组创建,[ ]中要给一个常量才可以,不能使用变量,如:
int n = 10;
int arr[n];
这种创建方法是错误的,不建议这么来创建数组。
数组的使用如下:
#include <stdio.h>
int main()
{
int arr[10] = {0};//数组的不完全初始化
//计算数组的元素个数
int sz = sizeof(arr)/sizeof(arr[0]);
//对数组内容赋值,数组是使用下标来访问的,下标从0开始。所以:
int i = 0;//做下标
for(i=0; i<10; i++)//这里写10,好不好?
{
arr[i] = i;
}
//输出数组的内容
for(i=0; i<10; ++i)
{
printf("%d ", arr[i]);
}
return 0;
}
1.数组是通过下标来访问的,下标从0开始;
2.数组的大小可以通过计算得到。
再来看下面的例子:
void bubble_sort(int arr[])
{
int sz = sizeof(arr)/sizeof(arr[0]);//这样对吗?
...
}
int main()
{
int arr[] = {3,2,4,5,6,1,7,9,8};
bubble_sort(arr);
...
return 0;
}
通过调试发现,bubble_sort函数内部的sz是1,这是为什么呢?
这里我们需要补充:
1.sizeof(数组名),计算整个数组的大小,sizeof内部单独放一个数组名,数组名表示整个数组。
2.&数组名,取出的是数组的地址。&数组名,数组名表示整个数组。
除此之外,所有的数组名都表示数组首元素的地址。
因此,数组在传参时,实际上只是把数组的首元素的地址传递过去了。
所以,正确的设计方式是:
void bubble_sort(int arr[],int sz)
{
...
}
int main()
{
int arr[] = {3,2,4,5,6,1,7,9,8};
int sz = sizeof(arr)/sizeof(arr[0]);
bubble_sort(arr,sz);
...
return 0;
}
二、操作符
操作符分为:算术操作符、移位操作符、位操作符、赋值操作符、单目操作符、关系操作符、逻辑操作符、条件操作符、逗号表达式、下标引用、函数调用和结构体成员。
1.算数操作符
+ - * / %
1)除了%操作符之外,其它的操作符可以作用于整数和浮点数。
2)对于/操作符,如果两个操作数作为整数,执行整数除法,而只要有浮点数执行的就是浮点数除法。
例如:
3)%操作符的两个操作数必须为整数,返回的是整除之后的余数。
2.移位操作符
<< 左移操作符
>> 右移操作符
注:移位操作符的操作数只能是整数。
2.1左移操作符
移位规则:左边抛弃,右边补0
如图所示:
2.2右移操作符
移位规则:分为两种
1)逻辑移位:左边用0填充,右边丢弃
2)算术移位:左边用原该值的符号位填充,右边丢弃
这两种移位规则都与左移类似,就不再画图介绍。
注意:对于移位操作符,不要移动负数位,这个是标准未定义的。
例如:
int num = 10;
num >> -1;//error
3.位操作符
& 按位与
| 按位或
^ 按位异或
注:它们的操作数必须是整数
这里有两道练习题:
1)不能创建临时变量(第三个变量),实现两个数的交换。
2)求一个整数存储在内存中的二进制中1的个数。
方法1:
方法2:
4.赋值操作符
赋值操作符简单来说就是等于号 “=”, 当然还有复合赋值符,如下:
+= -= *= /= %= >>= <<= &= |= ^=
举个例子:
int x = 10;
x = x + 10;
//可以写成下式
x += 10;
//其它运算符也是一样的道理,这样写更简洁。
5.单目操作符
! 逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
-- 前置、后置--
++ 前置、后置++
* 间接访问操作符(解引用操作符)
(类型) 强制类型转换
注:前置++/--:先使用再++/--
后置++/--:先++/--再使用
6.关系操作符
>
>=
<
<=
!= 用于测试"不相等"
== 用于测试"相等"
注:"=="与"="不要搞混了。
7.逻辑操作符
&& 逻辑与
| | 逻辑或
注意区分逻辑与和按位与、逻辑或和按位或。
1&2 ——> 0 1 | 2 ——> 3
1&&2 ——> 1 1 | | 2 ——> 1
练习:
第一题,当某个表达式的结果为0(假)时,“&&”后面的表达式就不再计算,因为无论后面的结果如何,整个表达式的最终结果都为0。而a++为后置++,先使用再++,所以最终a=1,b=2,c=3,d=4。
第二题,当某个表达式的结果为1(真)时,“| |”后面的表达式同样不再计算。此时a=0,++b为前置++,先++再使用,因此b=3,为真,不再往后算,而a++又为后置++,所以最终结果为a=1,b=3,c=3,d=4。
9.条件操作符
exp1 ? exp2 : exp3
意思是:当表达式1的结果为真时,整个表达式的结果为表达式2的结果;当表达式1的结果为假时,整个表达式的结果为表达式3的结果。
10.逗号表达式
exp1, exp2, exp3, ..., expn
逗号表达式,从左到右依次执行,整个表达式的结果为最后一个表达式的结果。
11.下标引用、函数调用和结构体成员
1) [ ] 下标引用操作符
int arr[10];//创建数组
arr[9];//使用下标引用操作符
//[ ]的两个操作数是arr和9
2) ( ) 函数调用操作符
接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数。
3)访问结构体成员
. 结构体.成员名
-> 结构体指针->成员名