各位大神 最近在学指针遇到了个问题 为什么上面输出就不用 * 而下面就用*呢 我感觉指针是一直要用 *才能输出里面的内容的
char str[100] = "abcd";
char *p = &str;
printf("%s\r\n",p);
int num = 3;
int *a = #
printf("\r\n%d",*a);
各位大神 最近在学指针遇到了个问题 为什么上面输出就不用 * 而下面就用*呢 我感觉指针是一直要用 *才能输出里面的内容的
char str[100] = "abcd";
char *p = &str;
printf("%s\r\n",p);
int num = 3;
int *a = #
printf("\r\n%d",*a);
对于题主我感觉指针是一直要用 *才能输出里面的内容的
这个说法,其实是不恰当的。
指针和其它所有的变量一样,都是一种变量类型,都有标识符
和值
两个属性。所有的值都是数字(因为计算机只能存01
,01
可以很直接转换为十进制数)。这个值如果直接读,是完全混乱的。比如,10
是什么?我即可以说是数字10
,也可以是ascii码为10
的那个字符
,还可以是指针
(其指向地址为10的那个变量)。所以,值
与标识符
与变量类型
绑定,三者共同解释一个变量。说这么多,就一句:变量都是统一的
。
对于指针,也是一个这样通用的变量。题中的p
与*p
与,*a
与a
其实没有本质区别。
printf("%s\r\n",p)
。%s
表示输出从第二个参数(即p)
指向(p甚至不是指针都可以,C语言只是愚蠢地去得到p的值,然后找到地址为这个值的字符,这个就表示p指向的字符)的那个字符开始,一直到\0
结束 的字符串。
如果你写成printf("%s\r\n",*p)
,就表示*p
指向的地址(注意,不是p
指向的地址)而*p
的值是一个字符类型,对它的值代表的地址访问是非法不合理的,但c是自由的,应该会允许这样做。
printf("\r\n%d",*a)
%d
是以十进制输出第二个参数(变量)的值,*a
代表以a
的值为地址的那个变量。所以,就是输出
a指向的那个变量的值,而如果是
printf("\r\n%d",a),它输出的就是
a的值,也就是是
num`变量的地址。
说的比较乱,但都是自己的一些总结。题主不妨多理解下。
基本的数据类型 用的是指,数组 等非基本数据类型就是用指针!
特别是在格式化字符输出的时候,由于指定了格式化需要参数类型,在参数类型不匹配是不会强制转换.
或者是格式化字符需要的参数是指,但是传的是指针,那么它会把传递过去的指针地址当做指来处理!
所以在使用格式化字符输出时需要注意站位符与,参数之间的匹配!
ps:其实我觉得如果是刚学的话,可以重复造下轮子,把printf函数自己亲手实现一次就知道其中的原理了.
用*表示要对该地址进行解引用,解引用就是取到该地址上的值。
但是%s就是需要首地址才能打印整个字符串。如果你对首地址解引用,那就只能取到首地址上的值(第一个字符),这时候你就要用%c了。
这只能说明对指针概念还不是很清楚。指针就是保存内存空间的地址的变量。例如定义指针 int *pr=100;
那么变量pr的值保存的就是整数100所在空间的地址,假如为5000,则pr=5000; 而*pr表示对pr
指向的内存空间中保存的数据的读写,也就是100。所以要读取100这个数据,就要用*pr,例如:
printf("%d",*pr);
int main(int argc,char *arg[]){
//保存整数的指针,并分配空间
int *pr = (int *)malloc(100*sizeof(int));
*pr = 100;
printf("pr指向空间的地址为%p,pr指向空间的内容是%d\n\n",pr,*pr);
free(pr); //用完指针记得释放
//保存字符串的指针,并分配空间
char *str = (char *)malloc(100*sizeof(char));
str = "You are so beautiful!";
while( *str != '\0' ){
printf("当前str指向的空间地址:%p,当前str指向空间里保存的数据是%c\n",str,*str++);
}
str = NULL;
free(str);
return 0;
}
p 实际上是字符指针,如果你要输出 p 指向的内容,就应该加 *,例如:
printf("%c", *p);
但是你在格式参数里使用了%s,表示输出字符串,所以就会尝试一直读取p指向的内容,直到遇到 '\0'。在C语言里使用 char* 表示字符串是一个特例,这个时候你可以把它看做一个整体,就好像:
typedef char *String;
%s意味着相应的参数为字符串数组的首地址,也就是str
#include "stdio.h"
int main(void) {
char str[100] = "abcd";
char* p = (char*)&str;
printf("%s %p \n", p, p);
printf("%s %p \n", str, str);
return 0;
}
运行以后可以发现,p和str的指是相同的
int (*func_p)();//指向int类型函数的指针
int *f();//返回指向int类型指针的函数
int num = 1;
int *p_num;
p_num = # //
*p_num//是取出num的数据
p_num//是取出num的内存地址
&P_num//是取出p_num的内存地址
p_num+1//是对num的内存地址加1 ,因为num是int类型的,占用4个字节,如果原来是0x000004那么加1后就是0x000008(数据只是测试随便写的),而不是对num的值计算
int arr[] = {1,2,3,4};
printf("%d\n",(arr+1));// 数组可以是分配好的连续指针,arr就是这个数组的首地址,对地址+1就是对这个类型+1,如果arr[0]是0x00004那么arr[1]就是0x00008然后前面的就是取地址值。 如果是int arr[][4]也可以写成int *arr[4];
printf("%d\n",*arr+1);//同上
(K&R 423页)
int arr[8][8];//int的数组
int **p;//指向int类型指针的指针
int *p[10];//具有10个元素的数组, 每个元素是一个指向int的指针
int (* p)[10];//一个指针, 指向有10个元素的int类型的数组
int * p[3][4];
int (* p) [3][4];
int (* p[3]) [4]; //具有3个元素的数组, 每个都是指向具有4个元素的int数组的指针
char *pd () //返回指向char的指针的函数
char (* pd)()//指向返回类型为char的函数的指针
char (* pd[3])()//由3个指针组成的数组,每个指针指向返回类型为char的函数
int const | const int p =&1 //p不能在修改了, p还可以使用
int const p = 1; //p不能在修改了,p还可以
const 在谁前面,修饰谁
第一个是声明一个常量的指针变量。指向的对象不可以修改但是P的指向可以修改。
第二个是声明一个指针变量P是常量类型,指向不可以修改但是指向的对象可以修改。
6 回答6.9k 阅读✓ 已解决
3 回答2k 阅读✓ 已解决
2 回答3.9k 阅读✓ 已解决
2 回答3.2k 阅读✓ 已解决
1 回答3.2k 阅读✓ 已解决
1 回答2.7k 阅读✓ 已解决
3 回答3.4k 阅读
格式化字符串不一样,%s要求指针,%d要求整数