一.static关键字

1.认识头文件

写C语言项目时,一般会创建很多文件,每个文件之间会产生“交互”。下来我们举一个交互的例子:

//test.c文件
void show()
{
    printf("hello world");
}
//main.c文件
#include <stdio.h>
int main()
{
    show();
    return 0;
}

上述代码的具体解释:上述代码中在test源文件中,进行了show函数的定义。随后在main源文件中,进行函数的调用。但是在此期间没有在main.c文件中进行函数的外部符号声明。
但是经过运行代码可以得知,mian.c文件中的函数依然可以正常运行。(会有编译器如下报警)


上述外部函数调用的例子,下面举一个外部变量的例子:

//test.c文件
int g_val=100;
//main.c文件
# include <stdio.h>
int main()
{
  printf("%d",g_val);//不可运行,产生报错
  return 0;
}

上述代码的具体解释:在test.c文件中,进行了变量的定义,并且初始化为100。在main.c文件中,使用了该变量。但是没有使用成功,产生了下方问题的报错:

如果要正常在其他文件中使用该变量,就需要进行外部变量的声明。如下例子所示:

//test.c文件
int g_val=100;
//main.c文件
# include <stdio.h>
int main()
{
  extern int g_val;
  printf("%d",g_val);
  return 0;
}

上述代码的具体解释:在main.c文件中,进行了外部变量的声明,所以才可以在其他文件中使用该变量。
但是这里需要注意的是,不可以这样声明:extern int g_val =100;因为声明并不会为变量开辟空间,等于100仅仅是赋值操作。所以可以得出结论:变量在声明时,不能进行初始化和赋值。

