C语言入门笔记 第二讲【常量、字符串和转义字符、选择、循环、函数、数组、操作符、关键字】

一、常量

生活中的有些值是不变的(比如:圆周率,性别,身份证号码,血型等等)

有些值是可变的(比如:年龄,体重,薪资)。

不变的值,C语言中用常量的概念来表示,变的值,C语言中用变量来表示。

C语言的常量分为以下四种:

1.字面常量

3,5.2,10.998等

2.const 修饰的常变量

const指常属性

如const double pi = 3.14;

这个pi就变不了了

若写pi = 5;

就会报错

此时的num还是一个变量,但它具有了常属性。

const int n = 5;
int arr[n];

这样在VS2019就不会报错,若去掉const,程序会认为arr[n]中缺少常量表达式。

注:在老版本的编译器里,即使给n加上const修饰,仍然不能通过,这正好证明了n的本质还是一个变量。

3.#define 定义的标识符常量 

#define MAX 10

4.枚举常量

可一一列举的量

性别:男,女

三原色:红、黄、蓝

枚举关键字: - enum

enum Sex
{
MALE,
FEMALE,
};

int main()
{
enum Sex s = FEMALE;
	printf("%d\n%d\n%d\n", s,MALE, FEMALE);
return 0;
}

打印出来的值分别是1,0,1

枚举常量具有默认值,从0开始

即MALE = 0, FEMALE = 1,这两个量是常量,没法改变

 

二、字符串、转义字符

1、字符串

“hello\n”

这种由双引号(Double Quote)引起来的一串字符称为字符串字面值(String Literal),或者简称字 符串。

要输入一个字符串,可以将其放入一个char[]数组中:

char arr1[] = "abc";
printf("%s\n", arr1);

若使用如下代码:

char arr2[] = { 'a','b','c' };
printf("%s\n", arr2);

则打印结果为:

调试-窗口-监视-监视1

会发现arr2字符串中的字符是无效的。

字符串长度为随机值,直到找到了一个'\0'为止。

若使用如下代码:

char arr2[] = { 'a','b','c','\0' };

(把‘0’换成0亦可)

即可正常输出字符串“abc”。

即使固定数组大小,写arr[3] = { 'a','b','c' };

也会输出乱码。

应写:char arr[4] = { 'a','b','c','\0' };

 

注:字符串的结束标志是一个 \0 的转义字符。在计算字符串长度的时候 \0 是结束标志,不算作字符串内容。

 

数据在计算机上存储的时候,存储的是二进制

ASCII编码:给每个字母对应一个值

a-97

A-65

2、转义字符

转变原来的意思的字符

转义字符释义
\?在书写连续多个问号时使用,防止他们被解析成三字母词

\' 

用于表示字符常量'

