第六讲 指针与字符串 —— 为什么指针 —— 持久动态内存分配 —— 字符串(字符数组).

Slides:



Advertisements
Similar presentations
◎ 標準函數 標準函數庫中,提供了許多不同功能的函數,而這些函數 的原型宣告以及使用函數相關的定義,依照相關函數的分 類,分別定義在不同的標頭檔之中。 標準函數庫中,提供了許多不同功能的函數,而這些函數 的原型宣告以及使用函數相關的定義,依照相關函數的分 類,分別定義在不同的標頭檔之中。 本來呼叫使用標準函數庫裡的函數,也就是使用模組裡的.
Advertisements

C语言程序设计 主讲教师 :张群燕 电话:
电子成绩单项目实现.
程序设计实习 3月份练习解答
第九章 字串 (String).
长城国际酒店式公寓营销策划报告
第七章 固定资产 第一节 固定资产概述 第二节 固定资产的确认和初始计量 第三节 固定资产的后续计量 第四节 固定资产清查与期末计价
第5章 指 针 教学目标: 掌握指针定义、初始化方法和基本运算; 掌握利用指针访问一维数组、二维数组的方法;
高级语言程序设计 C++程序设计教程(下) 2006年春季学期 与一些教材的区别 偏重理论,不去讨论某个系统的具体使用方法,但会涉及实现技术
第4章 数组 数组是由一定数目的同类元素顺序排列而成的结构类型数据 一个数组在内存占有一片连续的存储区域 数组名是存储空间的首地址
C++程序设计 王希 图书馆三楼办公室.
資料大樓 --談指標與陣列 綠園.
C++程序设计 第二讲 清华大学软件学院.
程序设计II 第三讲 字符串处理.
第3章 C 語言的基本知識.
Scope & Lifetime 前言 Local Scope Global Functions & Objects
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
第六章 继承性和派生类 胡昊 南京大学计算机系软件所.
计算概论 第十八讲 C语言高级编程 结构与习题课 北京大学信息学院.
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
Introduction to the C Programming Language
Object-Oriented Programming in C++ 第一章 C++的初步知识
程序设计期末复习 黎金宁
第三章 C++中的C 面向对象程序设计(C++).
2 C++ 的基本語法和使用環境 親自撰寫和執行程式是學好程式語言的不二法門。本章藉由兩個簡單的程式,介紹C++ 程式的基本結構和開發環境,讓初學者能逐漸建立使用C++ 的信心。
Chap 8 指针 8.1 寻找保险箱密码 8.2 角色互换 8.3 冒泡排序 8.4 电码加密 8.5 任意个整数求和*
计算机网络讲义 第5章 批量数据处理—数组 一维数组 排序和查找 二维数组 字符串.
第五章 指针 5.1 指针的概念和定义 5.2 指针运算 5.3 指针和数组 5.4 字符串指针 5.5 指针数组 5.6 指向指针的指针
第二章 C++对C 在非面向对象方面的改进 更简洁,更安全.
C语言 程序设计基础与试验 刘新国、2012年秋.
第3讲 C++程序控制结构 3.1 顺序结构 3.2 分支结构 3.3 循环结构 3.4 转向控制 3.5 综合案例分析.
字符串和字符数组 字符串的输入和输出 字符串的基本操作
程序的三种基本结构 if条件分支语句 switch多路开关语句 循环语句 循环嵌套 break,continue和goto语句
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
切換Dev c++顯示語言 工具->環境選項(V)->介面->language (Chinese TW)
数组 梁春燕 华电信息管理教研室.
第1章 概述 本章要点: C语言程序结构和特点 C语言程序的基本符号与关键字 C语言程序的编辑及运行 学习方法建议:
C++大学基础教程 第5章 数组 北京科技大学 信息基础科学系.
C++ 程式設計 基礎篇 張啟中 Chang Chi-Chung.
第三章 链表 单链表 循环链表 多项式及其相加 双向链表 稀疏矩阵.
7.1 广义表的概念 广义表是n(n≥0)个数据元素组成的序列,其中每个数据元素或是单个数据元素(简称原子),或仍然是一个广义表 。
第二章 基本数据类型及运算 C数据类型概述 基本数据类型 运算符和表达式 混合运算与类型转换 数据的输入输出 顺序程序设计举例.
C语言复习3----指针.
C++语言程序设计 C++语言程序设计 第三章 控制语句 第十一组 C++语言程序设计.
第10讲 构造函数和析构函数 构造函数 析构函数 This 指针.
C语言大学实用教程 第6章 数组 西南财经大学经济信息工程学院 刘家芬
函式庫補充資料.
C语言的特点 1. C程序由许多函数组成 2. C程序必须有且只有一个主函数main( ) 3. 函数用“{”和“}”表示起点和终点
第11章 從C到C++語言 11-1 C++語言的基礎 11-2 C++語言的資料型態與運算子 11-3 C++語言的輸出與輸入
字符串 (String) 字符串是 n (  0 ) 个字符的有限序列, 记作 S = “c1c2c3…cn” 其中,S 是串名字
C程序设计.
<编程达人入门课程> 本节内容 为什么要使用变量? 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ:
第二章 类型、对象、运算符和表达式.
第二讲 基本数据类 型及数组等 此为封面页,需列出课程编码、课程名称和课程开发室名称。
C/C++基礎程式設計班 C++: 物件的使用、參考、重載函式 講師:林業峻 CSIE, NTU 3/28, 2015.
第 9 章 建構函式與解構函式.
C程序设计.
第 3 章 类的基础部分 陈哲 副教授 南京航空航天大学 计算机科学与技术学院.
#include <iostream.h>
1.4WIN32中的宽字符.
《数据结构与算法设计》第一部分 面向对象的C++程序设计基础.
Introduction to the C Programming Language
基本資料型態 變數與常數 運算子 基本的資料處理 授課:ANT 日期:2014/03/03.
C 程式設計— 字元與字串 台大資訊工程學系 資訊系統訓練班.
變數與資料型態  綠園.
第二章 Java基础语法 北京传智播客教育
第六章 复合数据类型 指针的声明与使用 数组的声明与使用 指针与数组的相互引用 字符串及相关库函数 new与delete
台大資訊工程學系 資料系統訓練班 第119期 吳晉賢
C++语言程序设计 C++语言程序设计 第二章 基本数据类型与表达式 第十一组 C++语言程序设计.
Presentation transcript:

