指针

指针

指针

指针代表着C语言特定的一个强大的特性,同时也是最让我们害怕的。其中一些畏惧和焦虑来自于在C语言中以一种可笑的荒谬的方式来使用。一般的教程和课程值通过提问学生,让学生解读十分怪异的指针语法组合来讲解指针,很少去在实践中去使用指针。你可能已经看到过许多奇异的指针语法(你将会再次看到),但是,指针没有必要必须要用奇异的难以理解的方式去使用。典型的指针是非常容易理解的。

底线是指针允许你动态分配内存块,你将会使用指针去处理变量,而这些变量都是已经在堆中分配过的。(你可以使用指针去处理栈变量,但是大多数情况下是没有必要的)。
最基本的思想是:一个指针是一个特殊的C数据类型,它包括了一个地址,这个地址指向内存中的某个位置。考虑一个指针就像一个箭头,它指向一块内存区域,而这块内存区域就包含着我们比较感兴趣的实际数据。这不像电话号码的概念,也不像房子地址概念。
指针的目的是允许你手动地直接地区访问一块内存。它在strings和structs中大量使用。我们可以想象通过一个地址在许多块内存中找一个函数(例如一个结构体中包括许多东西),这相比于复制内存块谈后通过这个复制的内存块去访问更加高效,这就是所谓的通过调用传递和通过值传递。下面的例子让你更好的理解.

声明一个指针

这里就是如何声明一个指针

#include <stdio.h>

int main(int argc, const char * argv[]) {
int age = 30;
int *p;
p = &age;
printf("age=%d\n",age);

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

printf("p=%d\n",*p);

printf("sizeof(p)=%ld\n",sizeof(p));

*p = 40;
printf("*p=%d\n",*p);

printf("age=%d\n",age);
return 0;
}

输出的结果是:

age=30
p=0x7fff5fbff80c
p=30
sizeof(p)=8
*p=40
age=40

int age = 30这行我们声明了一个int变量age,并且初始化为30,在 p = &age这行,我们声明了一个变量p,它的类型是一个指向int的指针。* 语法是生成一个指针类型去指向另一个类型。通常,你需要声明一个指针去指向一个详细的类型,但是有一个特例就是void指针,它是一个指向未知类型的指针。现在不要担心这种指针。

现在我们有个指针变量p来指向int。到目前为止,它没有指向任何地方。。。我们仅仅声明了一下,想让一个内存空间持有这个指向int的指针。在p = &age,我们给我们的指针p赋值了。我们把另一个变量age的地址赋值给了p。因此现在为止,我们有以下的东西(我们可以在输出中看到):

  • age的值是30
  • p的值是age变量的地址
  • p指向的int有个值30
    在输出的第二行,我们可以看到一个很长的数字字符组合字符,它其实是一个16进制的内存地址。

取指针的值

printf("*p=%d\n", *p);这一行我们可以看到通过之后怎访问一个值用的是 * 语法。因此p是int的一个地址,反之 * p就是指针指向的int的值。访问指针指向的值就叫做取地址值。
在输出中我们可以看到指针的大小事8个字节。请记住,一个字节8位,因此一个4字节的指针可以达到32位。因此32位指针可以允许我们访问4G的内存。如果我们想超过4G,我们就需要一个更大的指针。在64位操作系统中,指针是8位。
注意一下在 * p = 40发生的事情,我们可以看到最后两行的输出值改变成了40,在*p= 40,,这行,我们使用指针取值去设置指针指向的变量的值(这里设置为了40)。既然p指向的是age这个变量,那么我们将会设置age这个值为40。

指针和数组

当我们使用int vec[5]来声明一个数组的时候,后台究竟发生了什么事情呢?其实后台一块内存被分配(在栈中),这块内存足够去容纳5个整型,vec变量就是一个指针,它指向数组的第一个元素,当你使用这种方式时:printf("vec[2]=%d\n",vec[2]);真正发生的事情是C使用指针算法进入数组,通过适当的次数,然后读取内存中的值。因此,如果你vec数组访问第三个元素,你可以使用vec[2],这个时候C语言开始通过vec的指向开始查找,跳过两个数字,然后取到需要的值(vec[2])。
实现这些最直观的方式就是使用malloc(或者calloc())给数组分配内存(这里在堆中分配),然后通过指针算数去读取值。

malloc和calloc和realloc

他们都是一个函数,作用是在运行时间分配内存,malloc()是根据括号内提供的大小去分配,calloc()和malloc()差不多,但是calloc()还把所有的元素初始化为0.clloc()函数有两个参数,一个是元素个数,另一个是每一个元素的大小。
realloc()可以改变内存的大小。
参考自:http://gribblelab.org/CBootcamp/8_Pointers.html

