C 指针&&表达式&&常量

一、指针


在计算机语言中,由于通过地址能找到所需的变量,可以说地址指向该变量单元,因此把地址形象的称为‘指针’,意思是能通过它来找到以它为地址的内存单元。

1.1、指针&&变量

指针变量与普通变量一样,使用之前不仅要定义说明而且必须要赋具体的值,未经赋值的指针变量不能使用;可以对指针变量初始化为NULL,但是不能对值为NULL的指针变量解引用。

如下定义一个指针变量p指向a,这样就可以通过p访问a并对a进行操作。

int a=0;
int *p=NULL;
p=&a;
*p=10;

指针变量有很多类型,比如int *、char*、float*、void*等等。每种类型的指针可以访问的内存大小不同,如果要访问int类型数据只能使用int*类型指针,以此类推。

void*类型指针,不能对该类型指针进行算法操作,如++和解引用,这是因为void*指向的内存的大小不确定。既然这样,那么void*类型指针到底有什么用呢?

在某些时候,为了提高效率,我们需要一个函数既可以处理int类型,又可以处理char类型,还可以处理其它类型数据,这个时候void*类型就非常有必要了。典型的如内存操作函数。

void * memcpy(void *dest, const void *src, size_t count);

#include <stdio.h>
#include <stdlib.h>

void*my_memcpy(void*dest, void const*src, size_t count)
{
  char*pdest = (char*)dest;
  char*psrc = (char*)src;
  while (count--)
  {
*pdest++ = *psrc++;
  }
  return dest;
}
int main()
{
  int i = 0;
  int arr[20] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
  my_memcpy(arr + 3, arr, 16);
  for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
  {
printf("%d  ", arr[i]);
  }
  printf("\n");
  system("pause");
  return 0;
}

上述代码可以实现数组的移动,移动大小以字节来记。但是memcpy()不处理内存重叠的情况,如果想处理内存重叠应该使用memmove().

上述内容使用的都是一级指针变量,其实还有二级、三级等等指针变量。我们现来看一下二级指针变量,其它以此类推。

int a=10;
int *pa=&a;
int *ppa=&pa;

指针变量ppa就是一个二级指针变量。上述代码形成的指向关系如下图所示:

变量pa保存的是a的地址,变量ppa保存的是pa的地址;我们可以通过*pa来访问a,同样我们可以通过*ppa来访问pa,那么我们就可以通过 **ppa访问a。也就是说 **ppa就是a,我们可以通过它来操作a。

1.2、指针&&常量

一个常量的地址没有任何意义,我们要讨论的是const修饰的指针。const修饰的指针变量时,这个指针变量便具有了常属性。

1.2.1常量指针

int main()
{
    int a=10;
    int const *pa=&a;//pa指向的内容不可改
    const int *pa=&a; //const放到int左边和右边修饰的都是*pa
    return 0
}

pa是一个常量指针,const限制了通过这个指针修改变量的值,如果对pa进行 *pa=20;操作,这时编译器会报错,因为const修饰*pa

但是,这并不意味着a不可改,只是不能通过*pa来改而已。我们可以进行如下操作来修改a的值。

int *p=&a;
*p=20;

1.2.2指针常量

int main()
{
    int b=10;
    int *const pb=&b;
    return 0;
}

pb是一个指针常量,指针常量的值是指针,这个值因为是常量,所以它不能被修改.此时pb是一个指针常量,不能在指向其它的变量。如进行以下操作是非法的。

int _b=15;
pb=&_b;

虽然pb不可改,并不是说pb指向的内容不可改,如*pb=30;这是可以的。

const 修饰的局部变量仅仅是语法上不可改,其实通过其它变量可以将pb的值改掉,一个指向pb的二级指针,如:

int *ppb=&pb;
*ppb=(int*)0x0018ff44;

但是,要注意的是const修饰的全局变量,不管通过什么方法都不可改。因为const修饰的全局变量被存到了只读数据区。

1.2.3指向常量的指针常量

int main()
{
    int c=10;
    const int *const pc=&c;
    return 0;
}

pc是一个指向常量的指针常量,pc是指针常量,指向的内容也是一个常量,即pc不可改,*pc也不可改。 同样这些并不意味着c的值不可改,只是不能通过*pc来改而已;pc不可改也仅仅是语法上的不可改,如想修改请参照1.2.2。

1.3、指针表达式与运算


不进行运算的指针变量是没有太大的意义的,要使用指针变量进行运算就要知道指针运算的结果和表达式的值。如下所示:

char ch=‘a‘;
char cp=&ch;

1.4、使用指针注意事项


  • 不能对一个未初始化的指针解引用;
  • 不能对一个NULL指针进行解引用;
  • 不能向函数传递NULL指针;
  • 不能对void*类型指针++和解引用;

C 指针&&表达式&&常量

时间: 2024-12-18 18:41:03

C 指针&&表达式&&常量的相关文章

