大家好,欢迎来到IT知识分享网。
目录
一、数组和指针
1、指针和数组的关系
下面是一个数组int a[2][3]:
(a),(a+1)的指向如图所示:即(a),(a+1)指向的是int [3],也就是说他们是行地址
所以对于int *p ,要使的指针能够指向数组,可以使用如下方式:
p = *a; 这里的*a就是列地址)
p = &a[0][0]; (*a == &a[0][0])
p = *(a+0); (*(a+0) == *a == &a[0][0])
//通过这三种方式使得指针指向数组a,之后变可以向后移动指针来获得数组内容,即可以理解二维数组a是一个一维数组p[6]。
例如使用 :
a[2][3] = {
{1,2,3},{2,3,4}}; int *p = *a; int i = 0; for(i = 0; i < 6; i++){ printf("%d",p[i]); }
二、数组指针和指针数组
1、数组指针
除了使用上述的方式,可以使用数组指针来指向a。即用行地址来指向a。
数组指针的定义为: 数据类型 (*指针 [index])= value 相当于 数据类型[index] *p = value.
所以可以使用(注意p是变量,a相当于常量,所以不能给a赋值,在其他方面p相当于a使用)
int (*p)[3] = a;来指向a;
下面是数组指针的两个例子:
例1:
//连接前面的代码 int (*p)[3] = a; int j = 0; for(i = 0; i < 2; i++){ for(j = 0; j < 3; j++){ printf("%d",*(*(p+i)+j)); } }
例2:
int main() { char s[6][5] = {
{"ll"}, {"jj"}, {"fk"},{"lsdf"}, {"fjsl"},{"sdjf"}}; char (*ptr)[5] = s; int i ; for(i = 0; i < 6; i++){ printf("%s\n", ptr[i]); } }
2、指针数组
例如:char *ptr[6],下面是他的使用
int main() { char s[6][5] = {
{"lddd"}, {"jj"}, {"fk"},{"lsdf"}, {"fjsl"},{"sdjf"}}; char *ptr[6]; int i; for(i = 0; i < 6; i++){ ptr[i] = s[i]; } for(i = 0; i < 6; i++){ printf("%s\n", ptr[i]); } }
三、char *p 和char q[]的区别:
1.区别一
所以在使用sizeof的时候需要注意sizeof(p) 和sizeof(q)的结果不同,sizeof(p) 的值是char *指针大小,64位机为8,而sizeof(q)就是字符串大小(包括‘\0′)。
我认为要明白这两个的区别还是需要自己在电脑上实验一下,例如这样
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char *p = {"kdfj"}; char q[7] = {"jjdkj"}; printf("%ld %ld %ld\n", sizeof(p), sizeof(*p), strlen(p)); printf("%ld %ld %ld\n", sizeof(q), sizeof(*q), strlen(q)); return 0; }
你将看到如下结果:
在写这个例子的时候,我在想sizeof 和strlen 函数在计算字符串大小时候的使用,一个众所周知的区别是是否计算 ‘\0’ ,然后我进行了下面的测试:
printf("%ld %ld\n", sizeof("dls"), strlen("dls"));
我在前面的测试中用过sizeof 和 strlen 计算字符串大小,但是为什么还要这样做呢?
就是为了体会一下sizeof 在计算这四种情况的区别:
char p[4] = {“ld”}, sizeof(p) = 4; 他就该是四,因为你请求的指针常量大小就是4,
不是 够 就加 ‘\0’. 他本质是个常量,你不能用p[0] = a,来改变他的值。
char p[4] = {“lll”}, sizof(p) = 4;
char p[4] = {“dlsl”}, sizeof(p) = 4; 这里没有计算 ‘\0’ 因为他没有。
“dls” , sizeof(“dls”); sizeof (“dls”) = 4;
第三种情况,我有个疑问,到底这样做否会有问题呢?因为他没有 ’\0′ 结束,所以我进行了如下的测试:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char *p = {"kdfj"}; char q[7] = {"jjdkj"}; // printf("%ld %ld %ld\n", sizeof(p), sizeof(*p), strlen(p)); // printf("%ld %ld %ld\n", sizeof(q), sizeof(*q), strlen(q)); // printf("%ld %ld\n", sizeof("dls"), strlen("dls")); char l[4] = {"llfd"}; int i; for(i = 0; i < 6; i++){ if(l[i] != '\0') printf("l[%d]: %c\n", i, l[i]); // else{ // break; // } } char t[4] = {"ld"}; for(i = 0; i < 6; i++){ if(t[i] != '\0') printf("t[%d]: %c\n", i, t[i]); // else // { // break; // } } return 0; }
对的你没有看错,我越界访问了,我就是想这么做,来看看他有什么问题:
可以看到 t[4] 他有 ‘\0’ 因为t[2] t[3]没有输出。而 l[4] 的问题就很明显,他没有 ‘\0’, 如果打开 else语句,你可以看到如下的输出:
对的没错, 我想表达的就是不要这样用 l[4] = {“lsld”}; 还是有个 ‘\0’ 好。
2.区别二
要记住,对于 char *p = {”ls”}, {”ls”}是一个常量,常量的值是不可以改变的,但是指针变量指向是可以改变的,但是这样p[0] = ‘a’会报错,因为你在修改那个常量。
对于 char q[4] = {“fd”}; 你就可以这样改 q[0] = ‘b’;
为此 我进行了如下的测试:
int main() { char *t = {"dkk"}; char *p = {"kdfj"}; char q[7] = {"jjdkj"}; printf("*p= %s\n", p); printf("*q = %s\n", q); //p[0] = 'a'; //报错 试图修改常量的值 p = t; q[0] = 'b'; //这个就可以, q 是指针常量,对,q自己是常量, //那么他指向的空间不能改变,但是内容可以改变 //q = t; //报错, 表达式必须是可修改的左值, q是常量当然不可修改 printf("*p= %s\n", p); printf("*q = %s\n", q); }
结果如下:
好了这个时候我又有了这样的疑问:
1 .怎么char *p = {“kdfj”}中,{“kdfj”}不可修改
2,但是char q[7] = {“jjdkj”}中,{“jjdkj”}可以修改呢?
以前我学习c的时候,老是会看到有人说 ={” jd“} 是个字符串常量,那时候我还没有仔细的观察, 直到现在,我好像有点明白了, 对于 ={“dkfj”},你要怎么看他,要看你是怎么定义的,就是你要看你的左值写的是什么,对于1来说他是字符串常量,对于2来说他是字符串,也是个变量。
四、指针常量和常量指针
1.指针常量
int *const p;
从前往后读,就是指针常量,但是重点在最后,他是一个常量;我的理解是,我们定义了一个常量,他是指针类型的,那么常量必须在定义的时候就初始化,例如我给他初始化为s;之后常量的值就不可以改变了,它一值指向s,但是呢,我们可以通过*p来修改他所指向内容的值。
int main() { char s[] = {"lslslslsjfjf"}; char t[] = {"jiawenshi"}; char * const p = s; printf("p = %s\n", p); p[1] = 'u'; printf("p = %s\n", p); p = t; //报错 printf("p = %s\n", p); return 0; }
2.常量指针
这里定义了常量指针 const char *p,或者可以这样定义:char const *p;读的时候从前往后读,就是常量指针。按照前面的理解就是他是一个指针,然后指向一个常量。也是一样的理解重点在指针,那么指针的值是可以改变的,但是所指向的常量值是不可以改变的。
int main() { char s[] = {"lslslslsjfjf"}; char t[] = {"jiawenshi"}; const char *p = s; // char const *p = s; // printf("p = %s\n", p); // p[1] = 'u'; //报错 printf("p = %s\n", p); p = t; printf("p = %s\n", p); return 0; }
3.总结
我在网上看到有的人的定义完全相反,其实我觉的没有什么太大的关系,只要记住” * “和 const谁更靠近p就可以决定哪个能改哪个不能改。
下面是一些参考,不过我认为我写的挺详细的:
char * 与char []区别总结_char*_bitcarmanlee的博客-CSDN博客
C语言 char*和char[]用法_c char*_imxlw00的博客-CSDN博客
如果你觉得我写的有问题,欢迎你与我交流。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/119019.html




