C++学习笔记(四)

1.指针(变量的地址):
  指针变量:存放指针(地址)的变量
  直接存取(访问):按变量地址取值
  间接存取(访问):将变量的地址放入指针变量中
  定义指针变量:基类型 *指针变量名

2.与指针有关的运算符:
  &:取地址运算符
  *:指针运算符(间接访问运算符);
  int *pointer_1,*pointer_2;
  int a = 1, b = 2;
  pointer_1 = &a;
  pointer_2 = &b;
  pointer_2 = &*pointer_1;//*,&优先级一样,自右至左结合,所以是先取a的值,再取a的地址&a给指针变量pointer_2
  若有*&a,表示的是先取a的地址,再取a的值。

3.谨记:函数传参:实参->形参 之间的数据是单向传递的“值传递方式”,指针变量也遵守这一原则,调用函数时,不会改变实参指

针变量的值,但可以改变实参指针变量所指向的值。所以可以利用指针来改变主调函数中多个变量的值,不用指针变量来实现这个是

很难实现这一点的。

4.数组元素的指针就是数组元素的地址

  int a[10];
  int *pointer;
  pointer = a[0];与pointer = a; 等价都表示数组的第一个元素的地址。

  如果初始:pointer = a; 以下都为此前提,那么:
  pointer+1 = a+1 = a[1] //实际地址看类型,pointer+1*n 或者 a+1*n 或者&a[1]
  所以有pointer+i = a+i = a[i] pointer+i*n a+i*n &a[i] 例:int型n=4;

  所以可以看出[]是变址运算符,对a[i]的处理是这样的:先按a+i*n计算数组元素的地址,然后由此地址找出所指向的单元的


  指向数组元素的指针变量也可以带下标,如:pointer[i]与*(pointer+i)等价。
  所以引用数组元素有两种方法:
  a.下标法:a[i];
  b.指针法:*(a+i)或者*(pointer+i);使用这种方法能使目标程序质量高(占运行内存小,运行速度快)
  ·注意:指针变量可以指向有效的数组元素,也可以指向数组以后的内存单元。例:
  int a[10], *p = a;
  cout <<*(p+10);//编译不会提示出错。

  5.如果先使p=a,即p指向数组a的首元素:
  (1).p++(或p+=1):使p指向下一元素,即a[1],如果用*p,则得到a[1]的值;
  (2).*p++: ++与*优先级相同,右结合,相当于*(p++),所以是先取*p的值,再使p++。
  例如:
  for(p=a;p<a+10;p++)
  cout <<*p ; //可改写为:
  for(p=a;p<a+10; )
  cout <<*p++;
  (3).*(p++):先取*p值,p再加1
  *(++p):先p加1,再取*p值,二者区别仅在于p++ 与 ++p 的含义。
  (4).(*p)++:先取*p的值,再使取得的值加1.
  (5).如果p当前指向a[i]:
  *(p--): 先取*p的值,即a[i],再使指针变量p指向a[i-1];
  *(++p): 先使指针变量自增1,指向a[i+1],再取*p的值a[i+1];
  *(--p): 先使指针变量自减1,指向a[i-1],再取*p的值a[i-1];

6.使用指针变量作函数参数接收数组地址
因为数组作形参时接收的也是实参数组的首地址,所以可以用指针变量来接收以数组为实参的参数,例如:
  void select(int array[]);//实际上可以表示为
  void select(int *array );/*编译器实际上是将数组名作为指针变量来处理的。所以实际上,在函数调用时并不存在一个

  占有存储空间的形参数组,只有指针变量。*/

7.多维数组与指针:
  int arr[3][4];假设arr起始为2000

  (1)C++中规定了数组名作为首地址,所以
  arr[0]是arr[0][0]的首地址,arr[1]是arr[1][0]的首地址即&arr[1][0],
  arr[0]+1,表示arr[0][1]的地址,arr[0]+2表示的是arr[0][2]的地址;
  *(arr[0]+2) 表示a[0][2]的值。所以有
  arr[i]+j 表示&arr[i][j],
  *(arr[i]+j) 表示arr[i][j]的值。
  (2)arr,表示首行地址&arr[0],则a+1表示第二行起始地址&arr[1],其值为2000+4*4=2016;
  arr[1]+1: 表示 &arr[1][1],所以有
  arr[i]+j: 表示 &arr[i][j],
  *(arr[i]+j):表示 arr[i][j]的值,因为arr[i] = *(arr+i);所以
  *(*(arr+i)+j): 也表示arr[i][j]的值。
  (3)指向数组元素的指针变量:
#include<iostream>
using namespace std;

int main(){

  int array[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
  int *p;
  p = array[0];//注意此处是array[0],而不是array,要符合指针类型。
  cout <<"--------------" <<endl;
  for( p; p<array[0]+12;p++ )
  cout <<*p<< ‘ ‘;
  cout <<endl;
  cout <<"--------------" <<endl;
  return 0;
}
(4)指针变量指向由m个元素构成的一维数组
#include<iostream>
using namespace std;

int main(){

  int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
  int (*p)[4],i,j;/*(*p)[4]是一个指针变量,它指向包含4个整型元素的一维数组,()不可丢,
否则变成*p[4],[]优先级高,变成了指针数组
*/
  p = a;//p指向a[0];
  cout <<"please input i,j:";
  while(1){
    cin >>i >>j;
    if( i>=3||j>=4 )
    cout <<"warning:i must less then 3,j must less then 4,please try a again:" <<endl;
    else break;
  }
  cout <<"---------------------" <<endl;
  cout <<*(*(p+i)+j);
  cout <<endl <<"---------------------" <<endl;
  return 0;
}

8.指向数组的指针作函数参数(一维数组名,多维数组名也可,之前有讲过)
#include<iostream>
using namespace std;

int main(){

  void output(int (*p)[4]);
  int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
  output(a);//a指向a[0]
  return 0;
}

void output(int (*p)[4]){//注意形参声明为指向一维数组的指针变量,而不是int型指针变量

  int i,j;
  for( i=0;i<3;i++ )
    for( j=0;j<4;j++ )
      cout <<*(*(p+i)+j) <<" ";
  cout <<endl;
}

9.字符指针(C++中共3种方法访问一个字符串,之前已经学习过两种)
(1)用字符指针指向一个字符串
#include<iostream>
using namespace std;

int main(){

  char *str = "I love China!";//对字符指针变量str的初始化其实是把字符串第一个元素的 地址 赋给str
  //等价于 char *str; str = "I love China"; 输出时,系统先输出str指向的第一个字符数据,
  //然后str+1,使之指向下一个字符,然后输出......直至遇到‘\0‘为止,在内存中,字符串的末尾
  //被自动加了一个‘\0‘
  cout <<str<<endl;
  return 0;
}
(2)利用字符指针实现对字符串的存取
#include<iostream>
using namespace std;

int main(){

  char str1[] = "I love liu_xiao_min",str2[20];
  char *p1,*p2;
  p1 = str1;
  p2 = str2;
  for( ;*p1!=‘\0‘;p1++,p2++ )
  *p2 = *p1;//其实string str1 = "I love liu_xiao_min",str2;str2 = str1;最简单快捷
  *p2 = ‘\0‘;
  p1 = str1;
  p2 = str2;
  cout <<p1 <<endl;
  cout <<p2 <<endl;
  return 0;
}

10.函数与指针
(1)用函数指针变量调用函数(原理:一个函数被编译时被分配一个入口地址。这个函数入口地址就称为函数的指针)
函数指针定义:
函数类型 (*指针变量名)(函数形参表);
例:
#include<iostream>
using namespace std;

int main(){

  int max( int x, int y );
  int (*p)( int, int );//(*p)括号不能漏
  int a,b,n;
  p = max; //函数名代表函数入口地址
  cin >>a >>b;
  m = p( a,b );
  cout <<"max=" <<m<<endl;
  return 0;
}
int max( int x, int y ){

  int z;
  if( x>y )
    z = x;
  else
    z = y;
  return z;
}

(2)用指向函数的指针作函数参数
类似:float intern(float a, float b, float (*fun)(float));

11.指针函数(函数返回值为指针的函数)
指针函数定义:
函数类型 *函数名(参数表列);
例:
#include<iostream>
using namespace std;

int main(){
  int *a(int a);
  int i = 10;
  cout <<a( 10 ) <<endl;
  return 0;
}

int *a( int a ){

  return &a;
}

12.指针数组(一个数组,其元素全部为指针类型数据)

一维指针数组:
类型名 *数组名[数组长度];

例:int *a[3]; //注意与int (*a)[3];的区别,后者是指向含有3个整型元素的一维数组的指针变量

#include<iostream>
#include<cstring>
using namespace std;

int main(){

void sort( char *name[], int n );//指针数组做函数参数
void print( char *name[], int n );

  char *name[] = { "BASIC","FORTRAN","C++","Pascal","COBOL" };//指针数组
  int n = 5;
  sort( name,n );
  print( name,n );
  return 0;
}

void sort( char *name[], int n ){ //选择法排序

  char *temp;
  int i,j,k;
  for( i=0;i<n-1;i++ ){
    k = i;
     for( j=i+1;j<n;j++ ){
    if( strcmp( name[k],name[j] )>0 )//name[x]中存放各个字符串的首地址
      k = j;
    }
    if( k!=i ){
    temp = name[i];name[i] = name[k];name[k] = temp;
    }
  }
}

void print( char *name[] , int n ){

  int i;
  for( i=0;i<n;i++ )
  cout <<name[i] <<endl;
  }
输出:
BASIC
C++
COBOL
FORTRAN
Pascal

13.指向指针的指针(指向 指针数据 的指针)
如12所述,数组name[x]是一个指针数组,此时设一个指针变量p,它指向指针数组元素的元素,则p就是指向指针型数据的指

针变量。
定义一个指向指针数据的指针:
char *(*p);//可以写成 char **p;
分析:
char *p:表示指向字符型数据的指针变量(即字符指针变量)。
char *(*p):表示p指向的是字符指针数据
例:
#include<iostream>
using namespace std;

int main(){

  char **p;//定义指向 字符指针数据 的指针变量p
  char *name[] = { "BASIC","FORTRAN","C++","Pascal","COBOL" };
  p = name + 2; //指向name[2]
  cout <<*p <<endl;//输出name[2]中指针指向的字符串的值
  cout <<**p <<endl;//输出name[2]指向的字符串中的第一个字符
  return 0;
}
输出:
C++
C
分析:
由于*p代表name[2],它指向字符串"C++",即在name[2]中存放了字符串"C++"的第一个字符串的地址,因此"cout <<*p <<endl;"就

是从第一个字符开始输出字符串"C++"。第二个cout中的**p是*p(值为name[2])指向的"C++"第一个字符元素的内容,即字符"C",所以

第二个cout语句输出"C".

时间: 2024-12-15 00:43:58

C++学习笔记(四)的相关文章

Caliburn.Micro学习笔记(四)----IHandle&lt;T&gt;实现多语言功能

Caliburn.Micro学习笔记(四)----IHandle<T>实现多语言功能 说一下IHandle<T>实现多语言功能 因为Caliburn.Micro是基于MvvM的UI与codebehind分离, binding可以是双向的所以我们想动态的实现多语言切换很是方便今天我做一个小demo给大家提供一个思路 先看一下效果 点击英文  变成英文状态点chinese就会变成中文                          源码的下载地址在文章的最下边 多语言用的是资源文件建

代码管理工具 --- git的学习笔记四《重新整理git(1)》

1.创建版本库 mkdir  创建目录 cd  地址,到该地址下 pwd 显示当前目录 1.创建目录 $ mkdir startGit $ cd startGit $ pwd 显示当前目录 或者cd到桌面,然后再创建目录 2.初始化版本库 $ git init 初始化仓库 提示信息:Initialized empty Git repository in /Users/xingzai/Desktop/startGit/.git/ 建立一个空的git仓库在/Users/xingzai/Desktop

Linux学习笔记四:Linux的文件搜索命令

1.文件搜索命令  which 语法:which [命令名称] 范例:$which ls  列出ls命令所在目录 [[email protected] ~]$ which ls alias ls='ls --color=auto' /bin/ls 另外一个命令:whereis [名称名称],也可以列出命令所在目录. [[email protected] ~]$ whereis ls ls: /bin/ls /usr/share/man/man1/ls.1.gz /usr/share/man/ma

小猪的数据结构学习笔记(四)

小猪的数据结构学习笔记(四) 线性表之静态链表 --转载请注明出处:coder-pig 本章引言: 在二,三中中我们分别学习了顺序表中的线性表与单链表,线性表有点类似于 我们前面所学的数组,而单链表使用的最多的是指针,这里问个简单的问题, 如果是在以前没有指针的话,前辈先人们怎么实现单链表呢?大家思考下! 没有指针,那么用什么来代替呢?前辈先人们非常机智,想出了使用下标+游标的方式 来实现单链表的效果!也就是今天要讲的--静态链表! 当然你也可以直接跳过本章,因为有了单链表就没有必要用静态链表了

Swift学习笔记四:数组和字典

最近一个月都在专心做unity3d的斗地主游戏,从早到晚,最后总算是搞出来了,其中的心酸只有自己知道.最近才有功夫闲下来,还是学习学习之前的老本行--asp.net,现在用.net做项目流行MVC,而不是之前的三层,既然技术在更新,只能不断学习,以适应新的技术潮流! 创建MVC工程 1.打开Visual studio2012,新建MVC4工程 2.选择工程属性,创建MVC工程 3.生成工程的目录 App_Start:启动文件的配置信息,包括很重要的RouteConfig路由注册信息 Conten

NLTK学习笔记(四):自然语言处理的一些算法研究

自然语言处理中算法设计有两大部分:分而治之 和 转化 思想.一个是将大问题简化为小问题,另一个是将问题抽象化,向向已知转化.前者的例子:归并排序:后者的例子:判断相邻元素是否相同(与排序). 这次总结的自然语言中常用的一些基本算法,算是入个门了. 递归 使用递归速度上会受影响,但是便于理解算法深层嵌套对象.而一些函数式编程语言会将尾递归优化为迭代. 如果要计算n个词有多少种组合方式?按照阶乘定义:n! = n*(n-1)*...*1 def func(wordlist): length = le

Android学习笔记四:添加Source

问题描述 Source not foundThe JAR file D:\.....\sdk\platforms\android-20\android.jar has no source attachment. 问题原因及解决办法 1. 使用SDK Manager下载最新版本的Sources for Android SDK 一般文件下载目录默认在SDK下的sources文件中即 \adt-bundle-windows-x86_64-20130522\sdk\sources\android-20

【Unity 3D】学习笔记四十二:粒子特效

粒子特效 粒子特效的原理是将若干粒子无规则的组合在一起,来模拟火焰,爆炸,水滴,雾气等效果.要使用粒子特效首先要创建,在hierarchy视图中点击create--particle system即可 粒子发射器 粒子发射器是用于设定粒子的发射属性,比如说粒子的大小,数量和速度等.在创建完粒子对象后,在右侧inspector视图中便可以看到所有的粒子属性: emit:是否是使用粒子发射器. min size:粒子最小尺寸. max size:粒子最大尺寸. min energy:粒子的最小生命周期

WEB前端学习笔记 四

接上一篇,web学习笔记 四,在此感谢您对此篇笔记的认可,但转发时请注明文章出自网知博学. 2.0  html的语法格式 html的标签要写在尖括号中 :<> 在在英文输入法状态下,按住shift键然后再按它左侧的尖括号就可了, 先学习一个简单的h1标签,是个标题标签,在html中这样写: <h1>我在h1标签中,我就是标题</h1> 那么h1标签中所包裹的文字,就标记成标题了.通过浏览器的解析后在页面上显示出来的效果就是字体加粗,加黑,和word中的标题性质一样! 大

初探swift语言的学习笔记四(类对象,函数)

作者:fengsh998 原文地址:http://blog.csdn.net/fengsh998/article/details/29606137 转载请注明出处 假设认为文章对你有所帮助,请通过留言或关注微信公众帐号fengsh998来支持我,谢谢! swift扩展了非常多功能和属性,有些也比較奇P.仅仅有慢慢学习,通过经验慢慢总结了. 以下将初步学习一下类的写法. 码工,最大爱好就是看码,而不是文字,太枯燥. // // computer.swift // swiftDemo // // C