第六讲 指针与字符串 —— 为什么指针 —— 持久动态内存分配 —— 字符串(字符数组)

指 针 什么是指针 指针的定义与运算 指针与一维数组 指针数组 指针与引用 指针与函数

指针定义 什么是指针 指针的定义 指针变量,简称指针,用来存放其它变量的内存地址 类型标识符 * 指针变量名 声明一个指针类型的变量,星号后面可以留空格 类型标识符表示该指针所指向的对象的数据类型,即该指针所代表的内存单元所能存放的数据的类型 Tips:变量为什么要声明? 1) 分配内存空间; 2) 限定变量能参与的运算及运算规则。 Tips:内存空间的访问方式:1) 变量名; 2) 内存地址,即指针。

指针运算 指针的两个基本运算 地址运算符:& 提取变量的内存地址:& 提取指针所指向的变量的值:* &变量名 // 提取变量在内存中的存放地址 例: int x=3; int * px; // 定义指针 px px=&x; // 将 x 的地址赋给指针 px 此时,我们通常称这里的 px 是指向 x 的指针 注意:指针的类型必须与其指向的对象的类型一致

指针运算 * 指针运算符: 初始化:声明指针变量时,可以赋初值 *指针变量名 // 提取指针变量所指向的对象的值 例: *指针变量名 // 提取指针变量所指向的对象的值 ex06_pointer_01.cpp 例: int x; int * px; // 声明指针变量,星号后面可以有空格! px=&x; *px = 3; // 等价于 x = 3,星号后面不能有空格! 在使用指针时,我们通常关心的是指针指向的元素! 初始化:声明指针变量时,可以赋初值 例: int x = 3; int * px = &x; // 指针的值只能是某个变量的地址

空指针 void 类型的指针 void * 指针名 void 类型的指针可以指向任何类型的对象的地址 例: int x = 3; int * px; void * pv; pv = &x; // OK, void 型指针指向整型变量 px = (int *)pv; // OK,使用 void 型指针时需要强制类型转换