(如果想要打印一个字符:’,写'''的话,程序会报错,因为系统会将前两个单引号识别为一对,那么它里面是空;所以我们可以将中间那个单引号加上斜杠,使它成为\',这时候它就不再表示括字符的,具有作用的单引号,而是一个常规的字符单引号)

\"用于表示一个字符串内部的双引号
\\用于表示一个反斜杠,防止它被解释为一个转义序列符。
\a警告字符,蜂鸣
\b退格符
\f进纸符
\n换行
\r回车
\t水平制表符
\v垂直制表符
\dddddd表示1~3个八进制的数字。 如: \130 X
\xdddd表示2个十六进制数字。 如: \x30 0

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

例题:printf("%d\n",strlen("c:\test\32\test.c"))

长度是多少?

首先,\t看成一个字符,不是两个;

其次,\32也是一个转义字符,看成一个字符。

32是2个8进制数字

\32作为8进制代表的那个十进制数字,作为ASCII码值,对应的字符

32:2×8^0+3×8^1=26

26作为ASCII码值,代表的字符是→

也就是说,printf("%d\n",'\32');

打印出来的值是:26

printf("%c\n",'\32');

打印出来的值是:→

三、选择语句

int input = 0;
	scanf("%d", &input);
	if (input == 1)
		printf("好offer");
	else
		printf("卖红薯");

四、循环语句

while

for

do......while

五、函数

#include <stdio.h>
int main()
{
    int num1 = 0;
    int num2 = 0;
    int sum = 0;
    printf("输入两个操作数:>");
    scanf("%d %d", &a, &b);
    sum = num1 + num2;
    printf("sum = %d\n", sum);
    return 0;
}
上述代码,写成函数如下:
#include <stdio.h>
int Add(int x, int y)
{
   int z = x+y;
   return z;
}
int main()
{
    int num1 = 0;
    int num2 = 0;
    int sum = 0;
    printf("输入两个操作数:>");
    scanf("%d %d", &num1, &num2);
    sum = Add(num1, num2);
    printf("sum = %d\n", sum);
    return 0;
}

函数的特点就是简化代码,代码复用。

六、数组

C语言中给了数组的定义:一组相同类型元素的集合

int arr[10] = {1,2,3,4,5,6,7,8,9,10};

七、操作符

算数操作符

+   -   *   /   %

移二进制位操作符

>>   <<

int a = 1;

a:00000000000000000000000000000001

int b =a<<1;

a:00000000000000000000000000000010

左边丢弃,右边补0

即b结果为2,但a没变,仍然是1

二进制位操作符

&   按位与   

int a = 3;   011

int b = 5;   101

int c = a&b;

第一位:1与1是1

第二位:1与0是0

第三位:0与1是0

所以结果为:001

那么c的值为1

^    按位或

第一位:1或1是1

第二位:1或0是1

第三位:0或1是1

所以结果为:111

那么c的值为7

|     按位异或

异或的计算规律:

对应的二进制位相同:0;

对应的二进制位相异:1;

结果为:110

c为6

赋值操作符

=  

+=   

a = 10;

a = a + 10;//a+10后的值再赋给a

等同于:

a += 10;//给a自己加上一个10

-=   

a = a-20;

a -=20;

*=   

/=   

&=   

a = a & 2;

a &= 2;

^=   

|=   

>>=   

<<=

单目操作符(所需操作变量为一个的操作符)

!:逻辑反操作

int a = 10;

printf("%d\n",a);

打印结果为10;

printf("%d\n",!a);

打印结果为0;

因为a不等于10了,所以为假,即0。

-:负值

+:正值

&:取地址

sizeof:操作数的类型长度(以字节为单位,ASCII编码中,一个英文一个字节,一个汉字两个字节)

计算数组大小:

int arr[10] = {0};//10个整型元素的数组

大小为10*sizeof(int) = 40;

也就是这个arr[10]的大小为40字节

~:对一个数的二进制按位取反

int a = 0;

int b = ~a;

a:0000000000000000000000000000

b:11111111111111111111111111111111

b的值输出为-1。

这里涉及到原码,反码,补码。

负数在内存中存储的时候,存储的是二进制的补码。

这里的b是有符号整型,b的二进制最高位是1,代表它是一个负数。

打印的是这个数的原码

原码--符号位不变,其他位取反--反码--加1--补码

补码--减1--反码--符号位不变,其他位取反--原码

b的补码:11111111111111111111111111111111

减1:       11111111111111111111111111111110

取反:      1000000000000000000000000001

得到原码

所以对应十进制数为-1。

--:

++:

1、后置++,a++

int a = 10;

int b = a++;

a = 11,b = 10

先使用a的值,再把a的值自增1;

2、前置++,++a

int a = 10

int b = ++a;

a= =11;b= =11

a先自增1,再使用a的值

*:

间接访问操作符(解引用操作符)

(类型):

强制类型转换

int a = (int)3.14;

把3.14强制转换为int类型

关系操作符

>

>=

<

<=

!=

==

逻辑操作符

&&    逻辑与

int a = 3;

int b = 5;

int c = a&&b;

c=1,为真;

int a = 0;

int b = 5;

此时c = 0,因为a为0,则是假

||       逻辑或

int c = a||b

a与b只要有1个为真,则为真

条件操作符(三目操作符,具有三个操作数)

exp1?exp2:exp3

expN为表达式

若表达式1为真,则表达式2被执行,且值为整个表达式的结果;

若表达式1为假,则表达式3被执行,且值为整个表达式的结果。

求最大值:

int a = 10;

int b = 20;

int max;

if(a>b)

        max = a;

else

        max = b;

return 0;

可用条件操作符来表示:

max = (a > b ? a : b);

a>b吗

大于,则max的值为a;

不大于,则max的值为b。

逗号表达式

exp1,exp2,exp3,...expN

下标引用、函数调用和结构成员

[]   下标引用 

()   函数调用

 .   结构成员

->  结构成员

八、常见关键字(变量名不能和关键字冲突)

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、关键字 typedef

typedef顾名思义是类型定义,这里应该理解为类型重命名

比如:

//将unsigned int 重命名为uint_32, 所以uint_32也是一个类型名
typedef unsigned int uint_32;
int main()
{
    //观察num1和num2,这两个变量的类型是一样的
    unsigned int num1 = 0;
    uint_32 num2 = 0;
    return 0;
}

2、关键字 register

计算机存储数据:

寄存器         空间最小           速度最快

高速缓存      空间较小           速度较快

内存             8G/4G/16G       速度较慢

硬盘             500G                 速度最慢

处理数据步骤:内存--拿数据--CPU(中央处理器)

当CPU速度越来越快时,内存还是很慢,跟不上了,所以出现了高速缓存和寄存器

CPU从寄存器里拿即可

若寄存器没有,则拿高速缓存

从上至下依次去拿

register int a = 10;//若a这个数需要被频繁大量使用,则建议将它放入寄存器中

3、关键字 unsigned

无符号关键字

unsigned int a,a为非负数。

4、关键字 static

static是用来修饰变量和函数的

1、修饰局部变量-静态局部变量

//代码1
#include <stdio.h>
void test()
{
    int i = 0;
    i++;
    printf("%d ", i);
}
int main()
{
 int i = 0;
    for(i=0; i<10; i++)
   {
        test();
   }
    return 0;
}
//代码2
#include <stdio.h>
void test()
{
    //static修饰局部变量
    static int i = 0;
    i++;
    printf("%d ", i);
}
int main()
{
 int i = 0;
    for(i=0; i<10; i++)
   {
        test();
   }
    return 0;
}

代码1中,在test()函数中的变量i,是一个局部变量,每次调用函数时,都需要重新在这个函数中创建一个i = 0;所以打印出来的值为:1 1 1 1 1 1 1 1 1 1

代码2中,经过static的修饰,变量i变成了一个静态局部变量,改变了它的生命周期,让静态局部变量出了作用域依然存在,到程序结束,生命周期才结束。

2、修饰全局变量-静态全局变量

//代码1
//add.c
int g_val = 2018;
//test.c
int main()
{
    printf("%d\n", g_val);
    return 0;
}
//代码2
//add.c
static int g_val = 2018;
//test.c
int main()
{
    printf("%d\n", g_val);
    return 0;
}

代码1正常,代码2在编译的时候会出现连接性错误。

结论:

一个全局变量被static修饰,使得这个全局变量只能在本源文件内使用, 不能在其他源文件内使用。

3、修饰函数-静态函数

//代码1
//add.c
int Add(int x, int y)
{
    return c+y;
}
//test.c
int main()
{
    printf("%d\n", Add(2, 3));
    return 0;
}
//代码2
//add.c
static int Add(int x, int y)
{
    return c+y;
}
//test.c
int main()
{
    printf("%d\n", Add(2, 3));
    return 0;
}

代码1正常,代码2在编译的时候会出现连接性错误。

结论:

一个函数被static修饰,改变了函数的链接属性,将函数的外部链接属性改成了内部链接属性。使得这个函数只能在本源文件内使用,不能在其他源文件内使用。

那么如何引用别的源文件里的函数呢?

使用extern关键字即可:

extern int Add(int,int);

其中Add这个函数是别的源文件下的函数。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值