C语言学习之路——指针初探

进来学习C语言碰到了指针,着实学了一段时间,搞不出个头绪,今日感觉有些眉目,来此做个记录,也望能给困顿的人一起分享下感悟。

学习指针还要从变量,数组,函数的定义这些基础说起。

如:int a=10;

int a[]={1,2,3,4};

int max (int x,int y)

{

....

}

学习C语言指针我想指针变量的定义就不用说了吧。

先上一个例子然后再给大家一一展开进行讲述。

#include<stdio.h>
int main()
{
int a;
scanf("%d",&a);
printf("a=%d",a);
}

哈哈,大家是不是嫌这个例子太简单了,哈哈,看官还请休要怪罪,就是这么一个小小的例子就是学习指针的切入点,scanf("%d",&a),这句是什么意思,我想大家肯定已经知道了就是从键盘输入中读取一个整数,然后赋值给a,不错,就是如此,但是为什么&a呢,声明变量a,系统在空间中开辟一个整数空间,具体占据多少字节要根据编译器和系统来定,&a,表示的就是这个地址空间的地址,scanf("%d",&a);其实是将读取进来的整数放进了该地址空间内,a只不过是该地址空间的一个比较友好的代称。指针的名字也是一种友好的代称,只不过这种代称指向的是地址而已。那既然&a表示的是变量a的地址,那一定可以赋值给指针变量喽。我们对上面的例子稍作修改。

#include<stdio.h>
int main()
{
int a;
int * p=&a;
scanf("%d",p);
printf("a=%d",* p);
}

这段代码与上面多讲的例子运行结果一模一样,p就是指针变量,把a的地址赋值给p,那p所代表的也就是a的地址空间了。将所读进来的整数放进p,还是放进&a,其实是同一个地方,只是名字不同而已。现在想来,指针的一切其实都是在这个例子上的变通。

int a;开辟的是一个单独的地址空间,那数组啦,函数啦,字符串啦那开辟的就是一串连续的地址空间。而那些友好的名字表达的就是地址的初始值而已。

来接着给大家上栗子:

#include<stdio.h>
int main()
{
int a[]={1,2,3,4,5};
int * p=a;
printf("a[1]=%d\n",* (p+1));
}
大家可以试一下看一下会有怎样的输出,我可以偷偷的告诉大家是‘2’,哈哈。为何呢?上面说了a代表的其实是一个数组的首地址,把首地址赋值给指针变量p,那么p+1表示自然就是a[1]地址,那为何是+1呢?哈哈,这个是你告诉编译器的啊,把指针变量声明为int型,那自然1代表的就是一个int型数字所占的一个地址空间啦。

大家慢慢消化练习,接着给大家再上一个栗子,指针指向多维数组,说实话这个确实使我懵圈了好长一段时间,多维数组,数组名表示的也是一个起始地址,不过他怪就怪在他的多维度。

还是先个大家上个例子。

#include<stdio.h>
int main()
{
int a[][3]={1,2,3,4,5,6,7,8,9};
int * p=a[0];
int (* p1)[3]=a;
printf("a[1][1]=%d\n",* (p+4));
printf("a[1][1]=%d\n",* (* (p1+1)+1));
}

这个大家可能猜到会输出什么呀,我再次偷偷的告诉大家输出两个5,不知道你看到这个例子有没有懵,反正当时我是懵了,不急,一点点 把它拨开比较差异自然也就懂了,首先两个指针的赋值,其实这里两个赋值是一样一样的,a,a[0],所表示的都是这个二维数组的首地址,只不过这两个指针不同,所以在用起来也就有一定的差异性,指针p仅仅是一个地址,一维的,程序在存储二维数组时其实也是按序存储的,也是一个一维的数据,所以指针p代表的是这个数组的起始地址,那么+1自然也就是依次往后进行遍历了,如果我把指针p的定义成 int * p=a[1],那程序该作何输出呢,哈哈这个我就不跟大家说了,可以自己进行操作,看一下,然后再进行分析为何,在这里提醒大家一点,a[0]表示的是第0行的首地址,那么a[1]表示的自然就是第一行的首地址啦,就到这,大家自己思考吧。然后是指针p1的赋值,后面有个[3],咦。。。这可了不得,它想干嘛,哈哈,它不想干嘛,它是觉得它能力大,想多分担点,它告诉编译系统说,我可以一下子存放三个地址,那它也就是个二维的概念啦,正好和咱们定义的二维数组一样,* (p1+1)表示就是第1行的首地址,然后再+1 (* (p1+1)+1),就是在这个一维数组中往后遍历一个啦,也就是第一行第一个元素的值(从0开始数)。这个地方我觉得不好理解消化,还是多做些练习慢慢思忖才能领悟。

再给大家上个栗子:

#include<stdio.h>
int main()
{
char * a[3]={"good study","day day up","c program"};
printf("a[1]=%s\n",a[1]);
}

这个会输出什么呢?这个例子可以体现指针数组的灵活之处,它可以存放长短不一的数据,其实表面看来它存放的是长短不一的数据,但其实它存放的是这些长短不一数据的首地址,大家请看:

#include<stdio.h>
int main()
{
char str[]="good good study";
printf("str=%s\n",str);
}

大家明白了这个也就知道上面的指针数组是怎么一回事了,
char * a[3]={"good study","day day up","c program"};其实是str1[]="good good study",str2[]="day day up",str3[]="c program",char * a[3]={str1,str2,str3},这些操作的集合。指针数组这样分开来看也就没那么复杂啦。

再来一个例子,哈哈,这个例子不得了,我觉的这个例子是最体现指针类型灵活性的地方。

#include<stdio.h>
int max(int x,int y)
{if (x>y) return x;
else return y;
}