指针赋值 指针可能的取值 一个有效的指针只有三种取值: 没有初始化或赋值的指针是无效的指针, 引用无效指针会带来难以预料的问题! int x=3; int * px=&x; int * py=&x+1; 一个有效的指针只有三种取值: (1) 一个对象的地址; (2) 指向某个对象后面的对象; (3) 值为 0 或 NULL(空指针)。 int * pi; pi=0; // OK pi=NULL; // OK 没有初始化或赋值的指针是无效的指针, 引用无效指针会带来难以预料的问题! 指针赋值:只能使用以下四种类型的值 (1) 0 或者值为 0 的常量,表示空指针; (2) 类型匹配的对象的地址; (3) 同类型的另一有效指针; (4) 另一个对象的下一个地址。

指针与常量 指向常量的指针 const 类型标识符 * 指针名 const int a = 3; int * pa = &a; // ERROR const int * cpa = &a; // OK 指向 const 对象(常量)的指针必须用 const 声明! 这里的 const 限定了指针所指对象的属性,不是指针本身的属性! const int a = 3; int b = 5; const int * cpa = &a; // OK *cpa = 5; // ERROR cpa = &b; // OK *cpa = 9; // ERROR b = 9; // OK ex06_pointer_const.cpp 指向 const 的指针所指对象的值并不一定不能修改! 允许把非 const 对象的地址赋给指向 const 的指针; 但不允许使用指向 const 的指针来修改它所指向的对象的值!

指针与常量 常量指针,简称常指针 指向 const 对象的 const 指针 常量指针:指针本身的值不能修改 int a = 3, b = 5; int * const pa = &a; // OK pa = &b; // ERROR 指向 const 对象的 const 指针 const 类型标识符 * const 指针名 指针本身的值不能修改,其指向的对象的值也不能修改

指针算术运算 指针可以和整数或整型变量进行加减运算, 且运算规则与指针的类型相关! int * pa; int k; pa + k --> pa 所指的当前位置之后第 k 个元素的地址 pa - k --> pa 所指的当前位置之前第 k 个元素的地址 在指针上加上或减去一个整型数值 k,等效于获得一个新指针,该指针指向原来的元素之后或之前的第 k 个元素 指针的算术运算通常是与数组的使用相联系的 一个指针可以加上或减去 0,其值不变 int * pa; int k; pa++ --> pa 所指的当前位置之后的元素的地址 pa-- --> pa 所指的当前位置之前的元素的地址

指针算术运算 pa short * pa pa-2 *(pa-2) pa-1 *(pa-1) *pa pa+1 *(pa+1) pa+2 // 每个元素占两个字节 pa-2 *(pa-2) pa-1 *(pa-1) pa *pa pa+1 *(pa+1) pa+2 *(pa+2) pa+3 *(pa+3)

指针算术运算 pb pb-1 int * pb *(pb-1) *pb pb+1 *(pb+1) pb+2 *(pb+2) //每个元素占四个字节 *(pb-1) pb *pb pb+1 *(pb+1) pb+2 *(pb+2)

指针与数组 C++中,指针与数组密切相关:由于数组元素在内存中是连续存放的,因此使用指针可以非常方便地处理数组元素! int a[]={0,2,4,8}; int * pa; pa = a; // OK pa = &a[0]; // OK, 与上式等价 *pa = 3;// OK,等价于 a[0]=3 *(pa+2) = 5; // OK,等价于 a[2]=5 *(a+2) = 5; // OK,等价于 a[2]=5 在 C++ 中,数组名就是数组的首地址! 当数组名出现在表达式中时,会自动转化成指向第一个数组元素的指针! 思考:pa = a+1,则 *pa = ?

一维数组与指针 一维数组与指针 在 C++ 中,引用数组元素有以下三种方式: (1) 数组名与下标,如:a[0] (3) 指针,如:int * pa=a; *pa int a[]={0,2,4,8}; int * pa = a; *pa = 1; // 等价于 a[0]=1 *(pa+2) = 5; // 等价于 a[2]=5 *(a+2) = 5; // OK,等价于 a[2]=5 *(pa++) = 3; // OK,等价于 a[0]=3; pa = pa+1; *(a++) = 3; // ERROR! a代表数组首地址,是常量指针! *(pa+1) = 10; // 思考:修改了哪个元素的值? ex06_pointer_array01.cpp 指针的值可以随时改变,即可以指向不同的元素; 数组名是常量指针,值不能改变。

