指针https://blog.csdn.net/qq_41035588/article/details/79673674
int **num
指针的类型:去掉num,int**
指针所指向的类型:去掉*num,int*
指针存储的值:32bit系统(4byte),指针是指向内存某块区域的首地址,内存地址32bit长,即指针本身所占据的内存区,永远是4byte
(1)int*ptr; //指针所指向的类型是int
(2)char*ptr; //指针所指向的的类型是char
(3)int**ptr; //指针所指向的的类型是int*
(4)int(*ptr)[3]; //指针所指向的的类型是int()[3]
(5)int*(*ptr)[4]; //指针所指向的的类型是int*()[4]
// test.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
int array[20]={0};
int *ptr=array;
for(int i=0;i<20;i++)
{
(*ptr)++;
ptr++;//add 1,sizeof(int)=4byte,加指针所指向数据类型的大小
cout<<array[i]<<endl;
}
system("pause");
return 0;
}
https://blog.csdn.net/zmz971751504/article/details/79363126
数组名可以看作指针。
&是取地址运算符,*是间接运算符。
char a[20]="You_are_a_girl"; //a++,and sizeof(char)=1byte
cout<<&a<<endl;//00FAFDB0
int *ptr=(int *)a;
ptr++; //ptr add 1,add sizeof(int)=4byte
cout<<ptr<<endl;//00FAFDB4
char a[20]=" You_are_a_girl";
char *p=a;
char **ptr=&p;
printf("p=%d\n",p); //address1
printf("ptr=%d\n",ptr); //address2
printf("*ptr=%d\n",*ptr); //address1
printf("**ptr=%c\n",**ptr); //none
ptr++;//error ,add 1, add sizeof(char*)
int a,*b,**c;
**c=*b=a
*c= b=&a
c=&b
int array[10]={0,1,2,3,4,5,6,7,8,9},value;
value=array[0]; //也可写成:value=*array;
value=array[3]; //也可写成:value=*(array+3);
value=array[4]; //也可写成:value=*(array+4);
char *str[3]={ //二维
"Hello,thisisasample!",
"Hi,goodmorning.",
"Helloworld"
};
char s[80];
strcpy(s,str[0]); //也可写成strcpy(s,*str); sizeof(char[3])=3byte
cout<<s<<endl;
strcpy(s,str[1]); //也可写成strcpy(s,*(str+1));
cout<<s<<endl;
strcpy(s,str[2]); //也可写成strcpy(s,*(str+2));
cout<<s<<endl;
int array[10];
int (*ptr)[10]; //ptr指针类型int*[10],指向数据类型int[10]
ptr=&array;
sizeof(int(*)[10])==4 或者 sizeof(ptr)==4 说明指针本身占4byte
因为 sizeof(int[10])==40
所以,ptr+1就是ptr+40
struct MyStruct
{
int a;
int b;
int c;
};
struct MyStruct ss={20,30,40}; //声明了结构对象ss,并把ss 的成员初始化为20,30 和40。
struct MyStruct *ptr=&ss; //声明了一个指向结构对象ss 的指针。它的类型是 MyStruct *,它指向的类型是MyStruct。
int *pstr=(int*)&ss; //声明了一个指向结构对象ss 的指针。但是pstr和它被指向的类型ptr 是不同的。
访问方法:
ptr->a; //指向运算符,或者可以这们(*ptr).a,建议使用前者
ptr->b;
ptr->c;
错误访问方法:
*pstr; //访问了ss 的成员a。
*(pstr+1); //访问了ss 的成员b。
*(pstr+2) //访问了ss 的成员c。
原因:
int array[3]={35,56,37};
int *pa=array; //通过指针pa 访问数组array 的三个单元的方法是:
*pa; //访问了第0 号单元
*(pa+1); //访问了第1 号单元
*(pa+2); //访问了第2 号单元
从格式上看倒是与通过指针访问结构成员的不正规方法的格式一样。
所有的C/C++编译器在排列数组的单元时,总是把各个数组单元存放在连续的存储区里,
单元和单元之间没有空隙。但在存放结构对象的各个成员时,在某种编译环境下,
可能会需要字对齐或双字对齐或者是别的什么对齐,需要在相邻两个成员之间加若干个"填充字节",
这就导致各个成员之间可能会有若干个字节的空隙。
所以即使*pstr 访问到了结构对象ss 的第一个成员变量a,也不能保证*(pstr+1)就一定能访问到结构成员b。
因为成员a 和成员b 之间可能会有若干填充字节,说不定*(pstr+1)就正好访问到了这些填充字节呢。
这也证明了指针的灵活性。要是你的目的就是想看看各个结构成员之间到底有没有填充字节,
int fun(char *s,int len)
{
int num=0;
for(int i=0;i<len;i++)
{
num+=*s;s++;
}
return num;
}
int _tmain(int argc, _TCHAR* argv[])
{
int a;
char str[]="abcdefghijklmn";
//char *b=str;
a=fun(str,sizeof(str)); //大小是15,末尾有个0
return 0;
}
void fun(char*s)
{
char c;
c=*(s+3);*(s+3)=*(s+0);*(s+0)=c;
c=*(s+2);*(s+2)=*(s+1);*(s+1)=c;
}
int _tmain(int argc, _TCHAR* argv[])
{
int a=125;
int *b=&a;
fun((char*)&a); //指针类型强制转换
//实参&a 的结果是一个指针,它的类型是int *,它指向的类型是int。形参这个指针的类型是char *,它指向的类型是char。
//这样,在实参和形参的结合过程中,我们必须进行一次从int *类型到char *类型的转换。
cout<<a<<endl;//为什么是32bit的地址?
fun((char*)b);
cout<<*b<<endl;//125
cout<<a<<endl;//125
}
//给指针赋地址值
unsigned int a;
char *ptr; //TYPE 是int,char 或结构类型等等类型。
a=20000; //N 必须代表一个合法的地址;
ptr=(char*)a;
cout<<ptr<<endl;
指针安全;
char s='a';
int *ptr;
ptr=(int *)&s;
*ptr=1298;
指针ptr 是一个int *类型的指针,它指向的类型是int。它指向的地址就是s 的首地址。在32 位程序中,s 占一个字节,int 类型占四个字节。最后一条语句不但改变了s 所占的一个字节,还把和s 相临的高地址方向的三个字节也改变了。这三个字节是干什么的?只有编译程序知道,而写程序的人是不太可能知道的。也许这三个字节里存储了非常重要的数据,也许这三个字节里正好是程序的一条代码,而由于你对指针的马虎应用,这三个字节的值被改变了!这会造成崩溃性的错误。
让我们再来看一例:
例十九:
[cpp] view plain copy
char a;
int *ptr=&a;
ptr++;
*ptr=115;
该例子完全可以通过编译,并能执行。但是看到没有?第3 句对指针ptr 进行自加1 运算后,ptr 指向了和整形变量a 相邻的高地址方向的一块存储区。这块存储区里是什么?我们不知道。有可能它是一个非常重要的数据,甚至可能是一条代码。
而第4 句竟然往这片存储区里写入一个数据!这是严重的错误。所以在使用指针时,程序员心里必须非常清楚:我的指针究竟指向了哪里。在用指针访问数组的时候,也要注意不要超出数组的低端和高端界限,否则也会造成类似的错误。
在指针的强制类型转换:ptr1=(TYPE *)ptr2 中,如果sizeof(ptr2的类型)大于sizeof(ptr1 的类型),那么在使用指针ptr1 来访问ptr2所指向的存储区时是安全的。如果sizeof(ptr2 的类型) 小于sizeof(ptr1 的类型),那么在使用指针ptr1 来访问ptr2 所指向的存储区时是不安全的。至于为什么,读者结合例十八来想一想,应该会明白的。