您的位置:首页 > 健康 > 美食 > C语言基础(十一)

C语言基础(十一)

2024/12/21 20:08:51 来源:https://blog.csdn.net/wehpd/article/details/141437610  浏览:    关键词:C语言基础(十一)

1、指针:

C语言中的指针是一种非常重要的数据类型,可以直接访问和操作内存地址。指针存储变量的内存地址,而不是变量的值本身。通过使用指针,可以灵活地控制数据的存储和访问,实现复杂的数据结构如链表、树。

定义指针:
在C语言中,指针是通过在变量类型前加上星号(*)定义的。例如,int *ptr; 表示 ptr 是一个指向 int 类型数据的指针。

初始化指针:
使用指针之前,需要将其初始化为某个变量的地址或 NULL(表示指针不指向任何有效地址)。
例如,int var = 10; int *ptr = &var; ,&var 是取地址运算符,获取 var 的地址,并将其赋值给 ptr。

通过指针访问数据:
通过解引用指针(在指针前加星号),可以访问指针所指向的数据。例如,*ptr = 20; 将 var 的值修改为 20。

指针的算术运算:
指针的算术运算主要是指针的加减运算,以指针指向的数据类型的大小为单位进行。
例如,如果 ptr 是指向 int 的指针,ptr+1 将使 ptr 指向下一个 int 类型的存储位置。

指针的关系运算:
可以比较两个指针是否相等或不等,以及它们之间的顺序关系(前提是两个指针指向同一个数组的元素或指向数组之后的位置)。

指针的用途:
动态内存分配:通过 malloc、calloc 和 realloc 等函数,可以在堆(heap)上动态地分配内存,这些函数返回指向分配的内存的指针。

数组和字符串的访问:
在C语言中,数组名实际上是数组首元素的地址,因此可以使用指针遍历数组或字符串。

函数参数:
通过指针,可以将变量的地址传递给函数,允许函数修改传递给它的参数的值。

实现复杂数据结构:
如链表、树、图等,这些数据结构中的元素通常通过指针相互连接。

指针在使用前必须初始化,否则它们可能指向不确定的内存位置,导致程序崩溃或不可预测的行为。
指针运算时不要越界,即不要访问指针未指向的内存区域。
使用完动态分配的内存后,应通过 free 函数释放,以避免内存泄漏。
 

2、指针变量:

指针变量在C语言中是一种特殊的变量类型,用于存储内存地址而不是直接存储数据值。通过使用指针变量,程序可以间接地访问和操作存储在内存中的数据。指针变量提供了一种强大的机制管理内存,特别是在需要动态内存分配、数据结构操作或系统级编程时。

指针变量的定义
指针变量的定义包括指定指针所指向的数据类型。例如:int *ptr; 定义一个名为 ptr 的指针变量,它指向一个整型(int)数据。* 表示 ptr 是一个指针,而 int 指定了指针所指向的数据类型。

指针变量的赋值
指针变量可以被赋予两个类型的值:

地址:指针最常见的用途是存储某个变量的地址。通过取地址操作符 & 实现,例如 :ptr = &a; 将变量 a 的地址赋给指针 ptr。
另一个指针:指针也可以被赋予另一个同类型指针的值,从而实现指针的传递或赋值。

指针变量的间接访问
指针变量的主要操作是间接访问,即访问指针所指向的内存位置的值。通过解引用操作符 * 实现,例如: *ptr 表示访问 ptr 所指向的值。

指针变量的运算
指针变量支持几种特殊的运算,主要是指针算术运算:

指针加减:指针可以进行加减运算,但加减的不是指针本身的值,而是指针所指向类型的大小。例如,对于指向整型的指针 int *ptr,ptr + 1 实际上是将 ptr 的值增加了一个整型的大小(通常是4或8个字节,取决于编译器和平台)。


指针比较:两个指针可以进行比较运算,以检查它们是否指向内存中的相同位置或相对位置。

指针必须被初始化后才能使用,以避免指向不确定的内存位置。
指针解引用时,必须确保指针指向了一个有效的内存位置,否则可能会导致未定义行为,包括程序崩溃。
指针运算时,要注意指针所指向的数据类型,因为不同的数据类型在内存中占用的空间大小是不同的。

测试代码1:

#include "date.h"
#include <stdio.h>  
int main() {  int time = getTime();int var = 10; // 定义一个整型变量var  int *ptr; // 定义一个指向整型的指针ptr  // 将指针ptr指向var的地址  ptr = &var;  // 打印var的地址 // %p 是打印指针(即地址)的格式说明符   printf("The address of var is: %p\n", &var);  // 打印var的地址,将 &var 强转换为 (void*) printf("The address of var is: %p\n", (void*)&var);  // 通过ptr打印var的地址(因为ptr已经存储了var的地址)  printf("The address of var through ptr is: %p\n", ptr);  // 通过ptr打印var的地址(因为ptr已经存储了var的地址),强转换为 (void*) printf("The address of var through ptr is: %p\n", (void*)ptr);  return 0;  
}

运行结果如下:

 

测试代码2:

#include "date.h" 
#include <stdio.h>  
//指针的访问 
int main() {  int time = getTime();int value = 10; // 定义一个整型变量value,并初始化为10  int *ptr; // 定义一个指向整型的指针ptr  // 将ptr指向value的地址  ptr = &value;  // 通过指针直接访问value的值,并打印出来// *ptr 表示直接访问 ptr 指针所指向的内存地址中的值。  printf("The value of value through pointer is: %d\n", *ptr);  // 地址是这个 printf("The address is: %d\n", ptr);  // 通过指针直接修改value的值  *ptr = 20;  // value的值已经被修改  printf("The new value of value is: %d\n", value);  return 0;  
}

运行结果如下:

 

测试代码3:

#include "date.h" 
#include <stdio.h>  int main() {  int tiem = getTime();// int 类型  int intVar = 10;  int *ptrInt = &intVar;  printf("The value of intVar through ptrInt: %d\n", *ptrInt);  // char 类型(使用字符串)  char str[] = "Hello, World!";  char *ptrChar = str;  printf("The first character of the string: %c\n", *ptrChar);  // 遍历字符串(指针运算)  while (*ptrChar != '\0') {  printf("%c", *ptrChar);  ptrChar++; // 指针运算:移动到字符串的下一个字符  }  printf("\n");  // float 类型 float floatVar = 3.14f;  float *ptrFloat = &floatVar;  printf("The value of floatVar through ptrFloat: %f\n", *ptrFloat);  // float数组,指针的算术运算  float floatArr[] = {1.1f, 2.2f, 3.3f};  float *ptrFloatArr = floatArr;  printf("The first element of floatArr: %f\n", *ptrFloatArr);  ptrFloatArr++; // 指针运算:移动到数组的下一个元素  printf("The second element of floatArr: %f\n", *ptrFloatArr);  return 0;  
}

运行结果如下:

 

测试代码4:

#include "date.h" 
#include <stdio.h>  int main() {  int time = getTime();int a = 10; // 定义一个整型变量a  int b = 20; // 定义一个整型变量b  int *ptrA = &a; // 创建一个指向a的指针ptrA  int *ptrB = &b; // 创建一个指向b的指针ptrB  // 输出a和b的地址  printf("Address of a: %p\n", (void *)&a);  printf("Address of b: %p\n", (void *)&b);  // 比较ptrA和ptrB(即a和b的地址)是否相同  if (ptrA == ptrB) {  printf("Addresses of a and b are the same.\n");  } else {  printf("Addresses of a and b are different.\n");  }  // 大多数情况下,a和b会被分配在栈上的不同位置,  // 通过某种方式(如数组元素),让它们共享相同的内存地址,比较就会返回true。    // 使用数组:  int arr[2] = {10, 20};  int *ptrArrA = &arr[0]; // 指向arr的第一个元素  int *ptrArrB = &arr[1]; // 指向arr的第二个元素  // 比较ptrArrA和ptrArrB(即arr[0]和arr[1]的地址)是否相同  // 比较两个数组元素的地址,当然不同。  if (ptrArrA == ptrArrB) {  printf("Addresses of arr[0] and arr[1] are the same. (This will not happen.)\n");  } else {  printf("Addresses of arr[0] and arr[1] are different.\n");  }  // 比较&arr[0]和&arr[0],则相同 if (&arr[0] == ptrArrA) {  printf("Addresses of &arr[0] and ptrArrA are the same.\n");  }  return 0;  
}

运行结果如下:

 

 

 

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com