举例 例:使用三种方法输出一个数组的所有元素 // 第一种方式:数组名与下标 for (int i=0; i<n; i++) cout << a[i] << "," ; // 第二种方式:数组名与指针运算 for (int i=0; i<n; i++) cout << *(a+i) << "," ; // 第三种方式:指针 for (int * pa=a; pa<a+n; pa++) cout << *pa << "," ; 若pa是指针,k是整型数值,则 *(pa+k) 可以写成 pa[k] *(pa-k) 可以写成 pa[-k] // 第三种方式:指针 for (int * pa=a, i=0; i<n; i++) cout << pa[i] << "," ; ex06_pointer_array02.cpp

a[i] <=> pa[i] <=> *(pa+i) <=> *(a+i) 一维数组与指针 一维数组 a[n] 与指针 pa=a 数组名 a 是地址常量,数组名 a 与 &a[0] 等价; a+i 是 a[i] 的地址,a[i] 与 *(a+i) 等价; 数组元素的下标访问方式也是按地址进行的; 可以通过指针 pa 访问数组的任何元素,且更加灵活; pa++ 或 ++pa 合法,但 a++ 不合法; *(pa+i) 与 pa[i] 等价,表示第 i+1 的元素; a[i] <=> pa[i] <=> *(pa+i) <=> *(a+i)

指针数组 指针数组:数组的元素都是指针变量 指针数组的声明: 类型标识符 * 指针数组名[n] int a[]={0,2,4,8}; int b[]={1,3,5,7}; int c[]={2,3,5,8}; int *pa[3]={a,b,c}; // 声明一个有三个元素的指针数组 // pa[0]=a, pa[1]=b, pa[2]=c 上面的 pa 代表指针数组,不是普通的指针!

二维数组 A C++中,二维数组是按行顺序存放在内存中的,可以理解为一维数组组成的一维数组。 例:int A[2][3]={{1,2,3},{7,8,9}}; A[0] —— A00 A01 A02 A[1] —— A10 A11 A12 可以理解为: A A[0][0] A[0][1] A[0][2] A[1][0] A[1][1] A[1][2] A[0] A[1] (第一行的首地址) (第二行的首地址) A[0], A[1] 称为行数组

二维数组与指针 int A[2][3]={{1,2,3},{7,8,9}}; int * pa = A[0]; // 行数组A[0]的首地址, 等价于 pa=&A[0][0] int * pa1 = A[1]; // 行数组A[1]的首地址,即 &A[1][0] *pa = 11; // 等价于 A[0][0]=11 *(pa+2) = 12; // 等价于 A[0][2]=12 *(pa+4) = 13; // 等价于 A[1][1]=13

二维数组与指针 对于二维数组 A,虽然 A、A[0] 都是数组首地址,但二者指向的对象不同:

二维数组与指针 如何用普通指针引用二维数组的元素? int A[2][3]={{1,2,3},{7,8,9}}; int * p = A; // ERROR! int * p = A[0]; // OK 当 int * p 声明指针时,p 指向的是一个 int 型数据,而不是一个地址,因此,用 A[0] 对 p 赋值是正确的,而用 A 对 p 赋值是错误的! 如何用普通指针引用二维数组的元素? 设指针 p=&A[0][0],则 A[i][j] <==> *(p+n*i+j) 例:二维数组与普通指针 ex06_pointer_array2D.cpp

指针与引用 引用与指针 引用作为函数参数的优点 引用是变量的别名; 引用必须初始化,且不能修改; 引用只针对变量,函数没有引用; int a = 3; int * pa = &a; // 指针 int & ra = a; // 引用 引用是变量的别名; 引用必须初始化,且不能修改; 引用只针对变量,函数没有引用; 传递大量数据时,最好使用指针; 用引用能实现的功能,用指针都能实现。 引用作为函数参数的优点 传递方式与指针类似,但可读性强; 函数调用比指针更简单、安全;

指针作为函数参数 指针作为函数参数 以地址方式传递数据。 形参是指针时,实参可以是指针或地址。 void split(double x, int * n, double * f) double x, x2; int x1; split(x, &x1, &x2) ex06_pointer_fun01.cpp 当函数间需要传递大量数据时,开销会很大。此时,如果数据是连续存放的,则可以只传递数据的首地址,这样就可以减小开销,提高执行效率!

