当前位置: 首页 > news >正文

宁波网站建设果核网站优化查询

宁波网站建设果核,网站优化查询,网站开发需要注意的,阿拉丁建站系统一、字符指针 int main() {char ch w;char* pc &ch;//pc就是字符指针//const char *p "abcdef";//这里其实是把字符串"abcdef"的首地址放入了指针p中//*p w;//这是错误的无法修改值(可以看到这里绿色波浪线警告)char arr[] …
一、字符指针
int main()
{char ch = 'w';char* pc = &ch;//pc就是字符指针//const char *p = "abcdef";//这里其实是把字符串"abcdef"的首地址放入了指针p中//*p = 'w';//这是错误的无法修改值(可以看到这里绿色波浪线警告)char arr[] = "abcdef";//创建了一个arr数组,里面存了字符串char* p = arr;*p = 'w';//此时这里的首元素可以被修改printf("%s\n", arr);return 0;
}

可以发现,通过字符指针 p ,将数组arr首元素a改为了w

而创建指针,直接指向字符串,是没法修改的

因为p里面存储的是,字符串abcdef的首地址

 

仔细比较二者之间的区别

int main()
{char str1[] = "hello bit.";char str2[] = "hello bit.";//这里字符型数组 str1[]和str2[]是分别创建了两块不同的空间,来存放相同的hello bit.内容,//这两块空间的起始地址不同,所以str1和str2代表的首元素地址也不同。const char* str3 = "hello bit.";const char* str4 = "hello bit.";//这里是创建了两个符号型指针str3和str4指向了同一块空间hello bit.的首地址//所以指针str3和str4的地址相同if (str1 == str2)printf("str1 and str2 are same\n");elseprintf("str1 and str2 are not same\n");//str1 and str2 are not sameif (str3 == str4)printf("str3 and str4 are same\n");elseprintf("str3 and str4 are not same\n");//str3and str4 are samereturn 0;
}
        这里str3str4指向的是一个同一个常量字符串。C/C++会把常量字符串存储到单独的一个内存区域,当 几个指针。指向同一个字符串的时候,他们实际会指向同一块内存。但是用相同的常量字符串去初始化 不同的数组的时候就会开辟出不同的内存块。所以str1str2不同,str3str4不同。

 

 

二、 指针数组
int arr1[10]; //整形数组 - 存放整型的数组
char arr2[4]; //字符数组 -存放字符的数组
那么指针数组 - 存放指针的数组
char* arr3[5];//

1. 指针数组举例

int main()
{//指针数组:是一个存放指针的数组。char* arr[] = { "abcdef", "hehe", "qwer" };//数组里每一个元素,都是字符串的首地址,指针int i = 0;for (i = 0; i < 3; i++){printf("%s\n", arr[i]);//arr[i] <=> *(arr+i)}return 0;
}

通过指针数组里,每个元素(首元素地址 - 指针),循环打印出数组里完整的字符串

2.用一维数组模拟实现二维数组
int main()
{//创建3个一维数组int arr1[] = { 1,2,3,4,5 };int arr2[] = { 2,3,4,5,6 };int arr3[] = { 3,4,5,6,7 };//arr[i] == *(arr+i)//创建arr指针数组 ,是一个存放整型指针的数组int* arr[] = { arr1, arr2, arr3 };//将3个一维数组的首元素地址(指针)存储int i = 0;for (i = 0; i < 3; i++){int j = 0;for (j = 0; j < 5; j++){//printf("%d ", arr[i][j]);printf("%d ", *(arr[i]+j));//arr[i]遍历一维数组,arr[i][j]遍历得到一维数组里的每个元素,}printf("\n");}return 0;
}

 

 

三、数组指针
整形指针: int * pint; 能够指向整形数据的指针。
浮点型指针: float * pf; 能够指向浮点型数据的指针。
那数组指针应该是:能够指向数组的指针。

//p1, p2分别是什么?

int *p1[10];  //指针数组

int (*p2)[10];//数组指针
如果容易混淆,可以试着这样分辨:
1)int *p1[10];  去掉命名为 int * [10] ,可以发现是一个拥有10个元素的数组,该数组里每个元素的类型是 int * 也就是整型指针类型 ,最后结合起来就是,指针数组
2)int (*p2)[10];
//解释:p先和*结合,说明p是一个指针变量,然后指着指向的是一个大小为10个整型的数组。所以p是一个 指针,指向一个数组,叫数组指针
//这里要注意:[]的优先级要高于*号的,所以必须加上()来保证p先和*结合
简单来说,指针p先和谁结合,他就是什么东西
int *p1[10] 先和 [] 结合,则为数组(然后是int * ,类型为整型指针)则为指针数组
int (*p2)[10] 先和*结合 ,则为指针(然后是int [], 整型数组)则为数组指针
1.&数组名VS数组名

arr 和 &arr 有什么区别?

