数据类型

为了更加丰富地表达生活中的各种值,C语言中有不同的数据类型。每个数据类型有其占用空间的大小。我们用sizeof可以获取某个数据类型所占用空间的字节数。

下面这段代码:

1
2
3
4
5
6
7
printf("%d", sizeof(char));
printf("%d", sizeof(short));
printf("%d", sizeof(int));
printf("%d", sizeof(long));
printf("%d", sizeof(long long));
printf("%d", sizeof(float));
printf("%d", sizeof(double));

在vs2019运行时,输出结果是:1244848

在linux平台运行时,结果是:1248848

对比发现,long在不同的编译器结果不同。c语言并没有规定long的大小,只是规定了sizeof(long)>=sizeof(int)。

变量的作用域和生命周期

  • 作用域:变量作用的范围。变量在哪里可以使用,哪里就是它的作用域。

局部变量的作用域是变量所在的局部范围;全局变量的作用域是整个工程。

  • 生命周期:变量由创建到销毁这一时间段

局部变量的生命周期是:局部变量的作用域;全局变量的生命周期是:整个程序。

常量

字面常量

const修饰的常变量

1
2
3
const double pi = 3.14;
pi = 6.66;
//报错信息:表达式必须是可修改的左值

由const修饰的变量只是不可以再次修改,但本质仍是变量。

define定义的标识符常量

1
2
#define MAX 100
printf("max = %d\n", MAX);

枚举常量

1
2
3
4
5
6
7
8
9
10
11
12
enum MyEnum
{
MALE,
FAMALE,
SECRET
};
int main()
{
printf("%d", MALE); //0
printf("%d", FAMALE); //1
printf("%d", SECRET); //2
}

字符串

1
2
3
4
5
6
7
8
int main()
{
char arr1[] = "hello";
char arr2[] = { 'h','e','l','l','o' };
printf("%s\n", arr1);
printf("%s\n", arr2);

}

image-20211227094115348

字符串的结束标志是一个\0的转义字符。在计算字符串长度的时候\0不算作字符串内容。printf输出内容是\0之前的内容,arr2找不到\0出现了乱码,用strlen计算长度时也会出现随机值。

转义字符

下段代码的输出结果是什么?

1
printf("%d\n", strlen("c:\test\628\test.c"));

输出结果是14。

\t----->水平制表符

\62—>将8进制数数字62转换成10进制数字50

注:

\ddd中ddd表示1-3位八进制数字,范围是0-7,所以上题中是\62,不是\628

\xdd中dd表示2个十六进制数字。 如:

1
2
printf("%c\n", '\x31'); //1
//将16进制数字31转换为10进制数字49,ascii码值代表的字符为 ‘1’

关键字

1
2
3
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

define

定义标识符常量
1
2
3
4
5
6
7
8
9
10
#include<stdio.h>
#define N 5
int main()
{
int arr[N] = {0,1,2,3,4};
int i = 0;
for (i = 0; i < N; i++) {
printf("%d", arr[i]);
}
}
定义宏
1
2
3
4
5
6
7
#define MAX(a,b)(a)>(b)?(a):(b)
int main()
{
int x = 10;
int y = 20;
printf("%d", MAX(x,y)); //20
}

static

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

  1. 修饰局部变量-称为静态局部变量
  2. 修饰全局变量-称为静态全局变量
  3. 修饰函数-称为静态函数
修饰局部变量

观察下面两段代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<stdio.h>
void add() {
static int b = 0;
b++;
printf("%d", b); //12345
}
int main()
{
int i = 0;
for (i = 0; i < 5; i++) {
add();
}
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<stdio.h>
void add() {
int b = 0;
b++;
printf("%d", b); //11111
}
int main()
{
int i = 0;
for (i = 0; i < 5; i++) {
add();
}
return 0;
}

对比发现,static修饰局部变量改变了变量的生命周期,让静态局部变量出了作用域依然存在,到程序结束,生命周期才结束。

static修饰局部变量时,改变了局部变量的存储位置,将局部变量由堆区存储到静态区。

修饰全局变量和函数

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

全局变量(函数)具有外部链接属性,可以用extern外部引用,但被static修饰后,外部链接变成了内部链接,只能在当前源文件内部使用。

typedef

类型重命名:使类型名简单化,书写更方便

1
2
3
4
5
6
7
//将类型unsigned int重命名为uint_32,下次可以直接使用类型uint_32
typedef unsigned int uint_32;
int main()
{
unsigned int a = 0;
uint_32 b = 0;
}

结构体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//定义结构体类型
struct MyStruct
{
char name[20];
int age;
char sex[6];
};
//d
void stu(struct MyStruct* ps) {
printf("%s,%d,%s", ps->name, ps->age, ps->sex);
}
int main()
{
//结构体实例化
struct MyStruct stu1 = {"菜鸟小胖p",20,"保密"};
struct MyStruct stu2 = { "小明",101,"男" };
//打印结构体
printf("%s,%d,%s\n", stu1.name, stu1.age, stu1.sex);
//函数打印结构体
stu(&stu2);
}