指针作为函数参数 指针作为函数参数的三个作用 使形参和实参指向共同的内存地址; 减小函数间数据传递的开销; 传递函数代码的首地址(后面介绍)。 Tips: 如果在被调函数中不需要改变指针所指向的对象的值,则可以将形参中的指针声明为指向常量的指针。

指针型函数 当函数的返回值是地址时,该函数就是指针型函数 指针型函数的定义 数据类型 * 函数名(形参列表) { 函数体 }

指向函数的指针 在程序运行过程中,不仅数据要占用内存空间,函数也要在内存中占用一定的空间。函数名就代表函数在内存空间中的首地址。用来存放这个地址的指针就是指向该函数的指针。 函数指针的定义 数据类型 (* 函数指针名)(形参列表) 这里的数据类型和形参列表应与其指向的函数相同 注:函数名除了表示函数的首地址外,还包括函数的返回值类型,形参个数、类型、顺序等信息。 Tips:可以象使用函数名一样使用函数指针。

函数指针 函数指针需要赋值后才能使用 int Gcd(int x, int y); int Lcm(int x, int y); int (* pf)(int, int); // 声明函数指针 pf = Gcd; // pf 指向函数 Gcd cout << "最大公约数:" << pf(a,b) << endl; pf = Lcm; // pf 指向函数 Lcm cout << "最小公倍数:" << pf(a,b) << endl; ex06_pointer_fun02.cpp

持久动态存储分配 动态内存申请 --- new 动态内存释放 --- delete 动态数组的申请与释放 在被调函数中申请动态内存, 返回给主调函数

动态存储分配 若在程序运行之前,不能够确切知道数组中元素的个数,如果声明为很大的数组,则可能造成浪费,如果声明为小数组,则可能不够用。此时需要动态分配空间,做到按需分配。 动态内存分配相关函数 申请内存空间:new 释放内存空间:delete 每个程序在执行时都会占用一块可用的内存,用于存放动态分配的对象,此内存空间称为自由存储区(free store)。

申请内存空间 px = new 数据类型; px = new 数据类型(初始值); 申请单个存储单元 px = new 数据类型; px = new 数据类型(初始值); 申请用于存放指定数据类型数据的内存空间,若申请成功,则返回该内存空间的地址,并赋值给指针 px; 若申请不成功,则返回 0 或 NULL。 delete px; // 释放由 new 申请的内存空间 注:px 必须是由 new 操作的返回值!

动态内存数组 px = new 数据类型[数组长度]; px = new 数据类型[数组长度](); // 赋初值 0 创建一维动态数组 ex06_pointer_new01.cpp px = new 数据类型[数组长度]; px = new 数据类型[数组长度](); // 赋初值 0 这里初始化时只能将全部元素设置为 0,而不能象数组变量那样用初始化列表赋初值(C++11新标准已加入该功能)

动态内存数组 px = new 数据类型[n1][n2]...[nm]; delete[] px; // 释放由 new 建立的数组 创建多维动态数组 px = new 数据类型[n1][n2]...[nm]; 注:此时 px 不是普通的指针,而是: (* px)[n2]...[nm] 动态数组的释放 delete[] px; // 释放由 new 建立的数组