时间: 2024-08-29 12:58:21

指针的相关文章

C语言指针的长度和类型

如果考虑应用程序的兼容性和可移植性,指针的长度就是一个问题,在大部分现代平台上,数据指针的长度通常是一样的,与指针类型无关,尽管C标准没有规定所有类型指针的长度相同,但是通常实际情况就是这样.但是函数指针长度可能与数据指针的长度不同. 指针的长度取决于使用的机器和编译器,例如:在现代windows上,指针是32位或是64位长 测试代码: #include<stdio.h> #include<math.h> #include<stdlib.h> #include<s

指向多维数组的指针变量

问题描述 指向多维数组的指针变量 #include int main() { int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12}; int *p; for(p=a[0];p<a[0]+12;p++) { if((p-a[0])%4==0) printf(" "); printf("%4d",*p); } } 把for(p=a[0];p<a[0]+12;p++)改成for(p=a[0];p<a+3;p++)为什么是正确的

指针-c语言中字符数组初始化问题

问题描述 c语言中字符数组初始化问题 字符数组初始化1: char str[]=""123"";//不报错2: char str[4]; str=""123"";//不能将const char[4] to char[4]字符指针初始化1: char *str=""123"";//不报错2: char *str; str=""123"";//不报错求

Ubuntu系统鼠标指针上下跳动该怎么办?

  可能不少网友都遇到了这个问题,就是鼠标指针一闪一闪的,一会而消失一会儿出现的样子.这个经验告诉你怎么做可以消除这个问题,保证99.5%有效率. 1.打开系统设置 2.点击显示 3.然后切换到"未知显示器",你会发现未知显示器是开启的状态 4.现在你只需要把未知显示器设置为"关闭"状态就可以了.然后点击应用,系统会提示你是否保存设置,注意别点错了.

C#定义鼠标指针形状

在Windows应用程序中,通过设置控件的Cursor属性可以定义鼠标的显示形状.控件(如Button控件)的Cursor属性用于设置鼠标指针的类型,默认为Default. 语法: public virtual Cursor Cursor { get; set; } 属性值:一个Cursor,表示当鼠标指针位于控件上时显示的光标. Cursor:是一个值,该属性值如表所示. 表 Cursor属性的值 值 说明 AppStarting 获取在应用程序启动时显示的光标 Arrow 获取箭头光标 Cr

fgets函数执行完成后,文件指针如何移动?

用fgets执行之后,读取了文件中的一行,这时文件位置指针是自动指向文件的下一行的开头吗,还是指向当前行的结尾?如果一行的字符串没读取完会怎样? 实例结果: 如果一行的字符串没读取完会,下一次会接着上一次读取: 如果读完了,直接从下一行开头开始. 百度百科: 从文件结构体指针stream中读取数据,每次读取一行. 读取的数据保存在buf指向的字符数组中,每次最多读取bufsize-1个字符(第bufsize个字符赋'\0'),如果文件中的该行,不足bufsize个字符,则读完该行就结束. 如若该

彻底搞定C语言指针 第六篇

指向另一指针的指针 一.针概念: 早在本系列第二篇中我就对指针的实质进行了阐述 .今天我们又要学习一个叫做指向另一指针地址的指针.让我们先回顾一下指针的概念吧! 当我 们程序如下申明变量: short int i: char a: short int * pi: 程序会 在内存某地址空间上为各变量开辟空间,如下图所示. 内存地址→6 7 8 9 10 11 12 13 14 15 ------------------- --------------------------------------

c语言先用scanf初始化了一个字符指针,之后再定义字符数组出现内存不可读,在线等,急求

问题描述 c语言先用scanf初始化了一个字符指针,之后再定义字符数组出现内存不可读,在线等,急求 #include #include int main() { char*s; scanf("%s",s); //printf("%sn",s); //int n = strlen(s); //printf("%dn",n); char ret[56]; return 0; } 解决方案 s只是指针变量,没有分配内存 char*s; s = mall

一个关于指针和数组的问题

问题描述 一个关于指针和数组的问题 #define _CRT_SECURE_NO_WARNINGS#include ""stdlib.h""#include ""stdio.h""#include ""string.h"" int main(){ char buf1[100] = { 0 }; char buf2[100] = { 0 }; char *p1 = buf1; char *

ios-MFMailViewController选择指针

问题描述 MFMailViewController选择指针 使用xcode的MFMailViewController .设置了接收器. [mailComposer setToRecipients:emailAddresses]; 需要将接收器设置给NSArray中的指针,不知道应该怎么实现? 具体一点就是,需要根据用户的Email或者其他信息来访问一个人