C 如何在没有printf的情况下打印指针地址
我正在做一个练习,需要打印指针的内存(地址)。使用C 如何在没有printf的情况下打印指针地址,c,arrays,pointers,printf,C,Arrays,Pointers,Printf,我正在做一个练习,需要打印指针的内存(地址)。使用printf(“%p”,…)很容易做到,但我不允许使用它 你知道我如何不用printf()就可以得到地址吗? 我唯一可以使用的功能是“写入” 以下是我的练习说明: 编写一个函数,该函数接受(const void*addr,size\u t size),并显示 如示例中所示的内存。 您的函数必须声明如下: 你可以这样做。。。您说过禁止使用printf(),但您没有提到sprintf print_bytes(char *ptr, int coun
printf(“%p”,…)
很容易做到,但我不允许使用它
你知道我如何不用printf()
就可以得到地址吗?
我唯一可以使用的功能是“写入”
以下是我的练习说明:
编写一个函数,该函数接受(const void*addr,size\u t size)
,并显示
如示例中所示的内存。
您的函数必须声明如下:
你可以这样做。。。您说过禁止使用
printf()
,但您没有提到sprintf
print_bytes(char *ptr, int count)
{
int i;
char string[1024];
string[0] = 0;
for(i = 0; i < count; i++)
{
sprintf(string,"%s %2x", string, *(ptr+i));
}
puts(string);
}
编辑:在OP澄清他们实际上想要转储内存内容之前,我提供了这个答案(澄清之前,他们要求代码表现得像
printf(“%p”,mem\u ptr)
此代码应拼出每个数字(十六进制):
#包括
/*您必须在某个地方提供此功能*/
外部无效写入字符(字符);
字符十六进制数字(整数v){
如果(v>=0&&v<10)
返回“0”+v;
其他的
返回“a”+v-10;/>i)和0xf);
}
}
这里,print\u address\u hex
是一次打印一个数字的基本算法()。[为了简化我不关心前导零的事情]
该算法的核心是运算符>
(类似于二进制整数除法)和&
(类似于二进制余数)。[请注意,这些运算符通常只对基数2、4、8、16、2^n起作用]
我使用了uintptru\t
使其可移植。此类型(在
中声明)指的是能够容纳指针的集成类型(与体系结构无关)。我们需要一个整数类型,以便可以使用算术运算符(除了指针算术的唯一有效运算符+
和-
。您可以像这样尝试:
#include <stdio.h>
void print_memory(const void *addr, size_t size)
{
size_t printed = 0;
size_t i;
const unsigned char* pc = addr;
for (i=0; i<size; ++i)
{
int g;
g = (*(pc+i) >> 4) & 0xf;
g += g >= 10 ? 'a'-10 : '0';
putchar(g);
printed++;
g = *(pc+i) & 0xf;
g += g >= 10 ? 'a'-10 : '0';
putchar(g);
printed++;
if (printed % 32 == 0) putchar('\n');
else if (printed % 4 == 0) putchar(' ');
}
}
int main(void) {
int tab[10] = {0, 23, 150, 255, 12, 16, 21, 42};
print_memory(tab, sizeof(tab)); return (0);
return 0;
}
您不必打印内存,您必须将addr中的每个字节转换为十六进制并打印出来,第二部分是用点和星号将每个字节的值转换为字符,如果它不可打印,它将打印点
#include <string.h>
#include <unistd.h>
void ft_putchar(char c)
{
write(1, &c, 1);
}
void print_ascii(const char *addr, int i)
{
int j;
int len;
j = 0;
if ((i + 1) % 16 == 0)
len = 16;
else
len = (i + 1) % 16;
while (j < 16 - len)
{
ft_putchar(' ');
ft_putchar(' ');
if (j % 2)
ft_putchar(' ');
j++;
}
if ((16 - len) % 2)
ft_putchar(' ');
j = 0;
while (j < len)
{
if (*(addr + i / 16 * 16 + j) >= 32 && *(addr + i / 16 * 16 + j) <= 126)
ft_putchar(*(addr + i / 16 * 16 + j));
else
ft_putchar('.');
j++;
}
ft_putchar('\n');
}
void print_hex(unsigned char value, int index)
{
if (index < 2)
{
print_hex(value / 16, index + 1);
if (value % 16 >= 10)
ft_putchar('a' + value % 16 % 10);
else
ft_putchar('0' + value % 16);
}
}
void print_memory(const void *addr, size_t size)
{
char *ptr;
size_t i;
if (addr && size > 0)
{
ptr = (char*)addr;
i = 0;
while (i < size)
{
print_hex(*(ptr + i), 0);
if (i % 2)
ft_putchar(' ');
if ((i + 1) % 16 == 0 || (i + 1) == size)
print_ascii(addr, i);
i++;
}
}
}
#包括
#包括
void ft_putchar(字符c)
{
写(1,&c,1);
}
无效打印\u ascii(常量字符*地址,整数i)
{
int j;
内伦;
j=0;
如果((i+1)%16==0)
len=16;
其他的
len=(i+1)%16;
而(j<16-len)
{
ft_putchar(“”);
ft_putchar(“”);
如果(j%2)
ft_putchar(“”);
j++;
}
如果((16-len)%2)
ft_putchar(“”);
j=0;
而(j=32&&*(地址+i/16*16+j)=10)
ft_putchar('a'+值%16%10);
其他的
ft_putchar('0'+值%16);
}
}
无效打印内存(常量无效*地址,大小)
{
char*ptr;
尺寸i;
如果(地址和大小>0)
{
ptr=(char*)addr;
i=0;
而(i
这段代码适用于您的考试。“我需要打印指针的内存”嗯,这对我来说有点不清楚。你想打印指针的值还是它指向的内存?@machine\u 1:实现
printf
的代码正是这样做的,所以这当然是可能的。@machine\u 1我在发布的答案中使用sprintf()
,但输出格式化文本时没有printf()
是一项简单的任务。想想在printf()
存在之前,我们是如何输出格式化输出的。或者考虑一下,如果在设计操作系统时实现C库,您将如何实现printf()
。这很琐碎,只是不方便。我仍然不知道你想做什么printf(“%p”,…)
打印地址(指针值)。但在您的评论中,“0000 0000 1700 0000 9600 0000 ff00 0000”看起来更像该地址的16字节内存的内容;这是128位,可能比指针值大。@GautierLemaire:你想做什么还不清楚。什么是“数组中的地址”?你的意思是你有一个指针数组,你想打印数组中每个元素的值吗?问你的问题最清晰的方式可能是使用printf(“%p”,…)
显示做你想做的事情的代码,并询问如何在不使用printf
的情况下做同样的事情。(由于这似乎是一个家庭作业问题,我很犹豫是否提供完整的答案,尽管我愿意将代码发送给您的讲师,并附上您的姓名。)OP明确表示他不能使用printf()
感谢您的回答,这是一个很好的方法。但是,您是否可以仅使用“写入”功能来执行此操作?@GautierLemaire:Whywrite
?这是POSIX特有的。如果您想要可移植性,您应该使用类似于fputc
或fputs
@DanielH:正如问题所述,我没有注意到。对不起,吵闹了。(我的问题仍然适用于创建任务的人,但不适用于OP。)@GautierLemaire:什么地址?如果您试图执行与printf(“%p”,…)等效的操作,请在问题中说明。这是你所写内容的含意,但与你的一些评论相矛盾。“指针地址”可能意味着指针对象的存储地址,但我认为您需要指针的值。
write(1, string, strlen(string)); /* 1 = STDOUT */
#include <stdint.h>
/* you must provide this function somewhere */
extern void write_char(char);
char hex_digit(int v) {
if (v >= 0 && v < 10)
return '0' + v;
else
return 'a' + v - 10; // <-- Here
}
void print_address_hex(void* p0) {
int i;
uintptr_t p = (uintptr_t)p0;
write_char('0'); write_char('x');
for(i = (sizeof(p) << 3) - 4; i>=0; i -= 4) {
write_char(hex_digit((p >> i) & 0xf));
}
}
#include <stdio.h>
void print_memory(const void *addr, size_t size)
{
size_t printed = 0;
size_t i;
const unsigned char* pc = addr;
for (i=0; i<size; ++i)
{
int g;
g = (*(pc+i) >> 4) & 0xf;
g += g >= 10 ? 'a'-10 : '0';
putchar(g);
printed++;
g = *(pc+i) & 0xf;
g += g >= 10 ? 'a'-10 : '0';
putchar(g);
printed++;
if (printed % 32 == 0) putchar('\n');
else if (printed % 4 == 0) putchar(' ');
}
}
int main(void) {
int tab[10] = {0, 23, 150, 255, 12, 16, 21, 42};
print_memory(tab, sizeof(tab)); return (0);
return 0;
}
0000 0000 1700 0000 9600 0000 ff00 0000
0c00 0000 1000 0000 1500 0000 2a00 0000
0000 0000 0000 0000
#include <string.h>
#include <unistd.h>
void ft_putchar(char c)
{
write(1, &c, 1);
}
void print_ascii(const char *addr, int i)
{
int j;
int len;
j = 0;
if ((i + 1) % 16 == 0)
len = 16;
else
len = (i + 1) % 16;
while (j < 16 - len)
{
ft_putchar(' ');
ft_putchar(' ');
if (j % 2)
ft_putchar(' ');
j++;
}
if ((16 - len) % 2)
ft_putchar(' ');
j = 0;
while (j < len)
{
if (*(addr + i / 16 * 16 + j) >= 32 && *(addr + i / 16 * 16 + j) <= 126)
ft_putchar(*(addr + i / 16 * 16 + j));
else
ft_putchar('.');
j++;
}
ft_putchar('\n');
}
void print_hex(unsigned char value, int index)
{
if (index < 2)
{
print_hex(value / 16, index + 1);
if (value % 16 >= 10)
ft_putchar('a' + value % 16 % 10);
else
ft_putchar('0' + value % 16);
}
}
void print_memory(const void *addr, size_t size)
{
char *ptr;
size_t i;
if (addr && size > 0)
{
ptr = (char*)addr;
i = 0;
while (i < size)
{
print_hex(*(ptr + i), 0);
if (i % 2)
ft_putchar(' ');
if ((i + 1) % 16 == 0 || (i + 1) == size)
print_ascii(addr, i);
i++;
}
}
}