动态内存举例 例:给定一个正整数 N,求出 N 个最小的素数 int main() { int N; cout << "Input N: "; cin >> N; int * pa = new int[N]; // 申请内存空间 int i, flag, k=0, n=2; while (k < N) // 寻找 N 个素数 { flag = 0; for(i=2; i<n; i++) if (n % i == 0) {flag = 1; break;} if (flag==0) { pa[k] = n; k++; } n++; } ex06_pointer_new02.cpp for(i=0; i<k && pa[i]<=sqrt(n); i++) if (n % pa[i] == 0) {flag = 1; break;}

动态内存举例 例:将前面的例子写成函数形式 int * find_prime(int N) { int * pa = new int[N]; // 申请内存空间 int i, flag, k=0, n=2; while (k < N) // 寻找 N 个素数 { flag = 0; for(i=2; i<n; i++) if (n % i == 0) {flag = 1; break;} if (flag==0) { pa[k] = n; k++; } n++; } return pa; 注:在主调函数中, 如果不再需要 pa, 则需用 delete[] 释放

字符串(字符数组) 字符串的表示 字符串输入输出 字符串操作 --- 相关函数 字符操作函数

字符串 字符串的表示:一维字符数组 字符串赋值:逐个赋值,循环实现 char str[5]={'m','a','t','h','\0'}; char str[5]="math"; // OK char str[]="math"; // OK,只能用于初始化 字符串以 "\0" 为结束标志 使用双引号时,会自动在最后添加结束标志 字符串赋值:逐个赋值,循环实现 char str[5]; str = "Math"; // ERROR:一维数组,不能直接赋值!

字符串输出 字符串的输出 法一:单个元素单个元素输出(循环,数组) 法二:整体输出 例: char str[20]="C++ and Matlab"; for(int i=0;i<20;i++) if (str[i]!='\0') cout << str[i]; else break; ex06_str_cout.cpp char str[20]="C++ and Matlab"; cout << str << endl; 注:输出字符中不含 "\0"

字符串输入 字符串的输入 输入单个字符串时,中间不能有空格 一次输入多个字符串时,以空格隔开 例: char str[5]; cin >> str; char str1[5], str2[5], str3[5]; cin >> str1 >> str2 >> str3; ex06_str_cin.cpp 运行时输入数据:How are you? str1: str2: str3: 内存中变量状态如下: H o w \0 a r e y u ?

整行输入 整行输入 cin.getline(str,N,结束符); 例: char str[13]; cin >> str; 运行时输入数据:How are you? 内存中变量状态如下: H o w \0 整行输入 cin.getline(str,N,结束符); 连续读入多个字符(可以有空格),直到读满 N-1 个为止, 或遇到指定的结束符(不存储结束符) 结束符可以省略,默认为 '\n' (换行) ex06_str_getline.cpp 例: char str[13]; cin.getline(str,13);

单个字符输入 单个字符的输入 getchar(); char ch; ch=getchar();

字符串操作 字符串相关函数 (需包含头文件 cstring 和 cstdlib ) 函数 描述 用法 strlen 求字符串长度 strlen(str) strcat 字符串连接 strcat(dest,src) strcpy 字符串复制 strcpy(dest,src) strcmp 字符串比较 strcmp(str1,str2) atoi 将字符串转换为整数 atoi(str) atol 将字符串转换为long atol(str) atof 将字符串转换为double atof(str) itoa 将整数转换为字符串 itoa(int,str,raidx) (更多函数见 http://www.cppreference.com)

字符串操作 strlen(str) 返回字符串 str1 的长度(不含结束符) strcat(str1,str2) strncat(str1,str2,n) 将 str2 的内容添加到 str1 中,至多添加 n 个字符 strcmp(str1,str2) 按字典顺序比较 str1 和 str2 的大小 如果 str1>str2,则返回一个正数; str1<str2,则返回一个负数;相等则返回 0

字符串操作 strncmp(str1,str2,n) 按字典顺序比较 str1 和 str2 的前 n 个字符的大小 strcpy(str1,str2) 将 str2 的全部内容复制到 str1 中; str1 的长度应该不小于 str2 的长度。 strncpy(str1,str2,n) 将 str2 的前 n 个字符复制到 str1 中; 若 n 大于 str2 的长度,则复制全部内容。 ex06_str_fun.cpp 例: int N = 20; char str1[N]; char str2[]="hello world!"; strncpy(str1,str2,N-1); // 实际复制字符个数不超过 str2 长度

字符串操作 x=atoi(str) x=atol(str) x=atof(str) 分别将 str 转化为整型、长整型和双精度型数据 例: int x; double y; x=atoi("66"); // x=66 y=atof("14.5"); // y=14.5 ex06_str_atoi.cpp itoa(int,str,radix) 按指定的进制将一个整数转化为字符串 例: char str[5]; itoa(66,str,16); // 按16进制转换

字符检测 需加入头文件 cctype 函数 描述 用法 isdigit 是否为数字 isalpha 是否为字母 isalnum isalpha('a') isalnum 是否为字母或数字 isalnum('c') islower 是否为小写 islower('b') isupper 是否为大写 isupper('B') isspace 是否为空格 isspace(' ') tolower 将大写转换为小写 tolower('A') toupper 将小写转换为大写 toupper('a') 以上检测和转换函数只针对单个字符,而不是字符串! 更多字符检测函数参见相关资料

字符与整数 字符与整型数据之间的转换 例: 字符数据与整型数据之间的转换是通过 ASCII 码实现的 字符参加算术运算时,自动转换为整数 char x='2'; int y=x; int z=x-'0'; cout << "x=" << x << endl; // x='2' 是字符 cout << "y=" << y << endl; // y=50 是整数 cout << "z=" << z << endl; // z=50-48=2 是整数 字符数据与整型数据之间的转换是通过 ASCII 码实现的 字符参加算术运算时,自动转换为整数 atoi 等只能作用在字符串上!不能作用在字符上!

课后练习 课后练习(自己练习) (1) 教材第七章:字符与字符串 p253 7.19 (2) 教材第十一章:指针

课后练习 课后练习(自己练习) (3) 已知一个数组,数组名为 x,试用一条语句算出该数组的元素个数 (提示:使用 sizeof 函数) (4) 阅读下面的代码 int a[]={6,21,12,34,55}; int * pa = a, * pb; *pa = 5; *(pa+2) = 8; *(pa++) = *a + 42; pb = pa; *(++pb) = 45; 指出最后 a 的值,*pa 的值,*pb 的值

上机作业 1) 有 17 人围成一圈,编号1~17,从1号开始报数,报到3的倍数的人离开,一直数下去,直到最后只剩一人,求此人编号。程序取名 hw06_01.cpp 2) 编写函数,交换两个双精度变量的值,分别用引用和指针实现。 函数分别为 swap_ref 和 swap_point,并在主函数中定义两个双精度变量, 从键盘接受输入,并将交换后的值在屏幕上输出。(程序名 hw06_02.cpp) void swap_ref(double & ra, double & rb); void swap_point(double * pa, double * pb); 3) 求最小的前 100 个素数,存放在数组 p 中,并分别使用下列方式在屏幕上输出 p,每行输出 10 个,程序取名为 hw06_03.cpp 方式一:数组名+下标运算; 方式二:数组名+指针运算; 方式三:指针+指针运算

