目录
1.指针
(1)指针的理解:
1. 指针是内存中一个最小单元的编号,也就是地址
2. 平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量
总结:指针就是地址,口语中说的指针通常指的是指针变量。
(2)指针变量
我们可以通过&(取地址操作符)取出变量的内存其实地址,把地址可以存放到一个变量中,这个 变量就是指针变量。
总结: 指针变量,用来存放地址的变量。(存放在指针中的值都被当成地址处理)。
在32位操作系统中,地址是4个字节,即指针变量所占内存为4个字节
在64位操作系统中,地址是8个字节,即指针变量所占内存为8个字节
(3)定义
数据类型 * 变量名 = 地址。例:
int a = 10;//在内存中开辟一块空间
int *p = &a;
//这里是对变量a,取出它的地址,可以使用&操作符。
//a变量占用4个字节的空间,这里是将a的4个字节的第一个字节的地址存放在p变量
中,p就是一个之指针变量。
(4)解引用
指针的解引用是指通过指针访问其所指向的对象或变量的值。在C语言和C++中,可以使用解引用操作符 *
来完成这个操作。例:
int x = 10;
int *ptr = &x; // ptr指向x
*ptr = 20; // 解引用ptr,修改x的值为20
printf("Now, the value of x is: %d\n", x); // 输出:Now, the value of x is: 20
总结:指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节)。 比如: char* 的指针解引用就只能访问一个字节,而 int* 的指针的解引用就能访问四个字节。、
(5)指针运算
- 指针+- 整数
对指针进行加法运算会根据指针所指向的数据类型,增加相应字节数。例如,如果一个指针指向一个整型变量,那么对该指针进行加法运算将会增加整型变量所占的字节数。
int arr[5] = {1, 2, 3, 4, 5};
int *ptr = arr; // 指向数组的第一个元素
ptr++; // 指针后移一个元素位置
- 指针-指针
两个指针进行减法运算,其结果是两个指针之间相隔的元素个数或字节数。这种运算通常用于计算数组中两个元素之间的距离或者判断它们在内存中的相对位置。
int arr[5] = {1, 2, 3, 4, 5};
int *ptr1 = &arr[2]; // 指向数组的第三个元素
int *ptr2 = &arr[0]; // 指向数组的第一个元素
int distance = ptr1 - ptr2; // 计算两个指针之间的距离(元素个数)
- 指针的关系运算
常见的有大于、小于、大于等于、小于等于、等于和不等于等关系。这些运算可以用来比较指针所指向的内存地址的大小关系。例如下面比较大小
int arr[5] = {1, 2, 3, 4, 5};
int *ptr1 = &arr[0]; // 指向数组的第一个元素
int *ptr2 = &arr[2]; // 指向数组的第三个元素
if (ptr1 < ptr2) {
// ptr1指向的地址在内存中比ptr2指向的地址小
}
2.数组
(1)概念
数组是一种数据结构,用来存储相同类型的元素的集合。在大多数编程语言中,数组是一个固定大小的连续存储空间,可以通过索引来访问其中的元素。数组的每个元素都具有相同的数据类型,并且在内存中是按顺序排列的。
(2)定义
声明格式如下:
type arrayName[arraySize];
例如声明一个整形数组
int number[5]; //声明一个包含5个整数的数组
int number[5] = {1, 2, 3, 4, 5};//创建一个包含5个整数的数组,并将它们依次初始化为1、2、3、4/5。
(3)索引
索引从0开始,因此第一个元素的索引为0,第二个元素的索引为1,依此类推。例如,访问数组 numbers
中的第三个元素。
numbers[2] = 10; // 给数组的第三个元素赋值为10
(4)二维数组
二维数组是一个表格,其中的每个元素都是一个一维数组。二维数组在编程中常用于表示矩阵、表格或者多维数据。
例如,声明一个包含3行4列的整数二维数组:
int matrix[3][4];
int matrix[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
}; //初始化
matrix[1][2] = 10; // 给第二行第三列的元素赋值为10
3.数组与指针
(1)指针数组
指针数组是一个数组,其中的每个元素都是一个指针。这些指针可以指向不同的数据类型或者相同的数据类型,具体取决于数组的声明方式。指针数组在编程中常用于处理多个数据对象或者实现动态内存分配。
例如,声明一个包含3个整型指针的指针数组:
int *ptrArray[3];
int num1 = 10, num2 = 20, num3 = 30;
int *ptrArray[3] = {&num1, &num2, &num3};
//创建了一个包含3个整型指针的指针数组,并将它们分别初始化为 num1、num2 和 num3 的地址。
(2)数组与指针
数组名表示的是数组首元素的地址。可以把数组名当成地址存放到一个指针中,我们使用指针来访问一个。例如
int arr[] = {1,2,3,4,5,6,7,8,9,0};
int *p = arr; //指针存放数组首元素的地址
int sz = sizeof(arr)/sizeof(arr[0]);
for(i=0; i<sz; i++)
{
printf("&arr[%d] = %p <====> p+%d = %p\n", i, &arr[i], i, p+i);
//printf("%d ", *(p + i));
}
4.结构体
(1)概念
结构体(Struct)是一种用户自定义的数据类型,用于将不同类型的数据组合在一起,形成一个新的数据类型。结构体可以包含多个成员(member),每个成员可以是不同的数据类型,包括基本数据类型(如整型、浮点型等)、数组、指针、甚至其他结构体。
(2)定义
声明格式如下
struct 结构体名称 {
数据类型1 成员1;
数据类型2 成员2;
// 更多成员...
};
例如,定义一个描述学生的结构体:Student
是结构体的名称,包含了三个成员:id
(整型)、name
(字符数组)、GPA
(浮点型)。
struct Student {
int id;
char name[50];
float GPA;
};
(3)使用
结构体的使用包括以下几个方面:
- 声明结构体变量: 使用定义好的结构体作为数据类型来声明变量。例如,
struct Student s1;
声明了一个名为s1
的Student
类型的变量。 - 访问结构体成员: 使用
.
运算符来访问结构体的成员。例如,s1.id = 12345; s1.GPA = 3.8;
分别给s1
的id
和GPA
成员赋值。 - 结构体作为函数参数: 可以将结构体作为函数的参数传递,这样可以方便地传递多个相关的数据。通常可以通过传址或传值的方式传递结构体。
- 结构体指针: 可以使用指向结构体的指针来操作结构体,这样可以在函数间传递结构体并修改其内容,而不需要拷贝整个结构体。指针访问结构体成员时使用箭头运算符
->
。例如,struct Student *ptr = &s1; ptr->id = 54321;
将s1
的id
成员通过指针ptr
进行了修改。