首页
社区
课程
招聘
[原创]再论C语言指针、地址、赋值的问题,又是一通“扯”
发表于: 2012-6-23 05:49 12852

[原创]再论C语言指针、地址、赋值的问题,又是一通“扯”

2012-6-23 05:49
12852

再论C语言指针、地址、赋值、洗钱的问题,又是一通“扯”

按:在CSDN论坛上,有位坛友提到这个问题:


#include<stdio.h>

int main(void) {

	int *p;

	p = (int *) 10;

	printf("%d\n", p);

	p = (int *) 'a';

	printf("%c\n", p);

	p = (int *) "I Love C/C++! Oh, Yeah!";

	printf("%s\n", p);

	return 0;

}


#include<stdio.h>

int main(void) {

	int *p;

	p = (int *) 10;

	printf("%d\n", (int)p);

	p = (int *) 'a';

	printf("%c\n", (char)p);

	p = (int *) "I Love C/C++! Oh, Yeah!";

	printf("%s\n", (char*)p);

	return 0;

}


[培训]科锐逆向工程师培训第53期2025年7月8日开班!

收藏
免费 6
支持
分享
最新回复 (12)
雪    币: 285
活跃值: (16)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
这肯定输出是10啊。。。
2012-6-23 07:20
0
雪    币: 42
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
好文,楼主辛苦
其实指针也就是一变量
2012-6-23 08:50
0
雪    币: 33
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
文章不错,通俗易懂,望楼主今后能写出更好的文章,加油!!!
2012-6-23 10:55
0
雪    币: 2503
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
不错 简单易懂!
2012-6-23 11:03
0
雪    币: 90
活跃值: (91)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
真正的好文章都是这么平易近人,深入浅出的!
2012-6-23 13:10
0
雪    币: 27
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
写得很好 文笔不错 解释了一些 没有准确“定义”的 知识 谢谢了
2012-6-23 14:24
0
雪    币: 142
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
能别您啊您的么?网络上这不是礼貌,是装X
2012-6-23 14:40
0
雪    币: 1505
能力值: (RANK:210 )
在线值:
发帖
回帖
粉丝
9
涉及到词法语法语义的东西都不用解释,因为标准就是这么定的,所以就行了. 这跟地址,指针,什么都没关系.
2012-6-24 23:31
0
雪    币: 367
活跃值: (35)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
10
您写的是不是太复杂了?
指针就是一个变量在内存中地址,这个地址数值在intel 32位系统下,它可以用4字节的空间存放.
所以,它本身也是一个变量.

对于printf等格式化函数,它只根据格式类型描述本身来取数据,并不理会实际内容.
所以, %d,%l,%u,%p, 都会根据它期待的类型进行直接取值, 而%s,则期待一个0终结的字符串(字符串的起始地址),所以,如果此地址无效则引发程序异常.
由于在32/64位系统下一些数据类型大小不同,使用%p则等价于总是取当前平台下指针大小的变量.
事实上,微软为了让大多数代码无需修改可以直接编译为64位版本, int 在64位下继续保持32bit,long继续保持32bit,而int64需要单独声明为longlong,int64等.这和linux等系统不同. 而int_ptr,long_ptr则根据当前平台的大小自动确定大小,详细内容可以看(std_int.h).

回到指针的问题. 所以,如果你对指针这个变量本身取值(memcpy到int,或强制类型转换成int/long),返回的内容,就是我们存入的内容,一般叫做地址.而是用指针特有的运算符*,则返回指针变量指向地址中的内容,内容根据指针类型而定.

但愿我的解释不至于太复杂.
2012-7-16 13:42
0
雪    币: 62
活跃值: (27)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
11
C语法不用记,熟悉指令集和编译原理,很容易理解。
2012-7-16 14:43
0
雪    币: 240
活跃值: (190)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
12
读得不错,我记得vc编译器的内置的基本类型有

数据类型
bool       1位
char /__int8       8位,一个字节
short/__int16      两个字节
long /int/__int32  四个字节
__int64                八字节
__int128             十六字节

tchar类型
wchar_t               编译器内置 ,可以设置他的长度为8还是16

浮点类型
float                     四字节
double                 八字节

指针变量类型
加*号为指针     ,视cpu位数不同,长度不同,目前 一般为32位和64位,单片机一般为8位和16位居多

无符号 类型

加unsigned为无符号,浮点类型不能加unsigned

数组类型[]
数组不同于指针,只是一个符号而已,比如 int a[12]; 数组符号(a)不是变量,是不占空间的,占空间的是a[12] ;编译后,数组(a)应该是一个立即数,准确地说是楼主文中 的指针。

其它
const关键字只是作为C语言中编程时的限制条件 ,程序运行时,没有任何影响.这意味着,const不会编译成具体的机器指令.

字符串
C语言中的字符串,只是一个以0结束的数组而已,这跟操作系统有关系 。
(我的同事就区分不了字符串这个东西,经常搞不清楚 string,char [],char*,CString有什么分别 ,老是弄错)

其它的都是通过typedef 或者 define命令衍生而来 的

这里,讲一下字符串这个东西.
在windows系统上C语言中,字符串就是一个数组,
比如:
char a[12];//数组,a只是一个指针,是一个符号,不占空间的,占空间的应该是char [12];12字节空间
char* p = a;//指向a数组首地址的指定变量,注意这个p是变量

c语言中,限制了上面两种表示字节串的类型之间的转换,
a 可以转换成p,但是p不能转成a,只是a是不占空间的,编译后a没有实际空间可用,所以不存在转换,不可能a=p;只能p=a;也就是说,a不能赋值,p可以,因为p是变量,a是不变量,一般交流中应该说a数组变量,而不是a变量

至于 string,CString只是对char* 的封装而已,是一个c++类;
2012-7-16 16:10
0
雪    币: 119
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
众多书里把指针是什么,实在是写的不清楚。其实就是两点,1是把声明,定义中的any * 与 DWORD 等价起来看。2.语句中的*表示取地址。3.掌握字符串的C机理。4.明白int *a 和int a[],这2个a的差别就OK了。
2012-12-5 15:44
0
游客
登录 | 注册 方可回帖
返回