上海网站建设推,如何做汉服,wordpress表结构写入不全,医疗网站建设新闻目录
数据类型
基本数据类型
typedef 声明
枚举类型
类型转换
变量类型
变量定义
变量声明
左值#xff08;Lvalues#xff09;和右值#xff08;Rvalues#xff09;
变量作用域 数据类型
基本数据类型
C 为程序员提供了种类丰富的内置数据类型和用户自定义的数…目录
数据类型
基本数据类型
typedef 声明
枚举类型
类型转换
变量类型
变量定义
变量声明
左值Lvalues和右值Rvalues
变量作用域 数据类型
基本数据类型
C 为程序员提供了种类丰富的内置数据类型和用户自定义的数据类型。下表列出了七种基本的 C 数据类型
类型关键字布尔型bool字符型char整型int浮点型float双浮点型double无类型void宽字符型 wchar_t
类型修饰符signed、unsigned、short、long 注一些基本类型可以使用一个或多个类型修饰符进行修饰比如signed short int简写为short、signed long int 简写为long。
下表显示了各种变量类型在内存中存储值时需要占用的内存以及该类型的变量所能存储的最大值和最小值。
注意不同系统会有所差异一字节为 8 位。默认情况下int、short、long都是带符号的即 signed。long int 8 个字节int 都是 4 个字节早期的 C 编译器定义了 long int 占用 4 个字节int 占用 2 个字节新版的 C/C 标准兼容了早期的这一设定。
类型位范围char1 个字节-128 到 127 或者 0 到 255unsigned char1 个字节0 到 255signed char1 个字节-128 到 127int4 个字节-2147483648 到 2147483647unsigned int4 个字节0 到 4294967295signed int4 个字节-2147483648 到 2147483647short int2 个字节-32768 到 32767unsigned short int2 个字节0 到 65,535signed short int2 个字节-32768 到 32767long int8 个字节-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807signed long int8 个字节-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807unsigned long int8 个字节0 到 18,446,744,073,709,551,615float4 个字节精度型占4个字节32位内存空间/- 3.4e /- 38 (~7 个数字)double8 个字节双精度型占8 个字节64位内存空间/- 1.7e /- 308 (~15 个数字)long double16 个字节长双精度型 16 个字节128位内存空间可提供18-19位有效数字。wchar_t2 或 4 个字节1 个宽字符
注意各种类型的存储大小与系统位数有关但目前通用的以64位系统为主。
以下列出了32位系统与64位系统的存储大小的差别windows 相同 typedef 声明
typedef是C和C语言中的一个关键字用于给一个已有的数据类型起一个新的别名。typedef可以提高代码可读性和可维护性。
typedef的语法如下
typedef existing_type new_type_name;其中existing_type代表要起别名的已有数据类型new_type_name代表新的别名。existing_type可以是任意合法的数据类型包括基本数据类型、指针、结构体、联合体、枚举等。
typedef可以将一个复杂的数据类型例如struct或者union简化为一个易于使用和理解的名称也可以定义新的类型名称以使得多个数据类型具有相同的类型名称从而增加代码的清晰度。
下面是一些typedef的例子
typedef int myint; // 将 int 类型起个新的别名 myint
typedef float* pfloat; // 将 float* 类型起个新的别名为 pfloat// 用 typedef 定义结构体别名
typedef struct {char name[20];int age;
} Person;// 用 typedef 定义枚举类型别名
typedef enum {Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday
} Weekday;在上面的例子中myint是int类型的别名pfloat是float*类型的别名。Person是一个结构体别名可以通过Person代替struct { char name[20]; int age; }来定义结构体。Weekday是一个枚举类型的别名可以通过Weekday代替enum { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }来定义枚举类型。
需要注意的是typedef只是给一个已有的数据类型起一个新的别名它并不会创建新的数据类型。因此typedef语句不能用于定义新的变量而只能用于定义新的类型名称。
枚举类型
枚举类型是C和C中的一种数据类型用于定义一个有限的、命名的整数值集合。枚举类型可以简化代码的可读性和维护性同时提供了一种方式来表示一组相关的常量。
在C/C中定义一个枚举类型使用enum关键字其语法如下
enum enum_name {value1,value2,value3,// ...
};其中enum_name是枚举类型的名称value1、value2、value3等是枚举常量表示枚举类型的取值。每个枚举常量都会被编译器分配一个整数值默认情况下从0开始递增。
以下是一个示例
enum Color {RED, // 0GREEN, // 1BLUE // 2
};enum Weekday {Monday, // 0Tuesday, // 1Wednesday, // 2Thursday, // 3Friday, // 4Saturday, // 5Sunday // 6
};在上面的示例中Color是一个枚举类型它包含了三个枚举常量RED、GREEN和BLUE。默认情况下RED的值是0GREEN的值是1BLUE的值是2。
同样地Weekday是另一个枚举类型它包含了七个枚举常量分别代表星期一到星期日它们的值从0到6递增。
在使用枚举类型时可以通过枚举常量来表示具体的值。例如
Color myColor RED;
Weekday today Wednesday;上述代码中myColor被赋值为REDtoday被赋值为Wednesday。
需要注意的是枚举常量的作用域是在所属的枚举类型中并且枚举常量之间是唯一的。也可以通过显式地指定枚举常量的值来自定义枚举常量的整数值。例如
enum Status {OK 0,ERROR -1,WARNING 1
};在这个示例中Status是一个枚举类型它包含了三个枚举常量OK、ERROR和WARNING并且分别被赋予了整数值0、-1和1。
枚举类型在编程中经常用于表示一组相关的常量增加代码的可读性和可维护性。它在switch语句中也常用于改善代码的可读性使得程序更加清晰易懂。
类型转换
类型转换是将一个数据类型的值转换为另一种数据类型的值。
C 中有四种类型转换静态转换、动态转换、常量转换和重新解释转换。
1、静态转换Static Cast 静态转换是一种编译时类型转换在代码中使用 static_casttype(value) 的形式进行。它可以将基本数据类型或者用户定义的类型进行转换。静态转换通常用于比较宽松的类型转换例如将一个指针转换为整数类型或者将一个整数类型转换为枚举类型等。但需要注意的是静态转换可能会导致数据精度损失或无效的转换因此在进行类型转换时要谨慎使用并确保转换操作是安全和合理的。
2、动态转换Dynamic Cast 动态转换是一种运行时类型转换在代码中使用 dynamic_casttype(pointer) 的形式进行。它通常用于将一个基类指针或引用转换为派生类指针或引用。在进行动态转换时需要注意转换操作的安全性如果指针或引用不是指向实际对象则转换操作会失败返回空指针或引用。
3、常量转换Const Cast 常量转换是一种用于移除变量的常量属性或加上变量的常量属性的类型转换使用 const_casttype(variable) 的形式进行。它通常用于解决一些编译器警告或者将 const 类型转换为非 const 类型的情况。但是需要注意常量转换只能用于非常量变量上否则会导致未定义的行为。
4、重新解释转换Reinterpret Cast 重新解释转换是一种类型转换它可以将一个指针转换为另一个无关类型的指针或者将一个整数类型转换为一个指针类型使用 reinterpret_cast 进行。它通常用于将不同类型之间的二进制数据进行转换但需要注意的是这种转换可能会产生危险和未定义的行为因此在使用时要格外小心。
下面是一个简单的代码示例演示了在 C 中如何使用不同类型转换方式
#include iostream
using namespace std;int main() {// 静态转换int a 10;double b static_castdouble(a);cout Static Cast: b endl;// 动态转换class Base {public:virtual void print() {cout This is a Base class. endl;}};class Derived : public Base {public:void print() {cout This is a Derived class. endl;}};Base* base_ptr new Derived;Derived* derived_ptr dynamic_castDerived*(base_ptr);if (derived_ptr ! NULL) {derived_ptr-print();} else {cout Dynamic Cast Failed. endl;}// 常量转换const int x 5;int y const_castint(x);y;cout Const Cast: y endl;// 重新解释转换int c 100;void* ptr reinterpret_castvoid*(c);int* d reinterpret_castint*(ptr);cout Reinterpret Cast: *d endl;return 0;
}输出结果如下
Static Cast: 10
This is a Derived class.
Const Cast: 6
Reinterpret Cast: 100
该示例中分别使用了四种不同的类型转换方式包括静态转换、动态转换、常量转换和重新解释转换。静态转换将整数类型转换为浮点数类型动态转换将基类指针转换为派生类指针并调用其成员函数常量转换将 const 类型的变量转换为非 const 类型的变量并修改其值重新解释转换将整数类型的变量地址转换为 void 类型的指针并再次转换回整数类型的指针。通过该示例可以更加深入地理解不同类型转换方式的使用方法和注意事项。
变量类型
1、整数类型Integer Types
int用于表示整数通常占用4个字节。short用于表示短整数通常占用2个字节。long用于表示长整数通常占用4个字节。long long用于表示更长的整数通常占用8个字节。
2、浮点类型Floating-Point Types
float用于表示单精度浮点数通常占用4个字节。double用于表示双精度浮点数通常占用8个字节。long double用于表示更高精度的浮点数占用字节数可以根据实现而变化。
3、字符类型Character Types
char用于表示字符通常占用1个字节。wchar_t用于表示宽字符通常占用2或4个字节。char16_t用于表示16位Unicode字符占用2个字节。char32_t用于表示32位Unicode字符占用4个字节。
4、布尔类型Boolean Type
bool用于表示布尔值只能取true或false。
5、枚举类型Enumeration Types
enum用于定义一组命名的整数常量。
6、指针类型Pointer Types
type*用于表示指向类型为type的对象的指针。
7、数组类型Array Types
type[]或type[size]用于表示具有相同类型的元素组成的数组。
8、结构体类型Structure Types
struct用于定义包含多个不同类型成员的结构。
9、类类型Class Types
class用于定义具有属性和方法的自定义类型。
10、共用体类型Union Types
union用于定义一种特殊的数据类型它可以在相同的内存位置存储不同的数据类型。
11、其他类型
空类型void空类型表示无类型。nullptr类型nullptrnullptr类型表示空指针。
12、引用类型
引用类型intfloat等
注意这些变量类型具有不同的特性和用途。基本数据类型用于存储单个数据值复合数据类型可以存储多个相关数据值指针类型和引用类型用于间接访问变量和内存地址类类型用于创建自定义的对象类型空类型表示无类型nullptr类型表示空指针。
例如以下是使用不同变量类型的示例
#include iostream
using namespace std;int main() {int age 25; // 整数类型double salary 5000.75; // 浮点数类型char grade A; // 字符类型bool isPassed true; // 布尔类型int numbers[] {1, 2, 3, 4, 5}; // 数组类型struct Person {string name;int age;};Person person1 {John, 30}; // 结构体类型enum Color { RED, GREEN, BLUE }; // 枚举类型Color color GREEN;int* ptr nullptr; // 指针类型int ref age; // 引用类型class Circle {double radius;};Circle c; // 类类型void* p nullptr; // 空类型return 0;
}在这个示例中我们用不同的变量类型声明和初始化了变量。请注意C是一种静态类型语言变量必须在使用之前显式声明其类型并且不能在运行时更改其类型。
变量定义
在C中可以使用以下语法来定义变量
type variable_name; // 变量定义不初始化
type variable_name value; // 变量定义并初始化为特定的值其中type表示变量的数据类型type 必须是一个有效的 C 数据类型可以是 char、wchar_t、int、float、double、bool 或任何用户自定义的对象variable_name表示变量的名称variable_list 可以由一个或多个标识符名称组成多个标识符之间用逗号分隔。value表示变量的初始值。
以下是一些示例
int age; // 定义一个整数变量age
double salary 5000.75; // 定义一个双精度浮点数变量salary并初始化为5000.75
char grade A; // 定义一个字符变量grade并初始化为A
bool isPassed true; // 定义一个布尔变量isPassed并初始化为trueint x, y, z; // 同时定义多个整数变量x, y, z
double pi 3.14159, radius 5; // 同时定义多个双精度浮点数变量pi, radius并初始化
注意事项
变量名必须遵循标识符的命名规则且不能与C的关键字重复。在定义变量时可以选择是否对其进行初始化。未初始化的变量将具有不确定的值。可以在定义变量时使用赋值运算符 进行初始化将特定的值赋给变量。在同一行上可以定义多个相同类型的变量并用逗号 , 分隔它们。
值得一提的是C还支持在函数内部定义局部变量、在类中定义成员变量以及在命名空间中定义全局变量。这些变量定义的语法稍有不同但基本原则和概念相同。
变量声明
在C中变量的声明是指在使用变量之前提前声明其存在告诉编译器变量的类型和名称。变量声明只会创建变量的标识符而不会分配内存空间或初始化变量。
以下是一些变量声明的例子
1、声明整数变量
extern int age; // 声明一个整数变量age2、声明浮点数变量
extern double pi; // 声明一个双精度浮点数变量pi3、声明字符变量
extern char grade; // 声明一个字符变量grade4、声明布尔变量
extern bool isPassed; // 声明一个布尔变量isPassed5、声明字符串变量
#include string // 引入string头文件
using namespace std;extern string name; // 声明一个字符串变量name需要注意的是变量的声明通常与变量的定义分开。变量的定义是在声明的基础上为变量分配内存空间并可能进行初始化。变量的声明一般放在头文件中以便在多个源文件中共享同一个变量。
例如在一个名为 variables.h 的头文件中声明变量
extern int age; // 声明整数变量age
extern double pi; // 声明双精度浮点数变量pi
extern char grade; // 声明字符变量grade然后在源文件中进行变量的定义和初始化
#include variables.hint age 25; // 定义并初始化整数变量age
double pi 3.14159; // 定义并初始化双精度浮点数变量pi
char grade A; // 定义并初始化字符变量grade这样通过在源文件中包含声明的头文件可以在不同的源文件中访问和使用这些变量。
左值Lvalues和右值Rvalues
在C中表达式可以分为左值lvalues和右值rvalues。左值和右值的主要区别在于它们在赋值操作符的左边或右边出现的位置。
左值lvalue是一个具有内存地址并且可以被引用的表达式。它可以出现在赋值操作符的左边或右边。换句话说左值是一个可以被取址的表达式。典型的左值包括变量、对象成员以及通过解引用指针获得的值。
右值rvalue是一个临时的、不具有内存地址的表达式。它只能出现在赋值操作符的右边。右值通常是临时生成的值、字面量或表达式的结果。右值不能直接被引用但可以通过将其绑定到右值引用rvalue reference来延长其生命周期。
C11引入了右值引用rvalue references它们是一种新的引用类型用于延长右值的生命周期并支持移动语义。通过将右值绑定到右值引用上可以对其进行修改或移动。
下面是一些示例
int x 5; // x是一个左值
int lvalueRef x; // 左值引用可以引用左值int y x 3; // x3是一个右值
int rvalueRef x 3; // 右值引用可以引用右值int z std::move(x); // std::move()将左值转换为右值引用需要注意的是C中的一些情况下左值可以被隐式地转换为右值例如在函数返回语句中即使左值也可以用作右值。
总结来说左值是具有内存地址的表达式可以出现在赋值操作符的左边或右边。右值是临时生成的、不具有内存地址的表达式只能出现在赋值操作符的右边。右值引用类型可以绑定到右值并支持对其进行修改或移动。
变量作用域
一般来说有三个地方可以定义变量 在函数或一个代码块内部声明的变量称为局部变量。 在函数参数的定义中声明的变量称为形式参数。 在所有函数外部声明的变量称为全局变量。
1、全局作用域Global Scope在任何函数、代码块之外定义的变量具有全局作用域。这意味着它们在整个程序中都是可见和可访问的。全局变量在程序启动时被创建在程序结束时销毁。
#include iostreamint globalVariable 10; // 全局变量int main() {std::cout globalVariable std::endl; // 可以在任何位置访问全局变量return 0;
}2、块作用域Block Scope在函数或代码块内部定义的变量具有块作用域。这意味着它们只在定义它们的代码块内部是可见和可访问的。当代码块执行完毕后变量将被销毁。
#include iostreamint main() {int x 5; // 块作用域的变量{int y 10; // 嵌套的块作用域的变量std::cout x y std::endl; // 可以在代码块内部访问x和y}std::cout x std::endl; // 只能在外层代码块内部访问x// std::cout y std::endl; // 错误y超出了作用域无法访问return 0;
}3、函数参数作用域Function Parameter Scope函数参数的作用域仅限于函数内部。它们在函数被调用时创建并在函数执行完毕后销毁。
#include iostreamvoid myFunction(int param) { // 参数param的作用域仅限于函数内部std::cout param std::endl; // 可以在函数内部访问参数param
}int main() {myFunction(5);// std::cout param std::endl; // 错误参数param的作用域仅限于函数内部无法在main函数中访问return 0;
}4、类作用域Class Scope在类定义内部声明的变量具有类作用域。它们可以被类中的任何成员函数访问。
#include iostreamclass MyClass {
public:int classVariable; // 类作用域的变量void myMethod() {std::cout classVariable std::endl; // 可以在成员函数中访问类作用域的变量}
};int main() {MyClass obj;obj.classVariable 10;obj.myMethod();return 0;
}需要注意的是当在内部作用域中声明的变量与外部作用域中的变量同名内部作用域的变量会隐藏外部作用域的同名变量。
变量的作用域是C中管理变量可见性和访问性的重要概念。了解变量作用域对于编写正确和清晰的代码非常重要。