int min(int x,int y)
{
if (x>y) return y;
else return x;
}

int fun(int x,int y,int (* p)(int a,int b))
{
int result;
result=(* p)(x,y);
printf("result=%d\n",result);
}

int main()
{
int max(int x,int y);int min(int x,int y);int fun(int x,int y,int (* p)(int a,int b));
int x,y,i;
scanf("%d %d",&x,&y);
printf("choice the fun:\n1:max\n2:min\n");
scanf("%d",&i);
if (i==1) fun(x,y,max);
else fun(x,y,min);
return 0;
}

这个例子比较长但是很简单,大家耐心看肯定看得懂,我在此想说的是,函数在程序中也是一个连续的地址空间所以也可以用指针变量进行表示。

(stdlib.h  void * malloc(unsigned int size);void * calloc(unsigned n,unsigned size);void free(void * p);

main函数原型int main(int argc,char * argv[]))这个是我自己用来做记录用的大家不用留意。

在下初学C语言对很多东西理解不深,写博客一是自己记录,另一个也是希望能帮到学习中困顿的人。大家发现纰漏与错误可以直接与QQ练习(2479630319)。

时间: 2024-08-03 11:14:28

C语言学习之路——指针初探的相关文章

C语言学习之路

C语言学习之路之环境准备 Hello,大家好,我的专业是软件工程,自从大一的时候,和很多人一样,在懵懂中学习了C语言~哈,不过呢,这门语言是真的很基础,也很重要!所以呢,如果是想要在IT行业大显身手的话,就必须对这门语言有所了解.那么,开始我们的探索之路吧,GO~ 工欲善其事,必先利其器!要学好这门语言,我们需要几个工具:一,是一本参考书,本人推荐使用<C Primer Plus>这本书,个人觉得这本书写的很好,推荐大家入门使用,还有一本书是<深入理解C指针>:二,是一款好的编译器

我的C语言学习之路——初装Linux(双系统模式)

我的C语言学习之路--初装Linux(双系统模式) 第一次听说Linux是在微软公布不再维护WindowXP系统,当时打开头条网,Linux几乎占据了头条,好奇之下,百度了Linux(Linux操作系统是UNIX操作系统的一种克隆系统,它诞生于1991 年的 [Linux桌面] 10 月5 日(这是第一次正式向外公布的时间)). 第二次听说Linux是在程序员联盟(微信公众号:programmerLeague)   讨论,这也是我真正接触Linux的时候.作为一个编程初学者,对一切有利于编译的软

IOS学习之路-- 指针&amp;宏函数

如果*p被()包住,说明指针变量p将来指向的是函数 //声明一个指针变量 //int (*p)(int, int) = sum; int (*p)(int, int); p = sum; // 如果*p被()包住,说明指针变量p将来指向的是函数 // 最左边的void说明p指向的函数没有返回值 // 最右边的()说明p指向的函数没有形参 void (*p)(); // 函数名test就是test函数的地址 // 将test函数的地址赋值给了指针变量p // 指针变量p成功指向了test函数 p

《C语言学习笔记》指针数组及其应用

C语言中,最灵活但又容易出错的莫过于指针了.而指针数组,是在C中很常见的一个应用.指针数组的意思是说,这个数组存储的所有对象都为指针.除了存储对象为指针,即一个地址外,其它操作和普通数组完全一样. 1 #include <stdion.h> 2 3 int main() { 4 int i; 5 char *name[] = {"BASIC", "FORTRAN", "C++", "Pascal", "C

c语言学习之路提升

这几天 把C语言的基础学习了 在网上查了查 想要提升自己 还要学习 数据结构和算法 从明天 开始 我将会 继续学习 c 语言的数据结构 和算法

C语言学习笔记-8.指针

一.什么是指针 1.指针是存放另一个变量内存地址的变量 指针型变量的长度为4个字节,32位 2.宏定义NULL,表示0 良好的编程习惯:暂时不使用指针时,将其值设为NULL 3.指针定义后,若未被初始化,则其值为0xCCCCCCCC(Visual Studio中) 若访问此地址,则程序崩溃 4.指针作用:对主函数中实参变量值进行修改 例:void get(int *input) { scanf(“%d”, input);             //注意:不能写成&input } 二.指针与数组

C语言学习之路(1)

学习C语言后我以为我就可以永久的告别单引号了,哎学习还不到一周就碰到了C语言中用单引号的情况,着实一惊. for(i=0;* (p+i)!='\0';i++) * (q+i)=* (p+i); * (q+i)='\0' 刚开始我用的是双引号 for(i=0;* (p+i)!="\0";i++) * (q+i)=* (p+i); * (q+i)="\0" 程序一运行,呵,蹦出个段错误,天哪,我学习C语言还不到一周就让我碰到了段错误,我这是造的什么孽啊,后来左思右想(看

C语言学习019:函数指针

在C语言中,函数名也是指针变量,比如创建了一个add(int n,int m)的函数的同时也创建了一个名为add的指针变量,因此我们可以把函数指针当作一种类型为它赋值.当作参数传递等操作 C语言创建函数指针的公式: 返回类型 (*指针变量)(参数类型) 1 #include <stdio.h> 2 3 int add(int n,int m){ 4 return n+m; 5 } 6 7 int sub(int n,int m){ 8 return n-m; 9 } 10 11 int mai

C语言学习笔记(六) 指针和数组

使用C语言就必然会使用到指针和数组.看下面的代码: int main(int argc, char** argv){     int a[4] = {1,3,5,7};     int *p = a;     int i;     for (i=0; i<4;i++){         printf("i=%d, p[i]=%d, *(p+i)=%d, a[i]=%d, *(a+i)=%d\n",                 i, p[i], *(p+i), a[i], *(