C语言深度复习【数组和指针】

目录

一.数组和指针

[1.1 数组指针](#1.1 数组指针)

[1.2 指针数组](#1.2 指针数组)

[1.3 函数指针](#1.3 函数指针)

[1.4 const和指针](#1.4 const和指针)

[1.5 sizeof和指针和数组](#1.5 sizeof和指针和数组)

[1.6 strlen和字符数组](#1.6 strlen和字符数组)


一.数组和指针

1.1 数组指针

  • 一个数组指针实际上是指指向数组的指针。当你有一个数组类型作为函数参数时,它在函数内部被当作一个指针来处理。
  • 例如,int (*pArray)[10] 声明了一个指向含有10个整数的数组的指针。
  • 的优先级要高于*号的,所以必须加上()来保证p先和*结合
  • 通常用于函数参数,以传递整个数组。由于数组在函数参数中退化为指针,返回数组的函数可以返回一个数组指针
cpp 复制代码
int arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int (*pArray)[10] = &arr; // pArray是一个指向含有10个整数的数组的指针

1.2 指针数组

  • 一个指针数组是一个数组,其元素是指针。
  • 例如,int *pointerArray[5] 声明了一个包含5个指向整数的指针的数组
  • 当你需要一个可以动态改变其元素的数组时使用,每个元素可以独立地指向不同的数据或内存地址
cpp 复制代码
int numbers[] = {0, 1, 2, 3, 4};
int *pointerArray[] = {&numbers[0], &numbers[1], &numbers[2], &numbers[3], &numbers[4]};

1.3 函数指针

cpp 复制代码
return_type (*pointer_name)(parameter_list);
  • return_type 是函数返回值的数据类型。
  • pointer_name 是指针变量的名称。
  • parameter_list 是函数参数的列表,包括参数的类型和顺序。
cpp 复制代码
#include<stdio.h>

int add(int a, int b)
{
	return a + b;
}

int sub(int a, int b)
{
	return a - b;
}

int main()
{
	int (*function_ptr)(int, int);// 声明一个函数指针
	function_ptr = add;//将函数指针指向 add 函数
	printf("%d\n", function_ptr(3, 5));// 通过函数指针调用 add 函数
	function_ptr = sub;
	printf("%d\n", function_ptr(3, 5));
}

1.4 const和指针

  • const type *ptr; 表示指针指向的数据是常量,但指针本身可以改变。
  • type *const ptr; 表示指针本身是常量,但可以通过指针修改数据。
  • const type *const ptr; 表示指针本身和指向的数据都是常量。
cpp 复制代码
int main()
{
	const int num = 10;
	const int* ptr = &num;
	// *ptr = 20; // 错误:不能通过指向常量的指针修改数据

	int num2 = 10;
	int num3 = 20;
	int* const ptr1 = &num2;
	// ptr1 = &num3; // 错误:不能改变指针的值
	*ptr1 = 30; // 正确:可以通过指针修改数据
	
	const int num4 = 10;
	const int* const ptr2 = &num4;
	// ptr2 = &some_other_int; // 错误:不能改变指针的值
	// *ptr2 = 20; // 错误:不能通过指向常量的指针修改数据
}

1.5 sizeof和指针和数组

  • sizeof 对于数组返回整个数组的大小。
  • sizeof 对于指针返回指针本身的大小。
  • 对于指向数组的指针,sizeof 在编译时返回指针的大小,而在运行时返回数组的大小。
  • sizeof 对于指针数组返回整个指针数组的大小。
cpp 复制代码
void func(int arr[10]) 
{
	printf("%zu\n", sizeof(arr)); // 这里输出的是指针的大小,不是数组的大小
}

int main()
{
	int arr[10];
	printf("%zu\n", sizeof(arr)); // 输出整个数组的大小,这里是 10 个 int 的大小

	func(arr);

	int* p;
	printf("%zu\n", sizeof(p)); // 输出指针的大小,通常是 4 或 8 个字节

	int array[10];
	int(*ptr)[10] = &array;
	printf("%zu\n", sizeof(*ptr)); // 输出数组的大小
	printf("%zu\n", sizeof(ptr));  // 输出指针的大小

	int* arr1[10] ;
	printf("%zu\n", sizeof(arr1)); // 输出指针数组的大小
}

1.6 strlen和字符数组

cpp 复制代码
size_t strlen(const char *str);

strlen 是 C 语言标准库函数,定义在 <string.h> 头文件中,用于计算一个以空字符**'\0' 结尾****的字符串的长度。strlen 函数不计算终止的空字符。**
当您有一个字符数组并且该数组存储了一个字符串时,您可以使用 strlen 来获取字符串的长度。

cpp 复制代码
#include <stdio.h>
#include <string.h>

int main() {
    char myString[] = "Hello, World!";
    size_t length = strlen(myString); // 计算字符串长度,不包括终止的 '\0'
    printf("长度为: %zu\n", length);
    return 0;
}

注意事项:

  • strlen 只能用于以空字符 '\0' 结尾的字符串。如果字符数组中没有空字符,strlen 可能会进入无限循环,因为它会尝试找到字符串的结束标志。
  • strlen 函数的时间复杂度是 O(n),其中 n 是字符串的长度,因为它需要逐个字符检查直到找到空字符。
相关推荐
Scott9999HH3 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
码智社4 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海4 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖5 小时前
JDK 26 新特性详解
java·开发语言
马优晨5 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区7 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大8 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai8 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
এ慕ོ冬℘゜8 小时前
前端基础:什么是时间戳?JS获取时间戳三种方法与实战用途
开发语言·前端·javascript
执明wa8 小时前
LayoutInflater详解: XML是如何变成View的?
android·xml·开发语言·android studio