上机作业 4) 编写函数,计算两个矩阵的乘积 Z=X*Y。其中 XRmp,YRpn, ZRmn,要求函数对任意的正整数 m,p,n 都能实现矩阵相乘。 void matrix_prod(double * px, double * py, double * pz, int m, int p, int n); 提示:这里 px, py, pz 分别指向 X[0][0], Y[0][0] 和 Z[0][0] 程序取名为 hw06_04.cpp 5) 生成一个 6 阶矩阵 T(定义见右方), 并分别使用下列方式按矩阵形式输出: 方式一:数组名+下标运算; 方式二:数组名+指针运算; 方式三:行指针+指针运算; (定义矩阵时,要使用循环实现, 程序名 hw06_05.cpp)

上机作业 6) 给定两个一维数组 a 和 b,其中 a 中的数据是无序的,而 b 中的数据按 升序排列。试统计 a 的所有元素中,大于 b 的第 k 个元素且小于第 k+1 个 元素的数据个数。其中 a=[98,12,34,71,43,54,28,33,65,56], b=[10,30,50,80,100] 要求将结果存放在数组 c 中,其中 c[k] 表示数组 a 中大于 b[k] 而小于 b[k+1] 的元素个数。程序名 hw06_06.cpp 7) 二进制转十进制。程序取名为 hw06_07.cpp 编写函数,将一个用字符串表示的二进制数转化为十进制数,如“10001”所对应的十进制数为17,在主函数中用“1100110011001100”来测试 int bin2dec(const char * const str); 提示:将一个字符转化成数字,可借助字符加减运算(推荐)或字符串函数

上机作业 8) 字符易位破译。程序取名为 hw06_08.cpp 编写函数,测试两个字符串是否字符异位相等,即两个字符串中包含的字母是相同的,但次序可以不同,如“silent”和“listen”是字符异位相等,但“baac”与“abcc”不是 bool isAnagram(const char * const str1, const char * const str2); 提示:先对字符串进行排序,然后再比较