你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

vodi 函数(u32 *a)里的*a是要往函数输入什么?

[复制链接]
wrdt24435 提问时间:2018-8-25 17:34 /
请教各位这个函数输入量的意思是什么?
意思是u32类型的*p吗? 在例程里输入的是 u32 a[n]; 这么定义的数组,而且使用该函数时是 函数(a) 这样输入,
另外函数里 *a++意思是指针地址+1? 例程里输入的都是上述的数组,*a++在例程执行出来的意思相当于是a[x+1]的值

收藏 评论14 发布时间:2018-8-25 17:34

举报

14个回答
zcl201207 回答时间:2018-8-25 18:48:24
最好的老师是实践,就是做实验看结果。。。
feixiang20 回答时间:2018-8-25 22:18:45
描述得有点难理解 ...

你的意思 void fn(u32 *a); 数据中的a是输入什么数据是么? 如果是这样, 那a就要输入一个u32型的指针地址, 如:
u32 val = 0;
fn( &val);

*a++, 取值运算符与自增运算符同级, 自右向左结合, 所以先自增后取值; "*a++在例程执行出来的意思相当于是a[x+1]的值"明白你的意思, 应该是对的!

评分

参与人数 2ST金币 +1 蝴蝶豆 +2 收起 理由
zero99 + 2
wrdt24435 + 1 感谢

查看全部评分

STM1024 回答时间:2018-8-27 08:20:54
*a++意思是指针地址+1

这种说法没错但是不太准确,严格意义上来说,是按其类型递增相应的位数。例如原来的地址是0x0004,如果你是uint8_t*的指针类型,那么递增以后地址就是0x0005,如果是uint32_t,递增以后是0x0008,递增了一个类型所占据的字节数

点评

感谢  发表于 2018-8-27 13:32

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

sincomaster 回答时间:2018-8-27 08:50:43
stm1024 发表于 2018-8-27 08:20
这种说法没错但是不太准确,严格意义上来说,是按其类型递增相应的位数。例如原来的地址是0x0004,如果你 ...

stm1024大神,我怎么觉楼主说的没错呢?楼主说的是指针地址+1,指针已经指定数据类型为u32 *了,这样地址+1就是跳转4个或8个字节了,让大神见笑了,

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

STM1024 回答时间:2018-8-27 09:20:13
sincomaster 发表于 2018-8-27 08:50
stm1024大神,我怎么觉楼主说的没错呢?楼主说的是指针地址+1,指针已经指定数据类型为u32 *了,这样地址+1就 ...

大神不敢当,我也只是想说明一下观点,就是指针不一定是按一个字节往前跑的
wrdt24435 回答时间:2018-8-27 13:05:01
zcl201207 发表于 2018-8-25 18:48
最好的老师是实践,就是做实验看结果。。。

原理不知道的话,做实验只能依葫芦画瓢那样仿照着例程,感觉这样就不能灵活使用了。
wrdt24435 回答时间:2018-8-27 13:25:06
feixiang20 发表于 2018-8-25 22:18
描述得有点难理解 ...

你的意思 void fn(u32 *a); 数据中的a是输入什么数据是么? 如果是这样, 那a就要输 ...

看了各位回复,首先u32型指针地址指的是4个地址的值意思吧?比如地址0x0000到0x0003的值是1,2,3,4,u32型指针能指向0x01020304的值
1. 那要怎么指呢?也就是u32 *p=什么?是0x0000吗?
2. 其次也就是说数组a其实是指针地址,而a[x]则是一个变量,那么比如我想往void fn(u32 *a)这个函数输入a[2],是(u32 *)&a[2]这样输入吗?
3. 为什么我用const u32 a[n]定义的数组输入函数里编译会报错,是因为const u32和u32类型不一样需要强制类型转换?
表达的不清楚请见谅,有些地方不知道用什么词汇好。
wrdt24435 回答时间:2018-8-27 13:32:18
stm1024 发表于 2018-8-27 09:20
大神不敢当,我也只是想说明一下观点,就是指针不一定是按一个字节往前跑的 ...

看了各位回复,首先u32型指针地址指的是4个地址的值意思吧?比如地址0x0000到0x0003的值是1,2,3,4,u32型指针能指向0x01020304的值
1. 那要怎么指呢?也就是u32 *p=什么?是0x0000吗?
2. 其次也就是说数组a其实是指针地址,而a[x]则是一个变量,那么比如我想往void fn(u32 *a)这个函数输入a[2],是(u32 *)&a[2]这样输入吗?
3. 为什么我用const u32 a[n]定义的数组输入函数里编译会报错,是因为const u32和u32类型不一样需要强制类型转换?
表达的不清楚请见谅,有些地方不知道用什么词汇好。
sincomaster 回答时间:2018-8-27 16:37:21
wrdt24435 发表于 2018-8-27 13:32
看了各位回复,首先u32型指针地址指的是4个地址的值意思吧?比如地址0x0000到0x0003的值是1,2,3,4,u32型 ...

楼主对指针的基础知识还不是很扎实啊,在多去看看
2018-08-27_162700.jpg

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

sincomaster 回答时间:2018-8-27 17:18:09
wrdt24435 发表于 2018-8-27 13:32
看了各位回复,首先u32型指针地址指的是4个地址的值意思吧?比如地址0x0000到0x0003的值是1,2,3,4,u32型 ...

如我上图所示给楼主说下吧!
首先你第一段话就是错的括号这段)
(看了各位回复,首先u32型指针地址指的是4个地址的值意思吧?比如地址0x0000到0x0003的值是1,2,3,4,u32型指针能指向0x01020304的值)
你说U32指针能指向0x01,0x02,0x03,0x04,步进是1,这只能是char *p指针才是这样.因为char 是1个字节,

