2014-10-07 219 views
1

我不知道这样的呼吁是可能的:C函数(不带参数)与参数

// declaration 
void func(); 

int main() 
{ 
    int ar[] = { 1, 2, 3 }; 
    func(ar); // call with parameter 
    return 1; 
} 

void func() // no parameters 
{ 
    // do something 
} 

有人可以解释我这个,特别是如何在我访问func()ar

+0

该程序不会编译。 – 2014-10-07 08:42:21

+2

@ mahendiran.b你的编译器坏了然后 – 2014-10-07 08:44:15

+0

@ mahendiran.b这个程序编译! – leon22 2014-10-07 09:02:57

回答

9

在C(非C++)中,声明为func()的函数被视为具有未指定数量的非类型化参数。不带参数的函数应明确声明为func(void)

+0

即使这个签名'func(void)'也被调用。我简直不敢相信。 – Rustam 2014-10-07 08:55:26

+0

@Rustam刚刚尝试过,它没有编译(gcc 4.8.2,没有任何标志,只是-o):''错误:太多的函数参数'func''' – zegkljan 2014-10-07 08:59:45

+0

请尝试在这里http://ideone.com/ ojV52B与c编译器 – Rustam 2014-10-07 09:01:17

0

你可以实现这样的东西。

void func(int *p, int n); 

int main() 
{ 
    int ar[] = { 1, 2, 3 }; 
    func(ar, sizeof (ar)/sizeof(ar[0])); // call with parameter 
    return 1; 
} 

void func(int *p, int n) // added 2 parameters 
{ 
    int i=0; 

    for (i=0; i<n; ++i){ 
     printf ("%d ", p[i]); 
     } 

} 
+0

这不是说明申报与使用之间差异的问题。 – mpromonet 2014-11-23 10:08:49

1

无法访问FUNC AR(),因为你没有在FUNC对它的引用()。

这将是可能的,如果AR将是一个全局变量或您有一个指针。

1

因此,你可以用func()做些事情,你需要将它输入的数据传递给它。

首先必须正确声明功能:

// declaration 
void func(int []); 

的定义它:

void func(int a[]) 
{ 
    // do something 
    printf ("a[0] = %d\n", a[0]); 
} 

全码:

#include <stdio.h> 

// declaration 
void func(int []); 

int main() 
{ 
    int ar[] = { 1, 2, 3 }; 
    func(ar); // call with parameter 
    return 1; 
} 

void func(int a[]) 
{ 
    // do something 
    printf ("a[0] = %d\n", a[0]); 
} 

这将显示: 一个[0] = 1

+0

这不是说明声明和使用之间差异的问题。 – mpromonet 2014-11-23 10:07:15

+0

@ mpromonet1:你说得对,我忽略了这个问题。明白他不知道如何使用他的功能。 – SCO 2014-11-23 11:39:35

0

如果要使用任何不带任何返回类型参数的函数,则应声明为(In C)

return_type func(void)。这只是通用的函数声明方式。

但是,任何如何,对于你的问题,它可以访问,但不generic..Try这个节目......

#include<stdio.h> 
    int *p; 

    void func(); 

    int main() 
    { 
    int ar[] = { 1, 2, 3 }; 
    p=ar; 
    printf("In main %d\n",ar[0]); 
    func(ar); // call with parameter 
    printf("In main %d\n",ar[0]); 
    return 1; 
} 

void func() // no parameters 
{ 
    printf("In func %d \n",*p); 
    *p=20; 
} 

即使这个方案正常工作,它不是通用的方式,也就是不确定的。

如果你声明像void func (void)这样的函数,它将不起作用。

2

黑客可能会利用GCC调用约定。

对于x86,参数被压入堆栈。局部变量也在堆栈中。

所以

void func() 
{ 
    int local_var; 
    int *ar; 
    uintptr_t *ptr = &local_var; 
    ptr += sizeof(int *); 
    ar = (int *)ptr; 

可能会给你的阵列地址在AR 86中。

对于x86_64,第一个参数存储在rdi寄存器中。

void func() 
{ 
    uintptr_t *ptr; 
    int *ar; 
    asm (
    "movq %%rdi, %0" 
    :"=r"(*ptr) 
    : 
    :"rdi"); 
    ar = (int *)ptr; 

可能会给你在x86_64 ar中的数组地址。

我自己没有测试过这些代码,您可能会自行调整偏移量。

但我只是显示一个可能的黑客攻击。

+0

好方法!我会看一下! ;-) – leon22 2014-10-07 12:59:33

+0

我已经更新了x86的代码。让我也知道,如果黑客真的有效! – 2014-10-07 13:47:04

+0

asm代码产生段错误,但用':'= r“(ptr)'替换':”= r“(* ptr)' – mpromonet 2014-11-23 10:23:14