首页 > 编程语言 > 详细

[知识点] 1.2 C 语言数据类型

时间:2020-09-04 08:38:46      阅读:37      评论:0      收藏:0      [点我收藏+]

总目录 > 1 语言基础 > 1.2 C 语言基本语句与数据类型

前言

这篇文章对 C语言里一些最基础的编程知识进行简要介绍。因为对 C / C++ 大部分入门内容都轻车熟路了,有些地方可能就不恰当地略过了。

对于 C++ 语言本身的许多基础知识以及高级教程,这里推荐一个很经典的教程网站:https://www.runoob.com/cplusplus/cpp-tutorial.html,非常详细。

子目录列表

1、基本数据类型

2、变量与常量

3、数组

4、结构体

5、函数

6、文件操作

 

1.2 C 语言数据类型

4、变量与常量

① 变量

变量,指没有固定值而可以改变的数,一般用非数字符号表达,在计算机语言中是相对关键的一类数。

C / C++ 中定义了如下基本数据类型:

int - 整型,表示整数,占用 4 个字节,表示范围为 [-2147483648, 2147483647 (= 2 ^ 31 - 1)],还有:

short int - 短整型,占用 2 个字节,表示范围为 [-32768, 32767 (= 2 ^ 15 - 1)];

long long int - 长整型,占用 8 个字节,表示范围为 [-9223372036854775808, -9223382036854775807 (= 2 ^ 63 - 1)],可缩写为 long long;

float - 单精度浮点型,表示小数,占用 4 个字节,表示范围大致为 [-3.4 * 10 ^ 38, 3.4 * 10 ^ 38];

double - 双精度浮点型,表示小数,占用 8 个字节,表示范围大致为 [-1.7 * 10 ^ 308, 1.7 * 10 ^ 308];

char - 字符型,表示字符,占用 1 个字节,表示范围为 [0, 255];

bool - 布尔型,表示真或假,占用 1 个字节,表示范围为 [0, 1];

void - 无类型

还有一些不太常用的暂时不列。

声明变量的格式:

变量类型 变量名, ...

比如:

int a;

double b;

char c = ‘a‘;

声明的同时可以赋值。

② 常量

常量与变量相对,表示不会改变的数,声明时直接附加一个 const,且必须赋值,比如:

const int a = 2;

③ 作用域

写在主程序外的变量称为全局变量,其作用域为整个程序;其他的为局部变量,其作用域是声明语句所在的代码块,只能在所属代码块或者所属函数中使用。至于代码块怎么理解,可以视作一对 {} 为一个代码块。

虽然称之为全局/局部变量,其实对于常量而言也是一样的。不过对于变量,还有一点需要注意:全局变量声明时没有赋值则初始化为 0;局部变量不会初始化,是出现 bug 很常见的起因。

④ 互通性

C / C++ 的基本数据类型具有很强的互通性。诸如 int, long long / float, double 等同类型可以直接互通,但要注意范围与精度问题;整型数与浮点数同样可以直接赋值,但浮点数赋值给整型变量会损失小数部分;int, char, bool 之间能够互通,尽管它们是完全不同的类型,区别仅在于三者的数据范围,以及 char 数组被特殊地视作字符数组。

比如定义 char x = 65,或者 int y = ‘a‘,两者都是合法的,且数值是相等的。

⑤ 强制转换

在值的前面加上数据类型强制转换标识,可以无视值本身所属的类型而直接转换,格式为 :(数据类型) 值。比如 (int) 2.527 的返回值为 2,(bool) 7 的返回值为 1。

10、数组

① 定义

前面已经介绍了变量,变量是独立的,即两个不同变量之间没有任何关系,而如果我们需要存储一系列有关联的变量,就要用到数组

形如 a[x] 的变量声明为数组。a 是数组的名字,x 表示数组中元素的个数。可以和数学中的数列相联系。数组的类型可以为上述任何基本数据类型,比如一个 int 类型的数组变量 a[x],表示有 x 个连续 int 类型的变量,而不同于独立的变量,这 x 个变量并没有自己独一无二的变量名,所以在访问的时候是通过其所属数组的变量名 + 编号来访问。