1.枚举类型、声明指针、常量、存储类型、运算符优先级记忆

原文:1.枚举类型.声明指针.常量.存储类型.运算符优先级记忆 1.枚举类型 枚举(enumerated)类型就是指它的值为符号常量而不是字面值的类型,以下面的这种形式来声明:enum   Jar_Type {CUP,PINT,GALLON,OUART}; 这条语句声明了一个类型,称为 Jar_Type.而enum  {CUP,PINT,GALLON,OUART}; 这条语句声明表示这种类型的变量以整型的方式存储,这些符号名的实际值都是整型值.这里CUP是0,PINT是1,以此类推.下面看一下一

C语言中,为什么指针表达式的值+1.对应的地址值却+4?/为什么两个数组元素的地址相减之差不为地址之差?

在C语言中,我们常常用到的一个运算是让某个变量的值+1. 例如 M = M + 1. 而在实际运用中,我们发现 对于指针进行+1运算,算出来的结果是+4. 如下图 图中我们定义的 变量M 和指针Matrix如下: int M = 3; int* Matrix = {1,2,3}; 可以看到,对于M和 Matrix ,+1运算的效果是不同的. 这个差异是因为C语言的标准中规定了 加法与减法运算对于地址的操作和对于值的操作是不同的,如下文中粗体所示: C89 3.3.6 Additive opera

C语言提高之——指针表达式

在理解指针表达式之前先有一个概念就是"左值"和"右值",对于左值就是可以出现在赋值符号左边的东西,右值就是那些可以出现在赋值符号右边的东西.进一步抽象可以这样理解:左值应该可以作为一个地址空间用来存放一个值,而右值可以作为一个值来处理,当然需要说明的是有些是既可以作为左值也可以作为右值的,例如:定义a为一个指针指向b,那么*a既可以作为一个右值即地址b中存放的数据,也可以作为一个左值即表示b的地址.其实说到这里就已经说明了一个简单的指针表达式了,那就是:*a.下边就

C指针解析 ------ 指针表达式

本文是自己学习所做笔记,欢迎转载,但请注明出处:http://blog.csdn.net/jesson20121020 所谓的指针表达式是指一个表达式,其结果是一个指针. 例1. int  a,b; int array[20]; int *p; p = &a;             //&a 就是一个指针表达式,因为&a的结果就是一个指针. int **q = &p;     //&p也是一个指针表达式. *q = &b;            //*p和

10深入理解C指针之---指针和常量

该系列文章源于<深入理解C指针>的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教. 指针作为C语言的左膀右臂,使用方便,修改容易,引用数据快速都是很有前景的应用.C语言中常量是值不能改变的量,由于在某些应用中,想要阻止没有授权的数据的修改时,就需要将指针和常量结合起来. 一.指向常量的非常量指针:指针值可以改变,但是指针解引用值不能改变 1.特征: 1).提供一种可移植的方式来声明与系统中可寻址的内存区域一致的长度 2).用作sizeof操作符的返回值的类型 3).用作内存相

c语言结构体&amp;常指针和常量指针的区别

结构体: 关系密切但数据类型不尽相同, 常指针和常量指针的区别: char * const cp : 定义一个指向字符的指针常数,即const指针,常指针. const char* p : 定义一个指向字符常数的指针,即常量指针. char const* p : 等同于const char* p[2]. 理解:const char *p; 常量指针,指向一块区域,这块区域不可写,只能读.char * const p; 指针常量,指向一块区域,这块区域可读可写,但是指针的值初始后就不能改,类似于一

C#使用指针表达式

如何:获取指针变量的值 使用指针间接运算符可获取位于指针所指向的位置的变量. 表达式采用下面的形式,其中, p 是指针类型: *p; 不能对除指针类型以外的任何类型的表达式使用一元间接寻址运算符. 此外,不能将它应用于 void 指针. 当向 null 指针应用间接寻址运算符时,结果将取决于具体的实现. 示例 下面的示例使用不同类型的指针访问 char 类型的变量. 注意,theChar 的地址在不同的运行中是不同的,因为分配给变量的物理地址可能会更改. unsafe class TestCla

指针,常量和类型别名

定义typedef char* cptr,cptr和char *在定义数据时的区别,可由下面两个程序得出.typedef char * cptr;void main(){char a;const cptr p = 0;p = &a;?system("pause");}上面的程序编译时报错,error C3892: “p”: 不能给常量赋值 void main(){char a;const char * p = 0;p = &a; system("pause&q

指针、常量和类型别名

今天看了C++Primer的2.5.1的一点小理解. 如果某个类型的别名指代的是复合类型或是常量,那么它用到声明语句里面就会产生意想不到的后果,例如下面的声明语句用到了类型pstring,它实际上是类型char*的别名: typedef char* pstring; const pstring cstr = 0; //cstr是指向char的常量指针 const pstring* ps; //ps是一个指针,指向char的常量指针. 上述两条声明语句的基本数据类型都是const pstring,