我对指针和数组的理解
指针
某社团的
上古学长曾经说过C语言中只有两种类型变量,值和指针。起初我还不太理解学长的意思,直到现在我才渐渐有一点明悟。
即是这两种类型
AnyType // 创建一个该类型的变量
AnyType * // 创建一个指针 这个指针指向的值是一个该类型的变量
指针也是变量,它本身也有值,它保存了它所指向地址的值。由此,可以通过指针间接修改变量的值,读取变量的值。
数组
数组可以理解为相邻的几块内存,无论是几维数组,都只是系统给出的假像,实际它还是线性排布的。
int arr[10] // 一个简单的数组 包含10个长度为一个sizeof(int)的空间
数组和指针的联系还是十分紧密的,例如 这个arr[0]
在引用时实际上可以写为 (arr + 0)
这也解释了为什么数组会从0开始。
指针数组和数组指针
- 指针数组:首先它是一个数组,数组的元素都是指针,数组占多少个字节由数组本身决定。它是“储存指针的数组”的简称。
- 数组指针:首先它是一个指针,它指向一个数组。它是“指向数组的指针”的简称。
其实只要分清了这两个概念就不会在搞混了。
指针的数组问题归档
修改const数组
题目要求修改
```strcmp_fix(const char * s1, const char * s2) ``
中所指向的 arr1,arr2 字符串 可是这个函数中的变量是 const 类型的指针,就是说 你无法通过 S1 和 S2 来改变 arr1/2 中的值。 由此 我猜想 const 的机制。 1. 仅通过禁止访问 const * 的变量所解引用的变量 的值。 2. 通过禁止修改 const*的值。
总体代码如下
#include <stdio.h>
#include <stdlib.h>
#define lenth 20
void strcmp_fix(const char *s1, const char *s2);
int main(void)
{
char arr_1[lenth], arr_2[lenth]; // 输入两个带
测试的字符串
printf("please enter your first arr \n");
scanf_s("%s", arr_1, lenth);
printf("enter your next arr\n");
scanf_s("%s", arr_2, lenth);
strcmp_fix(arr_1, arr_2);
printf("\n%s\n", arr_1);
printf("\n%s\n", arr_2);
system("pause");
}
void strcmp_fix(const char *s1, const char *s2)
{
char *sp1, *sp2; // sp1 sp2 是值等于 const*
变量的指针 我推测 const 限定符只能保护 S1 / 本身
sp1 = s1; // sp1/2 的值和 s1/2 一致
sp2 = s2;
(*sp1)++;
(*sp2)++; // 使每一个字符串第一个字符的值加 1
}
运行结果如下:
成功的修改了 原字符串的首元素的值。
机制分析
我先尝试对 const 解引用后的变量进行一些操作
将代码变为
(*s1)++;
直接报错
说明了 const 类型是不可修改的左值
说明猜想 通过禁止尝试修改 const*的值 是正确的
猜想 通过禁止访问 const * 的变量所解引用的变量的值 我们把上面的代码 改变一下 *s1++; 即是先解引用 s1 所指向的值 arr1++ 系统并没有给出报错,但是对应的,字符串的值也没 有改变。无法通过 s1 间接修改,但是…… 不妨看一下这几个变量的关系
不难发现 虽然不能通过 s1 修改 但是 可以通过 sp1 将 s1 的值提取出来。修改字符串只需要它的地址信息 即可。 Const* 类型并不能保证 它所指向的变量不被修改。
类型转换
题目要求是将任何类型的变量以十六进制(内存中实际的)的方式打印出来。
#include<stdio.h>
#include <stdlib.h>
typedef unsigned char *byte_pointer; // 比特位指针
void show_the_bit(byte_pointer byte_start, size_t lenth); // 将浮点数改变成
int main(void) {
float enter_num = 0.0;
scanf_s("%f", &enter_num); // 修改此处可以转换不同的类型
show_the_bit((byte_pointer)&enter_num, sizeof(float)); // 利用强制类型转换 跳过检查
system("pause");
}
void show_the_bit(byte_pointer start, size_t lenth)
{
for (size_t i = 1; i < lenth; i++)
printf("%.2x", start[i++]);
}
独特的空指针
#include<stdio.h> //中是这样定义的
#if !defined(NULL) && defined(__NEEDS_NULL)
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant//
一个整数常量表达式的值0,或这样的表达式类型void *,称为空指针常量
这里告诉我们:0、0L、’\0’、3 - 3、0 * 17 (它们都是“integer constant expression”)以及 (void)0 (tyc: 我觉得(void)0应该算是一个空指针吧,更恰当一点)等都是空指针常量(注意 (char) 0 不叫空指针常量,只是一个空指针值)。至于系统选取哪种形式作为空指针常量使用,则是实现相关的。
一般的 C 系统选择 (void)0 或者 0 的居多(也有个别的选择 0L); 至于 C++ 系统,由于存在严格的类型转化的要求,void* 不能象 C 中那样自由转换为其它指针类型,所以通常选 0 作为空指针常量(tyc: C++标准推荐),而不选择 (void*)0。