接上篇文章
4、常量(右值)
其值不会发生改变的量
分类: 1、字面常量: 无需定义可以直接写出来的量。字面常量的值一望便知,但是他的数据类型往往不能被准确分辨 。
#include <stdio.h>
int main(int argc, char const *argv[])
{
//字面常量:直接的值
100;
3.14;
return 0;
}
2、const修饰的常变量
#include <stdio.h>
int main(int argc, char const *argv[])
{
int num = 4;
printf("%d\n",num);
num = 8;
printf("%d\n",num);
//const-常属性
//const修饰的常变量
const int num1 = 4;
printf("%d\n",num1);
//num1 = 8;
//printf("%d\n",num1);
//error: assignment of read-only variable ‘num1’出错,常变量不能改变
//error,n为变量,数组[]中只能输入常量,这样写不正确
int n = 10;
int arr[n]={0};
//还是error,const int n 终究还是常“变量”
const int n = 10;
int arr[n]={0};
return 0;
}
3、#define定义的标识符常量
宏定义是由源程序中的宏定义命令完成的。宏代换是由预处理程序自动完成的,C语言中分为无参宏和带参宏
1)无参宏
#define 标识符 字符串 #:预处理命令 define:宏定义命令 标识符:所定义的宏名(大写) 字符串:常数、表达式或格式串等(大写)
#include <stdio.h>
#define MAX 10
int main(int argc, char const *argv[])
{
int arr[MAX]={0};//说明是常量
printf("%d\n",MAX);
return 0;
}
说明:
·宏定义是用宏名来表示的一个字符串,在宏展开时又以该字符串来取代宏名,这只是一种简单的代换,字符串中可以含任何字符,可以是常数,也可以是表达式,预处理程序对它不做任何检查。如果错误,只能在编译过程已进行的宏展开的源程序时发现。
·宏定义不是说明或语句,在末行不必加上分号,如加上分号则连分号一起置换
·宏定义必须写在函数之外,其作用域为从宏定义命令起,到源程序结束。如要结束其作用域,可使用“#undef”命令。
2)有参宏
在宏定义中的参数被称为形式参数(简称“形参”),在宏调用中的参数被称为实际参数(简称“实参”)。对于带参数的宏,在调用中,不仅要进行宏展开,而且要用实参去代换形参。
#define 宏名(形参表) 字符串
注意:是直接带入
#include <stdio.h>
#define NUM(X,Y) X+Y
#define NUM1(X,Y) (X+Y)
int main(int argc, char const *argv[])
{
int a = 5;
int s,s1 = 0;
s = NUM(2,3)*a;//2+3*5
s1 = NUM1(2,3)*a;//(2+3)*5
printf("s=%d\n",s);
printf("s1=%d\n",s1);
return 0;
}
宏定义与自定义函数
1)在带参宏定义中,形参不分配内存空间,因此不必进行类型说明;而宏调用中的实参有具体数值,要用它们去代换形参,因此必须进行类型说明。这与函数中的情况是不同的。
在函数中,形参与实参是两个不同的量,各有各自的作用域,在调用时要把实参值赋予形参值。
而在带宏参中,只是符号代换,不存在值传递的问题。
2)宏定义中的形参是标识符,而宏调用的实参可以是表达式。
4、枚举变量
定义方式:
enum enum_type_name
{
ENUM_CONST_1,
ENUM_CONST_2,
…
ENUM_CONST_n
}enum_variable_name
枚举--一一列举
enum变量类型还可以给其中的常量符号赋值,如果不赋值则会从被赋值的那个常量开始依次加1,如果都没有赋值,它们的值从0开始依次递增1.
#include <stdio.h>
enum Sex
{
MALE,
FEMALE,
SECRET
};
//MALE,FEMALE,SECRET-枚举常量
int main(int argc, char const *argv[])
{
enum Sex s = FEMALE;//给s赋予性别FEMALE
printf("%d\n",MALE);
printf("%d\n",FEMALE);
printf("%d\n",SECRET);
return 0;
}
#include <stdio.h>
enum Color
{
RED,
YELLOW = 3,
BLUE
};
int main(int argc, char const *argv[])
{
enum Color color = BLUE;
//BLUE = 6;//error //枚举常量不能改变
printf("%d\n",RED);
printf("%d\n",YELLOW);
printf("%d\n",BLUE);
return 0;
}
枚举与#define宏的区别
(1)#define宏变量是在预编译阶段进行简单替换,枚举常量则是在编译时就确定其值。
(2)一般在编译器中,可以调试枚举常量,但不能调试宏常量
(3)枚举可以一次定义大量相关的常量,而#define宏一次只能定义一个
四、字符串
"hello world\n"
这种由双引号引起来的一串字符称为字符串字面值,或者称为字符串。
注:字符串的结束标志是一个\0的转义字符。在计算字符串长度时\0是结束标志,不算做字符串内容。
#include <stdio.h>
int main()
{
char arr1[] = "abc";//数组
//"abc"='a''b''c''\0'--'\0'字符串结束标志
char arr2[] = {'a','b','c'};
//char arr2[]={'a','b','c',0};//结果为abc,但是正确写法是'\0'
//ASCII编码
//'\0'-0 ASCII码值
//'a'-97
printf("%s\n",arr1);
printf("%s\n",arr2);
for(int i=0;i<10;i++)
{
printf("%c\n",arr2[i]);
}
return 0;
}
#include <stdio.h>
#include <string.h>
int main(int argc, char const *argv[])
{
char arr1[] = "abc";
char arr2[] = {'a','b','c'};
printf("%ld\n",strlen(arr1));
printf("%ld\n",sizeof(arr1));
printf("%ld\n",strlen(arr2));
printf("%ld\n",sizeof(arr2));
return 0;
}
讨论:
为什么会出现输出char arr2[] = {'a','b','c'};,结果为abcabc(后面是乱码)?
与班助老师讨论后认为是因为字符数组没有进行初始化,出现abc重复是因为正好数组重复了(不同的编译器会出现不同的结果),给数组初始化后,即使不进行加'\0'也会只出来abc.
但是又与主任课老师说明问题后,他跟我解释是因为arr2中没有'\0',所以它就顺着打,将arr1打完后发现'\0'后停止。
将arr1的内容改变后,发现正确
五、转义字符
(偷懒,从网上找了一个)
六注释
1、将不需要的给注释掉(一般不建议删除)
2、给一些语句做注释
行注释:// 段注释:/*……*/ #if 0……#endif
快速注释:
Ctrl+K 然后Ctrl+C 注释 或者Ctrl+K+C
Ctrl+K 然后Ctrl+U 取消注释 或者Ctrl+K+U
(但是我的好像不行,郁闷中)
七、选择语句
控制语句主要就是解决那些代码需要执行,哪些代码不需要执行,或者相同的代码需要执行多次的问题
分类:
if...else..
switch ...case...
后续详细介绍
八、循环语句
1while循环
处理有些代码需要多次解决循环的问题,可执行性好
格式
while() { 语句块 }
注意:while(1):死循环
可以使CPU的占用率保持在100%
2do…while…循环
do{ 语句块 }while(表达式)
do……while……无论表达式如何都会有语句块
3for循环
for(表达式1;表达式2;表达式3) { 语句块 }
执行顺序:表达式1-->表达式2-->语句块-->表达式3(第一次循环没有表达式3)-->表达式2-->语句块---循环
九、函数
简化代码,代码复用(下面就是举例,没有细说,后续会完善)
#include <stdio.h>
int Add(int x,int y)
{
int z = x + y;
return z;
}
int main(int argc, char const *argv[])
{
int a = 4;
int b = 6;
int sum = Add(2,3);
int sum1 = Add(a,b);
printf("%d\n",sum);
printf("%d\n",sum1);
return 0;
}
十、数组
一组相同类型元素的集合
#include <stdio.h>
int main(int argc, char const *argv[])
{
int arr[10]={1,2,3,4,5,6,7,8,9,10};//定义一个存放10个整数数字的数组
//arr[下标],顺序是0-9
//char ch[20];
//float arr1[2];
printf("%d\n",arr[3]);
int i;
for(i=0;i<10;i++)
{
printf("%4d",arr[i]);
}
return 0;
}
数组的大小
#include <stdio.h>
#include <string.h>
int main(int argc,const char *argv[])
{
char str[]="helloworld";
//使用%s输出一个字符串
printf("str = %s\n",str);
char str1[32] = "helloworld";
printf("str1 = %s\n",str1);
char str2[32] = "helloworld";
//sizeof:计算数据类型所占的长度
//strlen:计算字符串的长度(不带\0)
printf("sizeof(str) = %ld\n",sizeof(str));
printf("sizeof(str2) = %ld\n",sizeof(str2));
printf("strlen(str) = %ld\n",strlen(str));
return 0;
}
十一运算符
1、关系运算符
> >= < <= !=
2、逻辑运算符
!:逻辑运算符
&&:逻辑与(并且)
短路原则:从左到右依次判断表达式是否为真,如果有一个为假,则整体为假,不再执行
||:逻辑或(只要有一个成功)
短路原则:从左到右依次判断表达式是否为真,如果有一个为真,则整体为真,后面的表达式不再执行
数学:10<=a<=20
代码:10<=a&&a<=20
3、位运算符
但凡涉及到位操作,一定先将这个数转换为二进制数,然后再操作
~:位逻辑反,1变0,0变1
&:位逻辑与:同为1才为1,否侧为0
|:位逻辑或:有一个为1,就为1,都是0才是0
^:位逻辑异或:相同为0,不同为1
<<:左移
>>:右移
#include <stdio.h>
int main(int argc, char const *argv[])
{
unsigned char m = 0xa7,n = 0x3b;
unsigned char k;
k = ~m;
//m 1010 0111
//~m 0101 1000=0x58
printf("~m=%#x\n",k);
k = m|n;
//m 1010 0111
//n 0011 1011
//m|n 1011 1111=0xbf
printf("~m=%#x\n",k);
k = m^n;
//m 1010 0111
//n 0011 1011
//m^n 1001 1100
printf("~m=%#x\n",k);
k = m << 3;
//左移三位
printf("~m=%#x\n",k);
k = n >> 3;
printf("~m=%#x\n",k);
return 0;
}
4、赋值运算符和复制复合运算符
赋值运算符:=
左值 = 右值
注意:左值必须是变量,右值必须是变量,也可以是常量
=:赋值
==:表示判断是否相等
a = a+b;---->a +=b;
+= -= *= /= %= |= &= ^= <<= >>=
5、条件运算符---三目运算符
格式
表达式1?表达式2:表达式3
表达式1正确--->表达式2,反之表达式3
#include <stdio.h>
int main(int argc, char const *argv[])
{
int a =100,b=20,c;
c=a>b?a++:b++;
printf("a=%d,b=%d,c=%d\n",a,b,c);
return 0;
}