c语言中利用指针给字母编码,C语言指针知识记录

C语言指针知识记录

前言

在学习过程中老是遇到很多坑,或者单纯是自己没掌握好的东西。不记录下来过一段时间又忘了。因此写下来作为记录,希望能帮到后来的朋友爬坑,同时也方便自己以后查阅。如有不正确的地方欢迎指出。

地址

程序的数据是存储在电脑中的虚拟存储器中的。这个虚拟存储器里面有许多单元,每个单元都有自己的标号,也就是这个单元的地址。指针的本质就是某个单元的地址。

比如,int n = 5 ; 声明了一个叫n的变量,并把它的值赋为5。在计算机内部这个值实际是虚拟存储器的某个单元中的,这个单元的地址可以通过取地址符号,&n获得。

其实可以把虚拟内存看成一个很大的数组,指针就是数组的下标。&n就是取存了n的单元的下标。

#include int main(void)

{

char ch = 'a';

int n = 5;

printf("ch 的地址:%p\n",&ch); //ch 的地址:0061FECF

printf("n 的地址:%p\n",&n); //n 的地址:0061FEC8

return 0;

}

指针

指针的本质是某个单元的地址,因此赋值时候,就应该把一个地址赋给它,比如int *p = &n;表示的是申请了一个int类型的指针,这个指针的内容为n的地址。因此,这个指针也就指向了n的。

p是一个指针,*p为指针所指向的内容。

#include int main(void)

{

int n = 5;

int *p = &n;

printf("p 的值:%p\n",p); // p的值:0061FEC8

printf("*p 的值:%d\n",*p); // *p的值:5

return 0;

}

关于指针的最基础的知识就是这些了,更详细更深入的知识可以参考博客: C语言指针详解

下面写一写我在学习中遇到的坑。

1. 字符串常量

先来看一段会报错的代码。原因是 “helloworld” 被存在一个只读的区域中,所以其实是常量,不能被修改。我这里是程序异常终止Process finished with exit code -1073741819 (0xC0000005)。

#include int main(void)

{

int i ;

char *s1 = "helloworld";

s1[0] ='H';

printf("%c",s1[0]);

return 0;

}

解释:

在C语言中 “helloworld” 叫做字符串字面量,也叫字符串常量。“helloworld” 会被编译器编程一个字符数组放在某处,这个数组的长度是 “helloworld” 的长度加1。(字符串末尾有\0)

char *s = “helloworld"含义为:s是一个指针,指向一个字符串常量,这个字符串常量是在编译的时候赋值的,被储存在一个叫"代码段”,这个地方是只读的。

因此char *s = “helloworld” 实际上是 const char *s = “helloworld”

接下来再看一段代码:

#include int main(void)

{

int i ;

char *s1 = "helloWorld";

char *s2 = "helloWorld";

printf("&i = %p\n",&i);

printf("s1 = %p\n",s1);

printf("s2 = %p\n",s2);

return 0;

}

通过以上代码可知,s1,s2因为指向同一个区域,因此相同。并且,s1,s2都比较小,明显和i的地址不在同一块区域。

关于不同变量存储位置详细可以参考博客C/C++程序内存的各种变量存储区域和各个区域详解

2. 用指针代替二位数组

前段时间写了个代码实现矩阵的基本运算。矩阵的数据结构如下。

typedef struct {

double **mat;

int row;

int col;

}Matrix;

用 **mat 代替 mat[MAXN][MAXN] 就能利用malloc开出合适的空间,避免空间浪费。

但由于学艺不精,把自己搞迷糊了,调试了很久才弄对。下面是矩阵初始化函数的代码。

void InitialMatrix(Matrix *T, int row, int col) {

T->row = row;

T->col = col;

T->mat = (double**)malloc(sizeof(double*)*row);

for (int i=0;imat[i] = (double*) malloc(col*sizeof(double ));

}

存储结构即为先申请row个指针,让他们分别指向col个double的空间。

3. 指针代替结构体数组

做大作业学生成绩管理系统,自己做肯定会用链表来存学生信息,但根据题目要求来看,得做成结构体数组的形式,当然还是需要用到指针,不能暴力的就来一个student stu[MAXN] 了。虽说现在的计算机也不差那点空间了,但是该学的知识还是要学好,奈何本人实在太菜,又被卡了很久。

下面是学生信息数据结构。

typedef struct

{

int id;

char name[50];

float chinese;cloat english; float math;float sum;

}student;

下面是题目的主程序。stu是一个指针,学生信息是存在一个指针里的,但给出的学生信息数据结构并不是链表。 ReadStuInfoFromFile ( ) 传入的又是stu这个指针的地址。没办法了,只能在ReadStuInfoFromFile ( ) 做一个结构体数组,然后将stu修改为这个结构体数组的地址。

int main() {

int n, rank, id,i,m;

student *stu =NULL;

n = ReadStuInfoFromFile(filepath,&stu);

PrintStudents(stu, n);

下面是ReadStuInfoFromFile () 的实现。

int ReadStuInfoFromFile(char *filepath,student ** pstu) {

FILE *fp = NULL;

fp = fopen(filepath,"r");

if (fp==NULL) return 0;

int n;

fscanf(fp,"%d",&n);

/* 只关注下面数据结构实现的部分*/

student *stu;

stu = (student*) malloc(n*sizeof(student));

for (int i = 0; i < n ; ++i) {

fscanf(fp,"%d %s %f %f %f",&stu[i].id,stu[i].name,&stu[i].chinese,&stu[i].math,&stu[i].english);

stu[i].sum = stu[i].chinese+stu[i].english+stu[i].math;

}

*pstu = stu;

fclose(fp);

return n;

}

在ReadStuInfoFromFile ( ) 里,stu是一个指针,即stu得到应该是一个地址。

malloc申请了一个大小为 n* sizeof(student) 的空间,是一片可分成 n 份的连续的空间,其实也就是一个产生了一个student类型的数组。这个数组的地址即为这这片空间的首地址。因此stu最后得到的其实就是这片空间的的首地址。

前面说过要将main() 里的stu改为结构体数组的地址。

pstu 是 main() 函数里的stu的地址,因此修改main() 里的stu ,需要通过 *pstu来修改。

因此 *p = stu;

暂时就先写到这里了,以后遇到关于指针的问题再来补充。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值