数组名绝大部分情况下是数组首元素的地址
但是有2个例外
1. sizeof(数组名) - sizeof内部单独放一个数组名的时候。

 sizeof(arr) - 此时数组名表示的整个数组,计算得到的是数组的总大小
2. &arr  - 这里的数组名表示整个数组,取出的是整个数组的地址,从地址值的角度来讲和数组首元素的地址是一样的,但是意义不一样

int main()
{int arr[10] = { 0 };printf("%d\n", sizeof(arr)); // 此时arr表示整个数组,计算得到整个数组的内存大小 - 40字节printf("%p\n", arr);//int * //arr数组名通常为首元素地址printf("%p\n", arr+1);//首元素地址 +1 ,指针往后移动一个int长度(4字节)printf("%p\n", &arr[0]);//int* //取首元素地址printf("%p\n", &arr[0]+1);//首元素地址 +1 ,指针往后移动一个int长度(4字节)printf("%p\n", &arr);//int(*)[10] //取数组地址 - 此时地址代表整个数组printf("%p\n", &arr+1);//数组地址+1,跳过整个数组(移动了40个字节)int (*p)[10] = &arr;//p是一个数组指针//int(*)[10]return 0;
}

之所以说 arr 和arr[0]是首元素地址,是因为+1之后它们都只跳过一个整型,4个字节

而&arr +1后跳过了整个数组,40个字节(看16进制末尾两个数字,68-40=28H,换算成十进制,2*16^1 + 8*16^0 = 32+8 =40 )

从而推断它们指针的类型为  :

arr 和 arr[0] - int* 整型指针(+1跳过一个整型)

&arr  - int (*)[]  数组指针 (+1跳过整个数组)


 2.数组指针的运用

int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int sz = sizeof(arr) / sizeof(arr[0]);int (* p)[10] = &arr;//数组指针 - 指向arr整个数组int i = 0;//p  --- &arr//*p --- *&arr//*p --- arr//虽然对,但是不推荐//for (i = 0; i < sz; i++)//{//	printf("%d ", (*p)[i]);//*p解引用数组指针,得到arr数组,再通过下标i得到arr数组的每个元素//}//虽然对,但是不推荐//for (i = 0; i < sz; i++)//{//	printf("%d ", *((*p) + i));//因为p - &arr , *p - arr,arr即首元素地址,arr[i] <=> *(arr+1)//	//所以,得到*((*p)+1)//}//使用指针来访问//int* p = arr;//for (i = 0; i < sz; i++)//{//	printf("%d ", *(p + i));//}//下标的形式访问数组//for (i = 0; i < sz; i++)//{//	printf("%d ", arr[i]);//}return 0;
}

 打印出数组的内容:

1.最简单的办法就是通过下标 和 指针

 

2.通过数组指针访问数组元素(不太推荐)

有点杀鸡用牛刀的感觉,没有必要。

上面说过,数组指针是一个指向数组的指针,+1就跳过整个数组。而我们仅仅是想要打印数组的每个元素而已,就用下标或者普通的整型指针就可以了。

但是也可以试试用数组指针

1)第一种写法:解引用 数组指针 得到数组,再通过下标访问元素

int(*p)[10] = &arr  , p的值为数组地址&arr,*p解引用一次,*(&arr)得到数组arr,

数组arr[]用下标再去访问每个元素,实现代码

 2)第二种写法:解引用 数组指针 得到数组,再通过普通整型指针访问元素

同样的

     p  --- &arr
    *p --- *&arr
    *p --- arr

*p得到首元素地址,(*p)+1 地址+1,移动一个整型,再用  *((*p)+1 ) 再对整个地址解引用,得到元素

 

