C的基本数据类型
1.int
C语言中的int是比较常用的数据类型,int是整型。整型数据顾名思义就是整数的意思。在C中定义一个整型变量就可以使用int这个数据类型。举例如下:
int a = 10;
int sum = 100;
上面的例子中定义了一个整型变量a等于10和整型变量sum等于100。int的取值范围: [-2147483648,2147483647](即-2^31 ~ 2^31 -1)。当int取值超出取值范围时,编译程序时就会出警告(有的会报错)。例如:
int a = 2147483648;
printf("%d",a);
如果你的编译器很强大那么它会给出个警告,表示数据类型的变量溢出,会打印出-2147483648的结果;否则会在编译程序时直接报错。
2.char
C语言中的char(即字符型)类型应用比较广泛,它即可以用作字符的表示又可以当作数值进行运算(对于数值较小的情况下)。char类型的定义方式如下:
char ch = 'a';
char num = 65;
上面定义了一个字符变量ch为a,又定义了一个字符变量num并赋值为65。char类型的取值范围是[-128,127](即-2^7 ~ 2^7-1)。因此char类型也可以存整型数,但是不要超出它的取值范围,否则还是会有溢出警告。上面的类型输出如下:
char ch = 'a';
char num = 65;
printf("%c %d",ch,num);
输出结果:a 65
char类型的变量用作字符表示的时候都是对应着ascII码的,当给char类型赋值不同的整数时,都能对应转化成ascII码表对应的字符。ASCII码表完整版
ASCII值 | 控制字符 | ASCII值 | 控制字符 | ASCII值 | 控制字符 | ASCII值 | 控制字符 |
0 | NUT | 32 | (space) | 64 | @ | 96 | 、 |
1 | SOH | 33 | ! | 65 | A | 97 | a |
2 | STX | 34 | ” | 66 | B | 98 | b |
3 | ETX | 35 | # | 67 | C | 99 | c |
4 | EOT | 36 | $ | 68 | D | 100 | d |
5 | ENQ | 37 | % | 69 | E | 101 | e |
6 | ACK | 38 | & | 70 | F | 102 | f |
7 | BEL | 39 | , | 71 | G | 103 | g |
8 | BS | 40 | ( | 72 | H | 104 | h |
9 | HT | 41 | ) | 73 | I | 105 | i |
10 | LF | 42 | * | 74 | J | 106 | j |
11 | VT | 43 | + | 75 | K | 107 | k |
12 | FF | 44 | , | 76 | L | 108 | l |
13 | CR | 45 | - | 77 | M | 109 | m |
14 | SO | 46 | . | 78 | N | 110 | n |
15 | SI | 47 | / | 79 | O | 111 | o |
16 | DLE | 48 | 0 | 80 | P | 112 | p |
17 | DCI | 49 | 1 | 81 | Q | 113 | q |
18 | DC2 | 50 | 2 | 82 | R | 114 | r |
19 | DC3 | 51 | 3 | 83 | X | 115 | s |
20 | DC4 | 52 | 4 | 84 | T | 116 | t |
21 | NAK | 53 | 5 | 85 | U | 117 | u |
22 | SYN | 54 | 6 | 86 | V | 118 | v |
23 | TB | 55 | 7 | 87 | W | 119 | w |
24 | CAN | 56 | 8 | 88 | X | 120 | x |
25 | EM | 57 | 9 | 89 | Y | 121 | y |
26 | SUB | 58 | : | 90 | Z | 122 | z |
27 | ESC | 59 | ; | 91 | [ | 123 | { |
28 | FS | 60 | < | 92 | / | 124 | | |
29 | GS | 61 | = | 93 | ] | 125 | } |
30 | RS | 62 | > | 94 | ^ | 126 | ~ |
31 | US | 63 | ? | 95 | — | 127 | DEL |
3.long
long num = 1234567;
long long num_num = 123456789;
long long数据类型较int型要大出许多,long的取值在一般情况下要大于或者等于int。所long的取值在32位系统下一般和int相同为[-2147483648,2147483647](即(-2^31 ~ 2^31 -1))。而longlong的取值范围要大为[-9223372036854775808,9223372036854775807](即-2^63 ~ 2^63 - 1)。
4.short
short作为c语言中最小的整型(即短整型),也用于存储整型数的数据类型,定义方式如下:
short num = 222;
short int numi = 232;
short类型的大小一般小于int的类型大小,short的取值范围一般在[-32768,32767](即-2^15 ~ 2^15 - 1)。在定义短整型上short int可以简写成short,同样long int也可写成long。
5.float
float fd = 3.1415926;
float ff = 3.1415926f;
float数据类型在定义的时候可以在数值后加f表示float类型,也可不加直接赋值成小数,最好还是加上吧,这样可以与其他数据类型相区别。float的取值范围在-3.4*10^38 ~ 3.4*10^38(即-2^127 ~ 2^127)。float的精度是6到7位有效数字。
6.double
double类型比float类型的精度要高,即双精度浮点型。 定义如下:
double d = 3.14159265354;
double类型的变量要比float的精度高,double的精度是15-16位有效数字。输出如下:
double d = 3.141592653546973;
printf("%0.15f",d);
<span style="font-size:14px;color:#000099;"><strong> 输出结果:3.141592653546973</strong></span>
C的指针
1.指针的类型
指针是c语言中最具特色的数据类型,下面我罗列一下经常使用的指针类型:
int *p; //整型指针p
char *ch; //字符指针ch
int **pt; //二级指针pt
int (*a)[10]; //数组指针a
int (*f)(); //函数指针f
这些指针各自有各自的类型,同时它们的作用都类似都是指向内存中的一片空间。
2.指针的使用
int a = 10;
int *p = &a;
*p = 20;
printf("%d",*p );
数组指针可以通过指针间接修改和使用数组中的任何元素。
int (*a)[10];
int num[10]={1,2,3,4,5,6,7,8,9,0};
a = #
printf("%d %d",(*a)[1],num[1]);
函数指针便于调用函数。
int sub(int a,int b)
{
return a - b;
}
int add(int a,int b)
{
return a + b;
}
int main(int argc, const char * argv[])
{
int (*f)();
f = sub;
printf("%d\n",(*f)(3,2));
f = add;
printf("%d\n",(*f)(3,2));
return 0;
}
C的构造类型
1.结构体
struct student
{
int num;
char *name;
};
struct student stu;
struct class
{
int num;
char *name;
int a[10];
}nsobj;
struct
{
int a;
int b;
char *p;
}q;
以上是结构体的三种定义方式,结构体的定义之后需要初始化才能使用。
stu.name = "lsmseed";
stu.num = 10;
定义时初始化
struct class
{
int num;
char *name;
int a[10];
}nsobj =
{
10,
"lsmseed",
{1,2,3,4,5,6,7,8,9,0}
};
2.共用体
共用体与结构体的区别在于共用体的成员变量共用同一块内存空间,给共用体成员赋值会影响到其他成员变量。
union student
{
int a;
char ch;
}stu;
int main(int argc, const char * argv[])
{
stu.a = 65;
printf("%d %c\n",stu.a,stu.ch);
stu.ch = 66;
printf("%d %c\n",stu.a,stu.ch);
return 0;
}
运行结果:
65 A
66 B
共用体中的成员变量改变使得其他的成员变量受到影响,这也就直接证明了共用体的所有成员共用一块内存空间的事实。一般这样的特性也可以用来测试自己机器是怎样存储数据的。
int checkSystem()
{
union check
{
int i;
char ch;
}c;
c.i = 1;
return (c.ch == 1);
}
3.数组
int a[5];
a[0] = 0;
a[1] = 1;
a[2] = 2;
a[3] = 3;
a[4] = 4;
数组的简单初始化:
char name[20] = "lsmseed";
int b[] = {1,2,3};
4.枚举
enum season
{
spring,
summer,
automn,
winter
} s;
enum season
{
spring,
summer,
automn,
winter
};
enum season s = winter;
enum
{
spring,
summer,
automn,
winter
} s;
枚举的三种定义方式和结构体的形式一样,虽然用法不同,但是却有着惊人的相似。枚举的最大特点是存储有限的常量来使用,因为枚举的成员都是命名常数,与常量对应。
enum season
{
spring,
summer,
autumn,
winter
};
int main(int argc, const char * argv[])
{
enum season s = winter;
printf("s = %d\n",s);
s = spring;
printf("s = %d\n",s);
s = summer;
printf("s = %d\n",s);
s = autumn;
printf("s = %d\n",s);
}
枚举类型的成员变量都有自己对应的常量。所以枚举类型可用于有限常量空间的数据存储。
C的空类型
空类型一般用作修饰函数的返回值类型,不能用于实例化变量,因为void表示抽象的数据类型。用void定义一个变量没有任何意义。
void a //编译报错
void fun() //定义一个无返回值类型的函数
{
printf("lsmseed\n");
}
void sum(void) //定义一个无返回值类型的且无参数类型的函数。
空类型还可以定义万能指针,接收任何指针类型。但是void类型的指针不能强制赋值给其他指针类型。
void *p;
int a = 10;
char ch = 'a';
p = &a;
printf("p = %p p1 = %p\n",p,&a);
p = &ch;
printf("p = %p p2 = %p\n",p,&ch);
return 0;
输出结果:
p = 0x7fff5fbff8bc p1 = 0x7fff5fbff8bc
p = 0x7fff5fbff8bb p2 = 0x7fff5fbff8bb
void *p;
int *p1;
p1 = p;
一般会报错,要是容错能力高的编译器会出警告。
C的全局变量与局部变量
1.全局变量
全局变量,就是程序始终都存在的变量,一般定义在函数外部。全局变量也分为外部全局变量和内部全局变量。外部全局变量用extern修饰,内部全局变量用static修饰。
#include <stdio.h>
int a;
int a;
int a = 10;
extern int b;
#include "one.h"
void sum(int c)
{
a++;
b++;
}
int main(int argc, const char * argv[])
{
a++;
b++;
printf("a = %d\n",a);
printf("b = %d\n",b);
sum(a);
sum(b);
printf("sum(a) = %d\n",a);
printf("sum(b) = %d\n",b);
printf("add(a,b) = %d\n",add(a,b));
return 0;
}
int b;
运行结果:
a = 11
b = 1
sum(a) = 13
sum(b) = 3
add(a,b) = 16
全局变量可以定义多个重复的,但是始终都是用一块存储空间,就像上面的程序定义了多个同名变量a,却都代表一个。全局变量的定义可以先声明,后定义,即先用extern声明变量b,再在其他地方定义一个变量b。一般全局变量b都可以省略extern关键字。
给上面的程序加两段代码,如下:
test.c
extern int a;
int add(int num1, int num2)
{
a++;
return num1 + num2;
}
test.h
#ifndef struct_Header_h
#define struct_Header_h
int add(int ,int );
#endif
运行结果:
a = 11
b = 1
sum(a) = 13
sum(b) = 3
add(a,b) = 16
a = 14
可以看出在主函数里定义的全局变量a,在test.c文件中使用的变量a是同一个,全局变量可以跨文件使用。
与外部全局变量相对的是内部全局变量,内部全局变量的特点是只能在本文件内部使用。
main.c
#include <stdio.h>
#include "one.h"
//int a;
//int a;
static int a = 10;
extern int b;
void sum(int c)
{
a++;
b++;
}
int main(int argc, const char * argv[])
{
a++;
b++;
printf("a = %d\n",a);
printf("b = %d\n",b);
sum(a);
sum(b);
printf("sum(a) = %d\n",a);
printf("sum(b) = %d\n",b);
printf("add(a,b) = %d\n",add(a, b));
printf("a = %d\n",a);
return 0;
}
int b;
one.c
static int a;
int add(int num1, int num2)
{
a++;
printf("a = %d\n",a);
return num1 + num2;
}
one.h
#ifndef struct_Header_h
#define struct_Header_h
int add(int ,int );
#endif
运行结果:
a = 11
b = 1
sum(a) = 13
sum(b) = 3
a = 1
add(a,b) = 16
a = 13
用static修饰的内部全局变量,仅在定义的文件内部有效,在其他文件中,仅限于其他文件内部的变量使用。所以,static修饰的内部全局变量,和其他文件中的重名时,是两个内部变量,不是同一个变量,这是和外部全局变量的区别。
2.局部变量
局部变量,就是定义在程序中函数内部的变量。局部变量分为自动类型变量和静态局部变量。自动类型的变量在函数执行结束后就自动释放了,静态的局部变量在程序运行的始终都存在。
#include <stdio.h>
void fun(a,b)
{
static int num = 1;
num++;
a++;
b++;
printf("a = %d\nb = %d\nnum = %d\n",a,b,num);
}
int main(int argc, const char * argv[])
{
int a = 10;
int b = 20;
printf("a = %d\n",a);
printf("b = %d\n",b);
fun(a, b);
fun(a, b);
return 0;
}
运行结果:
a = 10
b = 20
a = 11
b = 21
num = 2
a = 11
b = 21
num = 3
默认自动类型的变量a,b在函数fun调用完成后,自动释放了,每次的值输出都是一样的,而static修饰的变量num在调用完之后,每次的数值都保存在num变量中,直到程序结束时为止。
寄存器变量,一般用的不多,但是寄存器变量优先于内存分配存储空间,所以运行速度更快。
#include <stdio.h>
int main(int argc, const char * argv[])
{
register a = 0;
register b = 5;
printf("a + b = %d\n",a+b);
return 0;
}