赞
踩
<基类型>*<指针变量>
:void*
:可以作为所有指针的接口,void的指针类型可以被赋值为任何类型的指针。int a = 9;
int* p = &a;
int* q = p;//指向同一地址
*p = 8;
void* p1 = p;
double* q1;
p1 = q1;//是允许的
typedef int* Pointer;
// p和q均为指针变量
Pointer p, q;
//等价于
int*p, q;//主要q是int不是指针
int *p = (int *)0x080483A0;
int *p = 0x080483A0;
&
*
int x=9;
int *p;
p = &x;
*p = 1000;
char *p = (void*)
nullptr
:作为不依赖任何值的指针。Pointer p = nullptr;
//ANSI C
#define NULL ((void*)0)
//C++
#define NULL 0
//以下的情况,会调用int的重载版本
void func(int);
void func(char*);
func(NULL);
p = &d//error,不同类型
int* p ;
double *q;
//注意这里的++隐含的意义是加上一个sizeof(type)
p++;//p的值加4 (sizeof(int))
q++;//q的值加8 (sizeof(double))
int a[10] = { 1,2,3,4,5,6,7,8,9,10 };
int *p = &a[0];
for (int i = 0; i < 10; i++) {
cout << *p++ << " ";//指针移动
cout << *p << " ";
cout << *(p + i) << endl;//指针不动
for (int j = 0; j < 10; j++) {
cout << a[j] << " ";
}
cout << endl;
}
int x=1;
int *p=&x;
cout << p; // p的值 (x的地址)
cout << *p; // p所指向元素的值
char *p = "ABCD";//有问题
char *p = (char *) "ABCD"//没有问题,但是并不推荐这么使用
cout << p;//p指向的字符串,即: ABCD
//调用ostream& operator << (ostream&, char*)
//调用时,operator << (cout,p);
cout << *p; //p指向的字符,即:A
cout << (int *)p //p的值
void *p;
void *any_pointer;
int x;
double y;
any_pointer = &x;
any_pointer = &y;
*any_pointer //error,对void*类型的指针取值的时候,一定要先转换为对应具体类型的指针后再进行取值
*((int *)any_pointer) //OK
*((double *)any_pointer) //OK
//例:将某块内存清零,按照bit进行处理! void memset ( void *pointer, unsigned size) { char *p = (char *)pointer; for (int k=0;k<size;k++) *p++ = 0; } void memcpy(void *des, void *src, unsigned size) { //进行内存拷贝 char *sp = (char *)src; char *dp = (char *)des; for (int i = 0; i < size; i++) { *dp++ = *sp++; } } void showBytes(void *q, int n)//查看内存 { cout << n << endl; unsigned char *p = (unsigned char *)q; for (int i=0; i<n; i++){ cout << (void *)(p+i) << " : "<< setw(2) << hex << (int)*(p+i) << " "; if ( (i+1) %4 ==0 ) cout << endl; } cout << dec << endl; }
memset(void *s,int ch,size_t n);
struct A{...};
A a;
memset(&a,sizeof(A));
int A[100];
memset(&a[0],100);
int arr[100] = {0};
memset(arr,sizeof(arr));
memset(arr,100 * sizeof(int));//arr作为参数传递时
const <类型> * <指针变量>
const int c = 0; const int *cp; int y = 1; int *q; cp = &c; √//cp 可以指向 c q = &y; √//q 可以指向 y *cp = 1 ; ×//*cp 是一个常量,不可以赋值 *q = 2 ; √//变量指针可以指向变量 cp = &y; √//常量指针可以指向变量,传递的是y的空间,并且对于y的这个空间只是可读的,安全的 q = &c; ×//不可以的,因为q的修改可以间接修改c,所以编译器不允许 void print(int *p){ cout << *p << endl; } const int c = 8; print(c) ;//不可以被调用的 print(&c);//C++赋给的权利,在调用的时候除去常量的特性,这个&是强制类型转换,取消常量特性 void print(const int *p){//如此修改就可以大量复用 //常量使用者和变量使用者都可以使用 cout << *p << endl; }
void Fun1(int *p){
//*p 读写
}
void Func2(const int *p){
//*p 只读
}
int x=10; int *p = &x; cout << " x " << &x << x << endl; cout << " p " << &p << p << endl; cout << "*p " << p << *p << endl;//*p = x //Name Addr Value //x 0012FF7C 10 //p 0012FF78 0012FF7C //*p 0012FF7C 10 const int c = 128; int * q = const_cast<int *>(&c);//强制类型转换 *q = 111;//企图通过变量指针修改常量 cout << " c " << &c << c << endl; //这里的c是符号常量,所以在编译的时候,符号常量已经变为128了,相当于define cout << " q " << &q << q << endl; cout << "*q " << q << *q << endl; //Name Addr Value //c 0012FF74 128 //q 0012FF70 0012FF74 //*q 0012FF74 111 //why?为什么这个单元对于c是128,而对于q这个单元是111,见上面,确实已经修改成111了 void showBytes(void *q, int n)//查看内存 { cout << n << endl; unsigned char *p = (unsigned char *)q; for (int i=0; i<n; i++){ cout << (void *)(p+i) << " : "<< setw(2) << hex << (int)*(p+i) << " ";//这里是很重要的 if ( (i+1) %4 ==0 ) cout << endl; } cout << dec << endl; //cout利用控制符dec、hex和oct,分别输出十进制、十六进制和八进制显示整数 }
<类型>* const<指针变量>
int x,y;
int *const p = &x;//p就始终如一的指向x这个单元
//同时这个单元是可变的
p = &y;//错误的
int A[2]; typedef int T[2];//相当于int[2] T double (*fp)(int);//fp是指向函数的指针 double (int) * fp;//上面的理解,不能这么写 double *fp (int);//符合C++语法,fp是一个函数,参数是int,返回值是double* typedef double (*FP)(int); typedef double (*)(int) FP;//上面那个的理解 double f(int x){} int g(){} void main(){ FP fp; fp = f; //相当于fp = &f;为函数指针赋值 (*fp)(10);//相当于fp(10); fp = g; //Error }
#include <iostream> using namespace std; int add(int a,int b) {return a+b;} int minus(int a,int b) { return a-b; } void main(){ char c; int op1, op2; cin >> c; while (c != '#'){//#是终止符 //类似Windows中的一些时间的参数 //以下对应getTask() cin >> op1; cin >> op2; //以下对应executeTask() switch (c){ case '+': cout << add(op1,op2) << endl; break; case '-': cout << minus(op1,op2) << endl; break; } cin >> c; } }
//剥离IO getMessage,和操作系统一样 struct Task{ int op1; int op2; OPRAND_TYPE op; }; enum OPRAND_TYPE { END=-1, ADD, MINUS}; int add(int a,int b) { return a+b; } int minus(int a,int b) { return a-b; } //add 和 minus 抽象成函数指针 typedef int (*FP)(int, int); OPRAND_TYPE getTask(Task &task){ char c; cin >> c; switch (c){ case '#': task.op = END; break; case '+': task.op = ADD; cin >> task.op1; cin >> task.op2; break; case '-': task.op = MINUS; cin >> task.op1; cin >> task.op2; break; } return task.op; }
//抽离计算部分第一版 //如何修改可以使得无论多少个任务都不导致如下方法的修改 void executeTask(const Task task){ FP fp; switch(task.op){ case ADD: fp = app;break; case MINUS : fp = minus;break; } fp(task.op1,task.op2) } //抽离计算部分第二版代码 //Table Driven FP op[2] = {add, minus}; void executeTask(const Task task){ op[task.op](task.op1,task.op2); }
void main()
{
Task task;
while (getTask(task) != END)
executeTask(task);//call by reference
}
//组织改善:利用define,集合IDE
//完成时间处理、协议解析、服务框架
//第一版实现冒泡排序,默认数据类型为int
void MySort(int A[],unsigned int num)
{
for (unsigned i=1;i<num;i++){
for (unsigned j=0;j<num-i;j++)
if(A[j] > A[j+1]){
int tmp = A[j];
A[j] = A[j+1];
A[j+1] = tmp;
}
}
}
void MySort(void *base, unsigned width,unsigned num,int(*compare)(const void *elem1,const void *elem2)){//这部分意味着我们必须要传入一个compare的函数
char *A = (char*) base;//void* 是不可以进行移动的
char *tmp = (char*)malloc(width);//申请堆空间
for (unsigned i=1;i<num;i++){
for (unsigned j=0;j<num-i;j++)
if (compare(A + j * width,A + (j+1)*width) > 0){//序关系由函数确定
memcpy(tmp,A + j * width,width);//tmp = A[j]
memcpy(A + j * width,A+(j+1)*width,width);//A[j] = A[j+1]
memcpy(A + (j + 1) * width,tmp,width);//A[j + 1] = tmp
}
}
free(tmp);//释放这部分的空间
}
struct TStudent { char name[20]; int age; }; TStudent student[] = {...}; int num = sizeof(student)/sizeof(student[0]);//计算出来有多少个 int width = sizeof(student[0]);//计算出来宽度 MySort(student, width, num, icompare); MySort(student, width, num, scompare); //compare不用给大小,因为compare是调用者给出的,显然不用给出width了 //call back function:在运行中反过来调用 int icompare(const void *elem1, const void *elem2){ TStudent *p1 = (TStudent *)elem1; TStudent *p2 = (TStudent *)elem2; return p1->age - p2->age; } int scompare(const void *elem1, const void *elem2){ TStudent *p1 = (TStudent *)elem1; TStudent *p2 = (TStudent *)elem2; return strcmp(p1->name, p2->name); }
template <class T> void MySort(T A[],unsigned T num) { for (unsigned i=1;i<num;i++){ for (unsigned j=0;j<num-i;j++) if(A[j] > A[j+1]){ T tmp = A[j]; A[j] = A[j+1]; A[j+1] = tmp; } } } int a[100]; sort(a,100);//此时的T转换成为int(对应类型) class C{...} C a[300]; sort(a,300);//编译器可以将其变为C,但是有问题 //我们需要重载>运算符
直接给出即可
#include <math.h>
double integrate(double (*f)(double),double a, double b)
{ … f(x), a , b, … }
double my_func(double x){ … }
void main(){
integrate(sin,0,1);
integrate(cos,1,2);
integrate(my_func,1,10);
}
*(p+i)
:p不移动*(p++)
:p移动int *p = a
:这时候a表示的是数组的首地址
int * const
void f(int A[],int n){
sizeof(A)/sizeof(A[0])//始终1,就是地址
}
sizeof(a)
:是数组的整个块的大小sizeof(a[0])
:是数组中一个元素的大小int *p = &a[0][0]
:p指向的是T类型for(int i = 0;i < 12;i++){
*(p++) = 9;//越界了(对应一维数组的越界),但是二维数组没有越界
}
typedef int T[2];
T a[6];//int a[6][2]
T *q = a;
//不使用T的方法
int[2] *q;
int a[10];
sizeof(a);//数组大小
sizeof(a+1);//内存地址的长度,单位bytes
int *p;
int i=0;
p = &a[0] == p = a;
a[i] == *(a+i) == *(p+i) == p[i]
&a[i] == a+i == p+i == &p[i]
int b[20][10];
//等价于
//typedef int T[10];
//T b[20];
int *q;
q = &b[0][0];// q = b[0]
//b[i][j] == *(&b[0][0] + i*10 + j) == *(q + i * 10 + j) == q[i*10 + j]
T * p;//int (*p)[10];
p = &b[0];// p = b
//b[i][j] == *(*(b+i)+j) == *(*(p+i)+j) == p[i][j]
#include <iostream.h>
int maximum(int a[], int n)
{
int max = 0;
for(int k=0;k<n;k++)
if (a[k] > max)
max = a[k];
return max;
}
void main()
{
int A[2][4] = { {68,69,70,71} , {85,86,87,89}};
cout << "the max grade is" << maximum(A[0],2*4);//maximum(&A[0][0],2*4) =>maximum(&A[0][0],sizeof(A)/sizeof(A[0][0]))
}
void show(int a[], int n){ for (int i=0;i<n;i++) { cout << a[i] << " "; cout << endl; } cout << endl; } void show(int a[][2], int n){ for (int i=0;i<n;i++) for (int j=0;j<2;j++) { cout << a[i][j] << " "; cout << *(a+i)+j << " :" << a[i][j] << " "; //四个换一行 if ((i*2+j+1)%4 == 0) cout << endl; } cout << endl; } void show(int a[][2][3], int n){ for (int i=0;i<n;i++) for (int j=0;j<2;j++) for (int k=0;k<3;k++){ cout << a[i][j][k] << " "; cout << *(*(a+i)+j)+k << " :" << a[i][j][k] << " "; //换行输出 if ((i*6+j*3+k+1)%4 == 0) cout << endl; } cout << endl; } void main(){ int b[12]; for (int i=0;i<12;i++) b[i] = i+1; show(b,12); //二维数组 typedef int T[2]; show((T*)b,6);//show((int (*)[2])b,6),一定有括号 //三维数组 typedef int T1[3]; typedef T1 T2[2]; show((T2*)b,2);//show((int (*)[2][3])b,2) }
main函数:int main(int argc,char * argv[],char * env[])
Eg.
ping -t 192.168.0.1
argc : 3
argv: ping / -t / 192.168.0.1
env:
char *s1[] = {"C++", "PASCAL", "FORTRAN"};
char s2[][8] = {"C++", "PASCAL", "FORTRAN"};
int printf(const char*,...)
:后面是可变参数,由调用者决定。const char*
:是调用者和被调用者之间的约定目标求Q
X = Qn + r, -n < r <= 0 Q大于X,能放下,并且是整数倍
思考:X = qn + r, 0 <= r < n
q = x/n
r = x%n
这样子就能求了
X + n - 1 = Qn + r1, 0 <= r1 < n
Qn = ((x + n - 1)/ n) * n
n 是 2 的幂次 => 左移右移都是乘以或者除以2
n = 2 的 m 次方
所以先乘以2再除以2,相当于后m为全部清0
也就等价于(x+n-1) & (~(n-1))
//platform : x86 宏的说明,这不是在库文件中已经定义了的 typedef char *va_list; #define _INTSIZEOF(x) ((sizeof(x) + sizeof(int) - 1) & ~(sizeof(int) - 1)) //alignment 偏移的大小 #define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ) #define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t))) #define va_end(ap) ( ap = (va_list)0) #include <iostream> #include <stdarg.h> using namespace std; void MyPrint(char *s, ...){ va_list marker;//拿到一个指针 va_start(marker,s);//找到参数的位置,s的位置 int i=0; char c; while ((c=s[i]) != '\0'){ if (c != '%') cout << c; else{ i++; switch (c=s[i]){ case 'f': cout << va_arg(marker,double); break; case 'd': cout << va_arg(marker,int);break; case 'c': cout << va_arg(marker,char);break; } } i++; } cout << endl; va_end(marker);//将当前指针回归原始状态 } int max(int num, ...) { va_list marker;//拿到一个指针 va_start(marker, num); int maxNum = 0; int tmp = 0; for (int i = 0; i < num; i++) { tmp = va_arg(marker, int); if (tmp > maxNum) { maxNum = tmp; } } va_end(marker);//将当前指针回归原始状态 return maxNum; } void main(){ MyPrint("double: %f integer: %d string: %c ",1.1, 100, 'A'); cout << max(5,10,20,50,30,40); }
(*p).x == p->x
void myswap(int *p1, int *p2) { int* tmp = p1; p1 = p2; p2 = tmp; } void myswap2(int &p1, int & p2) { int tmp = p1; p1 = p2; p2 = tmp; } void myswap(char **p1, char **p2) { char *tmp = *p1; *p1 = *p2; *p2 = tmp; } void main() { char *p1 =(char*) "abcd"; char *p2 =(char*) "1234"; int a = 100; int b = 200; myswap(&a, &b); cout << a << " " << b << endl;//100 200 myswap2(a, b); cout << a << " " << b << endl;//200 100 myswap(&p1, &p2); cout << p1 << " " << p2 << endl;//1234 abcd }
new <类型名> [<整型表达式>]
//--------------------------------------
int x;
int *p = new int;
delete p;
int *p = (int *)malloc(sizeof(int));
free(p);
int &a = p;
//malloc
void * malloc (unsigned int size)
p = (int *)malloc(sizeof(int)); //new int
q = (int *)malloc(sizeof(int)*20); //new int [20]
//--------------------------------------- int *p = new int[10];//分配一块连续空间 int *p = (int*)malloc(sizeof(int)*10) int (*p2)[5] = (int (*)[5])p; for (int i=0;i<10;i++) p[i] = i+1; q = new int[2][5];//错误的,没有这种写法 //想用二维数组访问,升维操作 for (int j=0;j<2;j++) { for (int k=0;k<5;k++) cout << p2[j][k] << " "; cout << endl; } //--------------------------------------- //多维数组使用构造数据类型申请内存 typedef int i5Array [5]; void main(){ i5Array *p = new i5Array [2]; for (int j=0;j<2;j++) for (int k=0;k<5;k++) p[j][k] = (j*5)+(k+1); }
//---------------------------------------
class A
A *p = new A;//调用默认构造函数
A *p = (A*) malloc(sizeof(A));//只是分配空间
//---------------------------------------
namespace std{//处理内存
typedef void (*new_handler)();
new_handler set_new_handler(new_handler p) throw();
}//不满意应对,我们可以重载方法来处理
new -- delete|delete[]
malloc -- free
int *p = new int[8];
for(int i = 0;i < 8; i ++){
*(p++) = 128;
}
delete[] p;
//很大的问题,因为p移动过,这时候指针想上看size:128,就向下归还128个字节。
struct NODE{
int content;
NODE *next;
};
NODE *head=NULL;//使用头结点
//节点初始化
NODE *p = new NODE;
p->content = _value;
p->next = NULL;
head是不可以动的
//链表为空
head = p;
//链表不为空
p->next = head;
head = p;
//表尾插入
NODE *q = head;
while (q->next != NULL)//从头结点找到尾结点
q = q->next;
q->next = p;
NODE *q = head;
while (q != NULL && q->content != a ){
q = q->next;
}
if (q != NULL){
//存在a
p->next = q->next;
q->next = p;
}else{
//不存在a
cout << "Not found!";
}
//插在链表中某结点(值为a)的前面 NODE *q1=NULL, *q2=head;//q1是q2的前一个结点 while(q2 !=NULL && q2->content != a){ q1 = q2; q2 = q2->next; } if (q2 != NULL){//存在a if(q1 == NULL){// a是第一个结点 p->next = q2; head = p; }else{// a不是第一个结点 p->next = q2; q1->next = p; } }else{//不存在a cout << "Not found!"; }
NODE *q1=NULL, *q2=head;//q1是q2前面的一个结点 while (q2 != NULL && q2->content != a){ q1 = q2; q2 = q2->next; } if (q2 != NULL) {//存在a if (q1 == NULL){ // a是第一个结点 head = q2->next; delete q2; }else{// a不是第一个结点 q1->next = q2->next; delete q2; } }else{ //不存在a cout << "Not found!"; }
struct Node{
int k;
Node *next;
} *first = NULL;
void release(){
//释放整个单向排序链
while(first != NULL){
Node *p = first;
first = first->next;
delete p;
}
}
void print(){
//打印整个单向排序链
Node *p = first;
while (p){
cout << p->k << endl;
p = p->next;
}
}
insert(Node *first, int n); void insert(int k){ Node *p = new Node; p->k = k; p->next = NULL; //创建新结点 if (!first){ //链表为空 first = p; }else if (k < first->k){ //插入在头结点 p->next = first; first = p; }else{ //插入在后面 Node *p1 = first; while (p1->next != NULL && k > p1->next->k) p1 = p1->next; p->next = p1->next; p1->next = p; } } //first作为main里面的局部变量,如下使用会有问题吗 void main(){ Node* first = NULL; insert(first,n);//有问题,值传递,不能修改first insert(&first,n);//这样子就行了 }
void delNode(int k){ if (!first) return; Node *p1 = first; if (k == first->k){ //删除头结点 first = first->next; delete p1; }//删除头结点 else{ while(p1->next != NULL&& p1->next->k != k) p1 = p1->next; if (p1->next != NULL){ Node *p = p1->next; p1->next = p->next; delete p; } } }
int &a = *p;//一旦是p的别名,就一定只能是p的别名了
void f(int &a)//利用函数副作用
int max1(int x[], int num){ int m,i; m = x[0]; for (i=1; i<num; i++) if (x[i] > m) m = x[i]; return m; } int &max3(int x[], int num){ int i, j; j = 0; for (i=1; i<num; i++) if (x[i] > x[j]) j = i; return x[j]; } int *max2(int x[], int num){ //返回的指针 int *p,*q; p = x; q = x+1; while (num > 1){ if (*q > *p) p = q; q++; num--; } return p; } int main(){ int A[16];//操作的是调用者的空间的部分 cout << max1(A,16); cout << max2(A,16);//返回的是一个地址 *max2(A,16) = -1;//将最大值修改为-1 cout << max3(A,16); max(A,16) = -1;//将最大值修改为-1 }
void swap(const int& a, const int& b)
int *p = new int(100);
int &x = *p; …… ;
delete &x;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。