对于数组 a[x],其编号为 [0, x),即数组中第 i 个元素的访问方式为 a[i - 1],i - 1 被称作该元素在该数组的下标。也就是说,第 1 个元素是存储在 a[0],这在一些情况下可能会使用不便,从日常习惯来看,一般 1 才是表示一切的开始,而 0 表示不存在,所以我们通常可以将数组 x 稍微定义较大一点,比如需要 100 个元素时,x 定义为 101(x + 1, x + 5, x + 10 均可,一般越大越能更好避免越界情况,但同时也会带来占用更多空间的问题),然后从 a[1] 开始存储 / 访问数据,方便理解。

声明的同时可以进行初始化,用花括号表示一个组。

下面给出一些数组的定义:

int a[10];
char c[5] = {‘a‘, ‘b‘, ‘c‘, ‘d‘, ‘e‘};
const double fk[105];
bool w[3] = {1, 1};

并不一定需要将所有元素均进行初始化。

② 多维数组

上面介绍的数组属于一维数组,即只有一个下标,元素之间只有线性关系。那么,如果我们需要表示一个面甚至一个体的话,则需要用到多维数组。

二维数组由两个下标组成,形如 a[x][y]。数组总共包含 x * y 个元素,我们可以类比平面几何,将第一维 x 视作行,第二维 y 视作列,那么对于数组中的任意元素 a[i][j],可以理解为矩阵中第 i 行第 j 列元素的值。

三维数组同理,类比立体几何。当然,超越现实的更高维数组同样存在。

 

11、结构体

① 定义

相较于数组,结构体(struct)是一种更为灵活的高级数据类型。数组只能用来存储访问若干个相同数据类型的元素,而结构体,则可以将各类元素进行组合。先举个例子:

struct s {
    int b;
    double c;
    char d[10];
};

s a;

表示声明了一个名为 s 的结构体,这个结构体由一个 int 类型变量 b,一个 double 类型变量 c,一个 char 类型变量数组 d[10] 组成。接着,定义了一个名为 a 的结构体 s 变量。弄清楚 a 和 s 的区别 —— s 是结构体的名称,本身只是一种声明而不占用任何存储空间,是自定义的一种数据类型;a 是数据类型为 s 的一个变量,每定义一个这样的变量,就会同时生成一组 b, c, d[10]。对于任何存在的基本数据类型,都可以在结构体中进行定义。

同样地,结构体也可以是一组结构体,即结构体数组。比如:

struct s2 {
    int b;
    double c;
    char d[10];
} a[100];

a[100] 表示创建了一个数据类型为 s2,名为 a 的结构体数组,其中包含 100 个 s2 类型的结构体。

这里的定义方式和上面代码有一定区别,即直接在结构体作用域后写上变量名,再以分号结束,两种方式是等价的。

② 访问 / 修改元素

访问结构体中的各个变量有两种方式:

> 结构体变量名.成员元素名

比如上述代码,则可以使用诸如 a[1].b, a[2].c, a[3].d[5] 这种格式来访问元素。

> 指针名 -> 成员元素名 / (*指针名).成员元素名

关于指针,1.3.5  指针与引用 进行了介绍,这里不再赘述。

修改的话同理,直接赋值即可。

③ 结构体与类

注意,这里描述的结构体是 C 语言中狭义的结构体,不包含 C++ 赋予的新特性。因为在 C++ 中,结构体和 C++ 中独有的类(class)极其相似,且 C++ 作为面向对象语言,其对类 / 结构体赋予的意义要更为生动,所以这一部分单独在 1.3.6 类与对象 中进行介绍。

④ 关于数组与结构体的声明位置

注意,数组和结构体往往占用空间大,所以一般情况下尽量定义为全局变量,因为如果定义为局部变量,则可能导致爆栈进而 RE。

加上上述的“局部变量不会赋初值 0”,我的 OI 生涯中几乎无一例外地将所有可以定义为全局变量的全部定义为全局了,是一种图方便的做法,可以很大程度上避免这种类型的 RE。其实从逻辑上看不符合代码规范,也不利于对程序的阅读和理解,所以以后还是尽可能的符合逻辑地定义各种变量。

 

11、函数

(原网站这么重要的部分竟然是空的,,所以我也时隔许久才更新这一块)

最开始我们提到,每一个 C / C++ 程序都有个必不可少的部分:int main(),我们称之为主函数。那么,函数到底是什么?数学里我们其实已经接触许多,其实在计算机语言里也大同小异,从数学角度出发来介绍的话 —— 函数一般由自变量和因变量组成,最基础的函数表达式 y = f(x) 中,x 为自变量,y 为因变量,y 随着 x 的值变化而变化。而这个式子转化成 C计算机语言中是什么形式呢?举个例子:

int function(int x) {
    ...
    return y;
}

这是一个名为 function 的 int 类型的函数。x 类似于自变量,称为参数,y 类似于因变量,称为返回值,其数据类型和函数的数据类型是一致的,即 int 类型,该类型称为函数的返回类型。返回类型可以是任何基本与高级数据类型。

举一个例子。

int max(int a, int b) {
    if (a > b) return a;
    else return b;
}

这是最大值函数。参数有两个 a, b,函数为 int 类型,很好理解。

和数学中函数不同的是,C / C++ 对函数的定义更为宽泛:

返回类型可以为空,用 void 来表示,对于这样的函数,本质只是将若干语句组在一起,起到划分作用,它没有返回值。

参数可以为空,不填入即可,即没有任何传递进去的值,但函数依然正常执行。

举个例子。

 1 int n, ans;
 2 
 3 void add1() {
 4     for (int i = 1; i <= n; i++)
 5         ans += i;
 6 }
 7 
 8 int add2() {
 9     for (int i = 1; i <= n; i++)
10         ans += i;
11     return ans;
12 }
13 
14 int add3(int n) {
15     for (int i = 1; i <= n; i++)
16         ans += i;
17     return ans;
18 }
19 
20 int main() {
21     int o = n;
22     add1();
23     int a2 = add2();
24     int a3 = add3(o);
25     return 0;
26 }

add3 函数有返回值,也有参数。我们将定义在主函数的局部变量 o 传递给 add3,且该参数命名为 n。这个 n 并不同于全局变量 n(尽管在这里它们值是相同的),也就是说在函数内访问 n 时,是默认访问函数的参数而非全局变量,这是个优先级的问题。然后我们将最后得到的 ans 返回到主函数定义的 a3 中。

add2 函数有返回值而没有参数。

add1 函数没有返回值,也没有参数。这样的函数一般是用来对程序段进行划分,使程序逻辑更加清晰。对于上述程序,由于 n 和 ans 都是全局变量,那么 add1 函数这样的结构已经能够完成任务了。

函数参数有三种调用三种方式:传值调用,指针调用,引用调用。上述代码均为第一种,而后两种的使用方法参见:1.3.5 指针与引用

参数还可以指定默认值。指定了默认值的参数不需要在调用时传值。

回过头来说主函数。这样是一种为了符合程序规范,自圆其说的设计,将整个程序打包成一个函数,并且最后需要写明其返回值为 0,所以程序在运行结束后可以看到终端会写上一句 “... with return value 0”(程序返回值为 0)。而如果它不是 0,则说明程序出现了问题,一般是 RE。

 

12、文件操作

不涉及文件操作的时候,程序的输入输出都是直接在终端中进行的,引入文件操作后,可以使我们的程序从指定文件中读入数据,再将数据输出到指定文件。

① freopen 函数

一般格式:

freopen(文件名, "模式", 流);

部分模式列表:

r - 只读;w - 只写;r+ - 读写,文件必须存在;w+ - 读写,会自动新建;

a - 只写,不存在会自动新建,存在会直接将数据附加在文件末尾,保留 EOF 符;

a+ - 同 a,但不保留 EOF 符。

比如:

freopen("data.in", "r", stdin);

freopen("data.out", "w", stdout);

关闭文件(可以不写):

fclose(stdin);

fclose(stdout);

② fopen 函数

格式和 freopen 类似:

fopen(文件名, "模式");

区别在需要定义文件指针,比如:

FILE *in, *out;

in = fopen("data.in", "r");

out = fopen("data.out", "w");

与此同时,输入输出的函数需要进行修改,比如:

fscanf(in, "%d", &a);

fprintf(out, "%d", a);

相对比较麻烦,平时用的不太多。

③ fstream 函数

C++ 特有,名为“文件输入输出流”,格式为:

fstream 流名(文件名);

比如:

fstream file("data.txt");

其中,fstream 可以更改为 ifstream 或 ofstream,表示只支持读 / 写。

中间的读写函数从 cin / cout 改成 file 即可。

关闭文件:

流名.close();

 

[知识点] 1.2 C 语言数据类型

原文:https://www.cnblogs.com/jinkun113/p/13611175.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!