在写工程时,往往会有很多个类似于上方show函数和g_val变量的文件。此时就需要进行文件的管理。如果单纯的使用源文件,组织项目结构时,项目越大越复杂时,维护成本就会越来越高。这时候就需要头文件的加入。有了头文件的加入,组织项目结构的时候,就可以减少大型项目的维护成本问题。
使用头文件,其就会被源文件包含。这时会产生一个问题:头文件重复包含。(头文件重复包含不会引起编译器的报错,但是会影响代码运行的效率)。在头文件顶部加上预处理指令(# pragma once)就可以彻底解决这个问题。(其他解决方法以后详谈)
头文件中一般会包含:C语言库的头文件、所有变量的声明、所有函数的声明和所有的宏定义。下面进行举例表示:

//test.h文件
# pragma once
# include <stdio.h>
extern int g_val;
void show();

上述代码的具体解释:在头文件变量声明时,前面可以不加extern,但是必须加上,因为只有加上才可以让编译器和读者知道该操作是声明而不是定义。在头文件声明函数时可以不加上extern,因为函数括号后面为分号,就可以得知该操作是函数的声明而不是定义。

2.static修饰变量和函数

(1)多文件使用

//test.c文件
static int g_val=100;//全局变量
//main.c文件
printf("%d",g_val);//产生报错,不可运行

上述代码的具体解释:上述代码在test.c文件中,利用static关键字对全局变量g_val修饰,使得该变量只能在本文件中被访问,不能被外部文件直接访问。当然该关键字修饰函数也是如此,使得函数只能在本文件中被使用,不能在外部文件中被直接访问。(但是可以进行间接访问,如果要隐藏函数内部实现的话就可以利用关键字static)

(2)单文件使用

在以前C语言的学习中,我们遇到过下方的代码:

void fun()
{
  int i = 0;
  i++;
  printf("%d",i);
}
int main()
{
  for(int i=0;i<10;i++)
  {
    fun();
  }
}

上述代码的具体解释:运行结果是在屏幕上输出10个1。函数fun中i是局部变量,具有局部临时性。fun函数调用会为其开辟空间并且初始化为1,函数结束时空间释放。所以每次在main函数调用时,i的值会被重置为1。如果要达到大家预期的输出结果(输出1到10)。就需要关键字static修饰:

void fun()
{
  static int i = 0;
  i++;
  printf("%d",i);
}
int main()
{
  for(int i=0;i<10;i++)
  {
    fun();
  }
}

上述代码的具体解释:因为有了static关键字的修饰,使得输出结果变成了大家预期的那样:输出1到10的数字。所以我们可以得出结论:static修饰局部变量,更改了局部变量的生命周期,使得临时变量具有了全局声明周期。(注意这里更改的是变量的生命周期,而不是作用域,下面将用代码进行证明)

void fun()
{
  ststic int a = 100;
}
int main()
{
  printf("%d",a);//无法运行,编译不通过
}

上述代码的具体解释:fun函数中,利用ststic关键字修饰变量a。但是在main函数中无法使用。说明static关键字只是让局部变量拥有全局的生命周期,并没有扩大其作用域。(出了大括号就不可以访问该变量)。

二.基本数据类型

1.数据类型与模子

在这里插入图片描述
在C语言中,基本的数据类型如上图所示。基本的数据类型分为内置类型、构造类型、指针类型和空类型。基本类型主要有char,float,double,short,int,long,longlong。这些基本类型所占用内存的大小各不相同。
为什么会有这么多的数据类型呢?

定义变量的本质是在内存中开辟新的空间,用来保存数据。而不同的变量定义时,需要不同的类型(因为在生活中,数据都是不同类型的)不同类型确定了开辟空间的大小。(运用合适的数据类型,就可以极大限度的节省空间)
本质:用最小的成本解决各种多样化的场景问题

2.变量命名规则

在写程序过程中,根据命名就可以看出一名程序员的职业素养。所以我们应该严格要求自己。让自己的变量命名更加规范化。下面我将具体说明变量的命名规则。

  1. 一般规则:变量命名应该直观且可以拼读,可以望文知义,便于记忆和阅读。标识符最好采用英文单词或组合,不允许使用拼音。程序的英文单词一般不要太过复杂,用词应当准确。
  2. 命名的长度不应该过长或过短,英文的专业名词尽量不缩写。
  3. 当标识符由多个英文单词组成时,每个词的第一个英文字母应当大写,其余全部小写。例如:CurrentVal。
  4. 尽量避免在命名过程中出现编号。除非逻辑上的确需要编号。
  5. 命名不得出现仅靠大小写区分的相似标识符。例如:x和X、o和O、i和I。
  6. 命名变量的过程中,不应该使用已经被定义的函数名。
  7. 所有的宏定义、枚举常量和只读变量应全用大写字母命名,并且用_分割开来。
  8. 在定义循环变量时,可以采用i.j.k。尽量避免用单一字母定义变量。
  9. 定义变量的同时不要忘记对其进行初始化。定义变量之后,编译器会对其开启空间。如果没有初始化,下次使用该空间时,就是该空间上次定义的值(没有释放的情况下)。
  10. 初始化数据左右两边的数据类型一定要一致,不然会出现精度问题。

3.sizeof关键字

(1)sizeof的用法

上面我们学习了变量的本质和开辟变量的原因。知道了不同数据类型的大小不一样。在这里我们要学习sizeof关键字,它会得到不同类型之间的大小(单位是字节)

# include <stdio.h>
int main()
{
  printf("%zd",sizeof(char));//1
  printf("%zd",sizeof(short));//2
  printf("%zd",sizeof(int));//4
  printf("%zd",sizeof(long));//4
  printf("%zd",sizeof(long long));//8
  printf("%zd",sizeof(float));//4
  printf("%zd",sizeof(double));//8
  return 0;
}

上述代码的具体解释:代码通过利用关键字sizeof计算不同数据类型所占空间的大小。

(2)sizeof是函数吗?

该标识符有多种调用方法,下面举例说明:

int a=10:
printf("%zd",sizeof(a));
printf("%zd",sizeof(int));
printf("%zd",sizeof a);
printf("%zd",sizeof int);//编译不通过,报错

上述代码的具体解释:前两次调用类似于函数的格式,均是关键字名字加上括号,括号里面放参数。但是第三次调用没有括号,说明关键字sizeof不是函数,而是一个运算符。

(3)sizeof的拓展

前面我们学到了sizeof关键字可以得到不同数据类型的大小(单位是字节)。下面我们来做一个相关的练习巩固学习吧!

# incude<stdio.h>
int main()
{  
  int *p=NULL;
  int arr[10];
  int *test[3];
  printf("%zd",sizeof(p));//4
  printf("%zd",sizeof(arr));//40
  printf("%zd",sizeof(test));//12
  return 0;
}

上述代码的具体解释:代码首先定义一个指针变量,一个数组,一个指针数组。接下.来,利用分别关键字sizeof得出它们所占空间大小。
指针变量在32位操作系统下,大小为4个字节。在64位操作系统下,大小为8个字节。
数组在做sizeof关键字的参数时表示的不是首元素的地址,而是整个数组。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