四、数组传参和指针传参
1.一维数组传参 (形参:数组 或者 指针)
//一维数组传参,形参是数组
void print1(int arr[10], int sz)
{int i = 0;for (i = 0; i < sz; i++){printf("%d ", arr[i]);}printf("\n");
}
//一维数组传参,形参是指针
void print2(int *arr, int sz)
{int i = 0;for (i = 0; i < sz; i++){//printf("%d ", arr[i]);printf("%d ", *(arr+i));}printf("\n");
}
int main()
{int arr[10] = {1,2,3,4,5,6,7,8,9,10};int sz = sizeof(arr) / sizeof(arr[0]);print1(arr, sz);printf("\n");print2(arr, sz);return 0;
}

 

2.二维数组传参(形参是 二维数组 或者 数组指针)

//二维数组传参,形参是 二维数组
void print1(int arr[3][5], int r, int c)
{int i = 0;for (i = 0; i < 3; i++){int j = 0;for (j = 0; j < 5; j++){printf("%d ", arr[i][j]);}printf("\n");}
}
//二维数组传参,形参是 数组指针 - 指向第一个一维数组的指针
void print2(int(*arr)[5], int r, int c)
{int i = 0;for (i = 0; i < 3; i++){int j = 0;for (j = 0; j < 5; j++){//printf("%d ", *(*(arr + i) + j));//arr[i]printf("%d ", arr[i][j]);//arr[i]}printf("\n");}
}
int main()
{int arr[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};//二维数组的数组名,也表示首元素的地址//二维数组的首元素是第一行//首元素的地址就是第一行的地址,是一个一维数组的地址print1(arr, 3, 5);printf("\n");print2(arr, 3, 5);return 0;
}

1)二维数组传参,形参是 二维数组

       int arr[3][5]传上去的是首元素的地址,也就是第一个一维数组的地址。

 arr[i]得到每一个一维数组, arr [i][j]进而得到一维数组里的每个元素,这样,二维数组里每个元素便得到了 

2)二维数组传参,形参是 数组指针 - 指向第一个一维数组的指针

int(*arr)[5] 传上去的是数组指针,指向第一个一维数组的首元素地址,同理遍历得到每个元素的地址

 

五、 函数指针
函数指针:指向函数的指针
&函数名 得到函数的地址
1.函数指针
void test()
{
printf("hehe\n");
}
//下面pfun1pfun2哪个有能力存放test函数的地址?
void (*pfun1)();
void *pfun2();
pfun1可以存放。pfun1先和*结合,说明pfun1是指针,指针指向的是一个函数,指向的函数无参 数,返回值类型为void
int Add(int x, int y)
{return x + y;
}
int main()
{//printf("%p\n", &Add);//printf("%p\n", Add);//pf就是函数指针int (* pf)(int, int) = Add;//函数的地址要存起来,就得放在【函数指针变量】中int ret = (*pf)(3, 5);//int ret = Add(3, 5);//int ret = pf(3, 5);printf("%d\n", ret);//&函数名得到就是函数的地址printf("%p\n", Add);printf("%p\n", &Add);return 0;
}

 

2.可以给函数指针重命名

typedef int* ptr_t;
typedef void(*pf_t)(int);//将void(*)(int)类型重新起个别名叫pf_t

typedef void(*pf_t2)(int);//pf_t2是类型名
void(*pf)(int);//pf是函数指针变量的名字
 

3.两段有趣的代码(眼前一黑)
//代码1
( *void ()( ) )0 )( );
该代码是一次函数调用
1. 将0强制类型转换void (*)() 类型的函数指针
2. 这就意味着0地址处放着一个函数函数没参数,返回类型是void
3. 调用0地址处的这个函数
 
//代码2
void (*signal(int , void (*)(int) ) )( int );
gai代码是一个函数的声明
    函数的名字是signal
    signal函数的参数第一个是int类型,第二个是void(*)(int)类型的函数指针
    该函数指针指向的函数参数是int,返回类型是void
     
    signal函数的返回类型也是一个函数指针
    该函数指针指向的函数参数是int,返回类型是void
    
    void (* signal(int, void(*)(int)))(int)
6. 函数指针数组
7. 指向函数指针数组的指针
8. 回调函数
9. 指针和数组面试题的解析
http://www.khdw.cn/news/6443.html

相关文章:

  • 自己做的网站能备案吗免费企业网站建设流程
  • 网站备案 年审奉化seo页面优化外包
  • 网站建设氺金手指排名11网址域名
  • 在国外做盗版网站seo入门培训学校
  • 成品网站怎么新建网页全国疫情高峰时间表最新
  • 专业建站推广服务google免费入口
  • 网站制作(信科网络)b2b外贸接单平台
  • 模具 东莞网站建设百度手机版
  • 自有服务器怎么做网站备案如何推广app
  • 网站png小图标怎么做百度指数官方版
  • wordpress外贸商城主题西安百度关键词优化排名
  • 哪个网站做音基的题不花钱搜狗站长平台验证网站
  • 信息门户网站是什么搜索引擎营销优化的方法
  • 药品推荐网站模板seo和点击付费的区别
  • co域名哪些网站南宁seo咨询
  • 做宣传单赚钱的网站线上营销活动方案
  • 聊城做wap网站哪儿好360建站系统
  • 建筑直聘网合肥seo搜索优化
  • 网站建设分金手指科捷11北大青鸟培训机构官网
  • 有没有什么好的网站地推app接任务平台
  • 临沂做网站哪家好5118营销大数据
  • 服装企业网站模版优化网站怎么真实点击
  • 如何做服装微商城网站建设营销技巧在线完整免费观看
  • 专门做盗文网站的公司推销
  • 黄山旅游住宿攻略肥城市区seo关键词排名
  • 怎样做电商谷歌排名优化入门教程
  • 怎样为网站做外链长沙推广引流
  • 企业自助建站系统怎么建域名是什么
  • 常州网站建设思创网络百度我的订单查询
  • 潍坊高端网站开发百度关键词搜索怎么做