【C++】指针和函数
指针和函数
标签:c++
一、基本概念
定义:
也称作“指针变量”,大小为4个字节,内容代表一个内存地址
指针的定义及使用:
- 
定义: int *p;//指向的变量类型为整型 char *pc;
- 
赋值: int *p = (int *) 4000;//强制类型转换,让p = 4000 char ch1 = ‘A’; char *pc = &ch1; *pc = ‘B’; char ch2 = *pc; pc = &ch2;注:指针定义后就要赋值,防止变成野指针 
二、指针的相互赋值
不同类型的指针相互赋值要强制类型转换
int *pn;
char *pc;
char c = 0x65;//e
pn = pc;//编译出错,类型不匹配
pn = &c;//编译出错
pn = (int *) &c;//可以,但是&c只代表一个字节,pn代表四个字节,此时pn会占用&c后面的三个字节,导致错误
int n = *pn;//n中的内容不是0x65
因此,不要用不同类型的指针相互赋值
三、指针的运算
比较大小:
两个同类型的指针p1, p2,如果地址p1<地址p2,则p1<p2,其余同理
相减:
p1 – p2 = (地址1-地址2)/sizeof(T) 
T为指针的类型
加减整数类型变量或者常量:
p + n 等价于:地址p + n * sizeof( T )
p - n 等价于:地址p - n * sizeof( T )
自增自减:
同3
下标运算符[ ]:
p[ n ]等价于 *( p + n )
四、空指针
空指针NULL,即为地址0
可以做条件表达式使用
五、指针作为函数参数
- 
传递指针的方式依然是指传递,注意函数是在对指针操作还是对指针所指的内容操作,即函数只能改变指针指向地址中的内容,不能改变指针本身 #include<iostream> using namespace std; void Swap(int *p1, int *p2) { int temp = *p1; *p1 = *p2; *p2 = temp; } int main() { int m = 4, n = 3; Swap(&m, &n); cout<<m<<','<<n; } 结果:3,4
- 
使用指针作为函数参数时,应先判断指针是否为空,避免野指针对函数造成影响 
- 
返回一个指针时,也要注意返回非空指针 
六、指针和数组
数组的名字即为一个指针,作为函数形参时,T *p和T p[ ]完全等价
七、常量指针和指针常量
常量指针
const T* p
特点:不能通过常量指针修改指向的内容,即内容可以修改,但是要用其他方法
指针常量
T *const p = p0
特点:定义之后指针p就不能指向其他位置,但是可以通过指针对其指向内容修改
八、字符串和指针
普通字符串和指针的关系
字符串常量的类型就是char *,字符数组的类型也是char *
char name[20];
char *pName = name;
string对象和char *指针的关系
- 
可以用 char *类型指针对string对象赋值
- 
string对象有成员函数:const char *c_str(),返回的是字符串指针
- 
如果 s是一个string对象,对其执行const char *p = s.c_str(),当s的内容改变时,p可能会失效,因为s的位置可能发生改变#include<iostream> #include<cstring> #include<string> using namespace std; int main() { string s; char str1[20] = "the flower of war"; char str2[20] = "hhh"; char *p = str1; s = p; cout<<"s:"<<s<<endl; strcat(str2, s.c_str()); cout<<"str2:"<<str2<<endl; return 0; }
常用字符串操作库函数
cstring中声明:
char *strcat(char *dest, const char *src),返回dest
char *strchr(const char *src, int c),寻找c在src中第一次出现的位置,找到则返回位置指针,否则返回NULL
int strcmp(const char *s1, const char *s2),比较大小
char *strcpy(char *dest, const char *src),复制
int strlen(const char *src),求长度
char *strlwr(char *str),字母转小写
char *strupr(char *str),字母转大写
char *strncat(char *dest, const char *src, int n),连接前n个字符到dest
类似有:strncpy, strncmp
cstdlib中声明:
atoi:字符串转整数
atof:字符串转浮点数
itoa:整数转字符串,char *itoa(int value, char *string, int radix)
九、 void指针和内存操作库函数
定义及特点:
指针的类型为void *
- 可以用任何类型的指针对其初始化
- 主要用于内存复制
- sizeof()及各种指针运算不适用于空指针
库函数
在cstring中声明
void *memset(void *dest, int ch, int n),将ch复制到dest前n个字节中
void *memcpy(void *dest, void *src, int n),将src的开始n个字节复制到dest中
示例
#include<iostream>
using namespace std;
void *myMemcpy(void *dest, const void *src, int n)
{
    char *pDest = (char *)dest;//必须先将形参进行强制类型转换
    char *pSrc = (char *)src;
    for(int i = 0; i < n; ++i)
        *(pDest + i) = *(pSrc + i);
    return dest;
}
int main()
{
    char szName[10] = "abcdsedf";
    char destName[10];
    myMemcpy(destName, szName,5);
    cout<<szName<<endl;
    for(int i = 0; i < 5; ++i)
        cout<<destName[i];
}
十、 函数指针
定义:
类型名 (*指针变量名)(参数类型1,参数类型2,……)
赋值及调用:
- 
可以用一个原型匹配的函数的名字给一个函数指针赋值 
- 
调用格式:函数指针名(实参表) #include<iostream> using namespace std; void PrintMin(int a, int b) { if(a < b) cout<<a; else cout<<b; } int main() { int x = 4, y = 1; void (*pf)(int ,int) = PrintMin; pf(x, y); return 0; }
应用
qsort()函数
原型:void qsort(void *base, int nelem, unsigned int width, int (*pfCompare)(const void *, const void *))
其中比较函数的原型:int 函数名(const void *elem1, const void *elem2)
注意:
- 返回值必须是int
- 两个参数的类型必须都是const void *
- 假设是对int排序的话,如果是升序,那么就是如果a比b大返回一个正值,小则负值,相等返回0,其他的依次类推
#include<iostream>
#include <cstdlib>
using namespace std;
//比较函数可以根据自己的需求写,其作用相当但不限于
//使用sort()时的运算符重载
int myCompare(const void *elem1, const void *elem2)
{
   unsigned int *p1, *p2;
   p1 = (unsigned int *)elem1;
   p2 = (unsigned int *)elem2;
   return (*p1 % 10) - (*p2 % 10);
}
const int NUM = 5;
int main()
{
   unsigned int a[NUM] = {8,123,11,10,4};
   qsort(a, NUM, sizeof(unsigned int), myCompare);
   for(int i = 0; i < NUM; ++i)
       cout<<a[i]<<endl;
   return 0;
}
十一、 指针域动态内存分配
使用方法:
指针类型 *p = new 指针类型(int *p = new int)
指针类型 *p = new 指针类型[空间大小](int *p = new int[N]),分配到N*sizeof(T)的空间
注意
- 分配空间失败时,系统会抛出异常
- 动态分配的内存使用结束后要释放,方法为:delete 指针,delete [ ] 指针
- 释放一个指针后,不会使指针的值变为NULL
十二、 二阶指针
指向指针的指针,大小永远为4字节,对应多维数组
十三、指针数组
定义:
T *a[N]
数组中每个元素的类型是T *,a的类型是T **
示例:
#include<iostream>
using namespace std;
int main()
{
    char **p = NULL;
    char *countries[] = {"China","USA","Japan","France"};
    p = countries;
    for(int i = 0; i < 4; ++i)
        cout<<*(p + i)<<endl;
    cout<<*((*p) + 1);
}
-------------------------------------------
个性签名:只要想起一生中后悔的事,梅花便落满了南山
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号