u32 *p的意思是:
声明一个u32类型的指针,指针指向的数据是u32类型,所以u32类型数据占4个字节(要注意不同的系统可能不一样)

我的第11行代码:
arr的地址就是arr[0]的地址,也就是0x001FFAA8
arr[1]地址是0x001FFAAC

注意parr这个(sizeof parr)也就是说指针变量本身占4个字节,(比如你的指针类型是占8个字节但指针变量本身还是4个字节,因为指针变量内存得是地址,不用8个字节这么大去存地址,除非地址很长//这句话你要好好理解一下,)

然后你看到没,&(*parr++)读出来的地址,0x001FFAA8(arr[0]的地址) 到0x001FFAAC(arr[1]的地址)指针加1就是跳转4个字节地址,

你的第一个问题1. 那要怎么指呢?也就是u32 *p=什么?是0x0000吗?)
这个就看函数调用了,像我的long *parr,我传的是(第20行代码)数组arr的首地址,所以long *parr = arr =arr[0]  = 1,但我32行代码用的是&(*parr++),用了%p来输出地址,如果是%d就输出值1,去掉&,

你的第二个问题其次也就是说数组a其实是指针地址,而a[x]则是一个变量,那么比如我想往void fn(u32 *a)这个函数输入a[2],是(u32 *)&a[2]这样输入吗?)
你要读a[2],正确的做法是*a+2(就不能使用*a++),你这种写法有点看不懂((u32*)&a[2])

你的第三个问题:
如果前面用了const修饰,那么后面的函数调用也用上吧,报错应该不至于吧,警告就会有,

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

tanic 回答时间:2018-8-27 17:24:53
1.u32 *p=?
这里?建议是指向变量地址
如 uint32_t a[10];
    uint32_t *p=a;
,不建议直接写地址如 0x20000000这种,因为ARM是精简指令集集必须寻址必须对齐,有的ram也只能对其访问
2.是的  
3.类型确实不一样,const修饰的是常量不可修改 没有const是变量可修改,强制转换不建议做,因为const修饰的应该不在ram中

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

STM1024 回答时间:2018-8-27 17:46:01
本帖最后由 stm1024 于 2018-8-27 18:23 编辑

我的C也学得很一般,针对你的问题,我还是一点点用例子来说明吧。我要说的都是老生常谈,基本上都是入门级的问题。
没什么技术含量,如果讲的不好甚至不对的地方,欢迎大家比较客气的批评指正。
1. 指针的自增
入门问题:指针的申明,到底是用
Type *x;
还是
Type* x;
答案是都可以,不过我个人更喜欢第二种。
  1. void f1(uint32_t* a)
  2. {
  3.     printf("Test For uint32_t\r\n");
  4.     do
  5.     {
  6.         printf("0x%08x\r\n",a);
  7.         a++;
  8.     }while(*a);
  9. }

  10. void f2(uint8_t* a)
  11. {
  12.     printf("Test For uint8_t\r\n");
  13.     do
  14.     {
  15.         printf("0x%08x\r\n",a);
  16.         a++;
  17.     }while(*a);
  18. }

  19. //测试一下这两段代码:
  20.     uint32_t a[]={7,6,5,4,3,2,1,0};
  21.     uint8_t b[]={7,6,5,4,3,2,1,0};
  22.     f1(a);
  23.     f2(b);
复制代码
运行的结果是:
2018-08-27_172953.jpg

f1和f2中同样都是a++,但是递增的效果并不一样,因为形参的类型分别是uint32_t*和uint8_t*的,所以指针的值,其实就是指向的对应数据类型的首地址,类型告诉了编译器该如何使用这个地址。




2.指针类型的转换
为了说明问题,我再写一个函数:
  1. void f3(uint8_t* a,uint8_t n)
  2. {
  3.     uint8_t i;
  4.     for(i=0;i<n;i++)
  5.         printf("%d\r\n",*(a+i));
  6. }
复制代码
然后代码是:
  1. f1(a);
  2.     f2((uint8_t *)a);
  3.     f3(a,32);
复制代码
运行效果呢?
2018-08-27_173813.jpg
可以看到,即使f2调用的时候做了强制类型转换,但是f2((uint8_t *)a);输出的第一个地址和f1(a)中的是一样的。
不过为什么第二函数只输入了一个值呢?因为在内存布局中,a数组的组织方式是07 00 00 00...
2018-08-27_174350.jpg
当到了第二个字节的时候,变成00,也就是'\0',函数提前退出了。
f3则直接打印32个字节的值,也有助于验证这个情况。
所以,要往哪个函数里面输入什么,取决于你要如何理解那一块内存区域,任何可访问的内存区域都是可以提供给这个函数的。
这个函数的意思是说,不管你那块内存区域是啥,我拿到内存首地址后,就按uint32_t,每四个字节作为一个单位来处理数据。
还有需要说明的是,有些控制器会有内存对齐的要求。


此外,对于一些内存操作的函数,如memcpy (void*, const void*, size_t);第一个数据类型是void*的指针类型。




评分

参与人数 1蝴蝶豆 +5 收起 理由
zero99 + 5

查看全部评分

STM1024 回答时间:2018-8-27 18:15:31
3. const指针和一般指针
    char a='x';
    const char* p=&a;
    *p='y';

这段代码是通过不了编译的,因为你的p是常常量指针,特点是,你可以修改指针指向的内存地址,但是不能修改指向地址的内容。
不过还是可以通过a来修改这个值。像string头文件中,很多函数,source char 都被定义为const char*,就是怕调用者瞎搞,把原始内容都给你破坏了。
和这个相反的还有char* const,指针常量,这个所指向的地址不能变,但是可以修改其中的内容。
还有常量指针常量const char* const类型,都不能改变……

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版