本文目录一览:
- 1、linux环境c语言编程!问题棘手!高手进!
- 2、linux c语言文件操作下,文件指针不用FILE*定义而是用int整型定义 (以下是一本书上的例程)
- 3、linux下c语言编程出现段错误
- 4、Linux下的C语言编程,怎么读取16进制数
- 5、在LINUX下C语言编程调用这个函数int open(argv[1],O_CREAT|O_RDWR,0755) 执行时参数是怎样给定的?
- 6、linux c 引用传递参数
linux环境c语言编程!问题棘手!高手进!
【第一个问题】
argv[i]越界了,不能保证都是null,改成这样
for(i=1;iargc;i++)
demo[i-1]=atoi(argv[i]);
for(–i;i3;++i)
demo[i]=10;
【第二个问题】
我的理解是第一个子进程wakeup的瞬间,其他的子进程还是sleep,因此第一个子进程执行了printf
优先级再高的进程sleep了也抢不过优先级低的活动进程
因此最好保持3个子进程同时活动
else//子进程执行代码
{
sleep(1);//为了父进程顺利启动3个子进程,sleep还是留着吧
for(i=1;i;i++);//保持活动一段时间
//报告进程号和优先级
printf(“child %d priority=%d\n”,getpid(),getpriority(PRIO_PROCESS,0));
exit(EXIT_SUCCESS);
//return EXIT_SUCCESS;
}
linux c语言文件操作下,文件指针不用FILE*定义而是用int整型定义 (以下是一本书上的例程)
不要弄混open()和fopen():
open() 是底层系统调用,返回值为文件描述符, (int)
fopen() 是库函数, 返回值为流指针(FILE *)
fopen() 的实现也是调用的open()函数, 可以理解成对底层调用的一个高层封装.
linux下c语言编程出现段错误
简单看了一下你的程序
首先,你没有给出完整的程序,这个让大伙看起来确实不方便,因为没有main函数,可能踩内存的地方并不是这个函数本身,是main函数
其次说你的这个函数,貌似确实有点问题,但是由于没有完整的程序,我只说出我的理解,如果有错,直接忽视就好
sprintf(flag_height,”%03d”,i+1);
sprintf(flag_width,”%03d”,j+1);
我觉得问题出在这里,你查下 sprintf 的用法,第一个参数应该是一个字符串的首地址,你写的确实没有错,参数给入的是一个地址flag_height,但是纵观你的程序,你并没有给这个指针赋值,程序运行到这里,估计在默认创建指针的时候应该赋值为NULL(貌似根据编译器不同而有不同),那个寻址后报出段错误,也是意料之中了
由于没有你完整的代码,不知道你要做什么,修改意见不好提
给出个人意见,仅供参考
如果要打印flag_height中的值,首先应该给flag_height指针分配一片内存,使用malloc函数,其次在向内从中写入值,然后调用sprintf,就应该没有问题了
Linux下的C语言编程,怎么读取16进制数
#include stdio.h
#include string.h
#include sys/types.h
#include errno.h
#include sys/types.h
#include fcntl.h
#include unistd.h
#include termios.h
#include stdlib.h
#define BUFFER_SIZE 1024
#define HOST_PORT 0
int set_port(int fd, int baud_rate, int data_bits, char parity, int stop_bits)
{
struct termios newtio,oldtio;
if( tcgetattr(fd,oldtio) != 0)
{
perror(“Setup Serial 1”);
return -1;
}
bzero(newtio,sizeof(newtio));
newtio.c_cflag |= CLOCAL | CREAD;
newtio.c_cflag = ~CSIZE;
/* set baud_speed*/
switch(baud_rate)
{
case 2400:
cfsetispeed(newtio,B2400);
cfsetospeed(newtio,B2400);
break;
case 4800:
cfsetispeed(newtio,B4800);
cfsetospeed(newtio,B4800);
break;
case 9600:
cfsetispeed(newtio,B9600);
cfsetospeed(newtio,B9600);
break;
case 19200:
cfsetispeed(newtio,B19200);
cfsetospeed(newtio,B19200);
break;
case 38400:
cfsetispeed(newtio,B38400);
cfsetospeed(newtio,B38400);
break;
default:
case 115200:
cfsetispeed(newtio,B115200);
cfsetospeed(newtio,B115200);
break;
}
/* set data_bits upon 7 or 8*/
switch(data_bits)
{
case 7:
newtio.c_cflag |= CS7;
break;
default :
case 8:
newtio.c_cflag |= CS8;
break;
}
/**/
switch(parity)
{
default:
case ‘N’:
case ‘n’:
{
newtio.c_cflag = ~PARENB;
newtio.c_iflag = ~INPCK;
}
break;
case ‘o’:
case ‘O’:
{
newtio.c_cflag |= (PARODD | PARENB);
newtio.c_iflag |= INPCK;
}
break;
case ‘e’:
case ‘E’:
{
newtio.c_cflag |= PARENB;
newtio.c_cflag = ~PARODD;
newtio.c_iflag |= INPCK;
}
break;
case ‘s’:
case ‘S’:
{
newtio.c_cflag = ~PARENB;
newtio.c_cflag = ~CSTOPB;
}
break;
}
/*set stop_bits 1 or 2 */
switch(stop_bits)
{
default:
case 1:
{
newtio.c_cflag = ~CSTOPB;
}
break;
case 2:
{
newtio.c_cflag |= CSTOPB;
}
break;
}
newtio.c_cc[VTIME] = 0;
newtio.c_cc[VMIN] = 1;
tcflush(fd,TCIFLUSH);
if((tcsetattr(fd,TCSANOW,newtio)) != 0)
{
perror(“com set error”);
return -1;
}
printf(“set UART done!\n”);
return 0;
}
int open_port(int com_port)
{
int fd = 0;
char *dev[] = {“/dev/ttyAMA0”, “/dev/ttyS1”, “/dev/ttyS2″,”/dev/ttyS3”,
“/dev/ttyS4”, “/dev/ttyS5”, “/dev/ttyS6”};
if((com_port 0) || (com_port 6) )
{
printf(“the port is out range”);
return -1;
}
fd = open(dev[com_port], O_RDWR | O_NOCTTY | O_NDELAY);
if(fd 0)
{
perror(“open serial port”);
return -1;
}
if(fcntl(fd, F_SETFL,0) 0)
{
perror(“fcntl F_SETFL”);
return -1;
}
if(isatty(fd) == 0)
{
perror(“isatty is not a terminal device”);
return -1;
}
return fd;
}
int main(void)
{
int fd = 0;
char Buffer[BUFFER_SIZE] = {0};
if((fd = open_port(HOST_PORT)) == -1)
{
perror(“open port”);
return -1;
}
if(set_port(fd,115200,8,’N’,1)== -1)
{
perror(“set port”);
return -1;
}
int ReadByte = read(fd,Buffer,512);
char NFC[1024]=””;
if(ReadByte0)
{
int i;
printf(“readlength=%d\n”,ReadByte);
printf(“The Data is:”);
for (i=0;iReadByte;i++)
{
printf(“%02x “,Buffer[i]);
int lennn = strlen(NFC);
sprintf(NFC+lennn, “%02x “,Buffer[i]);
}
printf(“\n”);
printf(“%s\n”, NFC);
sleep(3);
}
else printf(“Read data failure “);
close(fd);
return 0;
}
在LINUX下C语言编程调用这个函数int open(argv[1],O_CREAT|O_RDWR,0755) 执行时参数是怎样给定的?
你好,O_CREAT表示在argv[1]中的文件存在时,第三个参数没用,并且以读写将其打开;argv[1]中的文件不存在时,则创建这个文件,并设置文件的权限为755,就是用chmod更改的文件权限,755表示对所有者可读可写可执行,对所属组可读可执行不可写,对其他用户可读可执行不可写。
linux c 引用传递参数
C/C++函数参数的传递方式有三种:值传递(pass by value)、指针传递(pass bypointer)、引用传递(pass by reference)。
C/C++函数参数的传递通道是通过堆栈传递,默认遵循__cdecl(C声明方式),参数由调用者从右往左逐个压入堆栈,在函数调用完成之后再由调用者恢复堆栈。(Win32API遵循stdcall传参规范的,不在本文讨论范围)
下面是测试代码
void Swap(__int64* _pnX, __int64* _pnY)
{
__int64 nTemp = *_pnX;
*_pnX = *_pnY;
*_pnY = nTemp;
}
void Swap(__int64 _nX, __int64 _nY)
{
__int64 nTemp = _nX;
_nX = _nY;
_nY = nTemp;
}
void SetValue(__int64 _nX)
{
__int64 nTemp = _nX;
}
// Test001
void GetMemory(__int64* _pBuff)
{
_pBuff = new __int64[4];
}
// Test002
void GetMemory(__int64** _ppBuff)
{
*_ppBuff = new __int64[4];
}
int _tmain(int argc, _TCHAR* argv[])
{
__int64 nA = 0x10;
__int64 nB = 0x20;
// Test to pass by pointer
Swap(nA, nB);
// Test to pass by reference
Swap(nA, nB);
// Test to pass by value
SetValue(nA);
// Test the pointer that points the pointer
__int64* _pArray = NULL;
GetMemory(_pArray);
delete[] _pArray;
_pArray = NULL;
// Test the pointer
GetMemory(_pArray);
return 0;
}
指针传递和引用传递
// 下面看一下对应的反汇编的代码(VS版)
__int64 nA = 0x10;
0041370E mov dword ptr [nA],10h
mov dword ptr [ebp-8],0
__int64 nB = 0x20;
0041371C mov dword ptr [nB],20h
mov dword ptr [ebp-18h],0
// Test to pass by pointer
Swap(nA, nB);
0041372A lea eax,[nB]
0041372D push eax
0041372E lea ecx,[nA]
push ecx
call Swap (4111E5h)
add esp,8
// Test to pass by reference
Swap(nA, nB);
0041373A lea eax,[nB]
0041373D push eax
0041373E lea ecx,[nA]
push ecx
call Swap (4111E0h)
add esp,8
// GCC版
0x00401582 +30: lea eax,[esp+0x18]
0x00401586 +34: mov DWORD PTR [esp+0x4],eax
0x0040158a +38: lea eax,[esp+0x1c]
0x0040158e +42: mov DWORD PTR [esp],eax
0x00401591 +45: call 0x401520 Swap(int*, int*)
0x00401596 +50: lea eax,[esp+0x18]
0x0040159a +54: mov DWORD PTR [esp+0x4],eax
0x0040159e +58: lea eax,[esp+0x1c]
0x004015a2 +62: mov DWORD PTR [esp],eax
0x004015a5 +65: call 0x401542 Swap(int, int)
通过上面的反汇编代码,我们可以看出指针传递和引用传递在机制是一样的,都是将指针值(即地址)压入栈中,调用函数,然后恢复栈。Swap(nA, nB)和Swap(nA, nB);在实际上的汇编代码也基本上一模一样,都是从栈中取出地址来。由此可以看出引用和指针在效率上是一样的。这也是为什么指针和引用都可以达到多态的效果。指针传递和引用传递其实都是改变的地址指向的内存上的值来达到修改参数的效果。
值传递
下面是值传递对应的反汇编代码
// Test to pass by value
SetValue(nA);
0041374A mov eax,dword ptr [ebp-8]
0041374D push eax
0041374E mov ecx,dword ptr [nA]
00413751 push ecx
00413752 call SetValue (4111EAh)
00413757 add esp,8
因为我的机器是32位的CPU,从上面的汇编代码可以看64Bit的变量被分成2个32Bit的参数压入栈中。这也是我们常说的,值传递会形成一个拷贝。如果是一个自定义的结构类型,并且有很多参数,那么如果用值传递,这个结构体将被分割为非常多个32Bit的逐个拷贝到栈中去,这样的参数传递效率是非常慢的。所以结构体等自定义类型,都使用引用传递,如果不希望别人修改结构体变量,可以加上const修饰,如(const MY_STRUCT _value);
下面来看一下Test001函数对应的反汇编代码的参数传递
__int64* _pArray = NULL;
004137E0 mov dword ptr [_pArray],0
// Test the pointer
GetMemory(_pArray);
mov eax,dword ptr [_pArray]
push eax
call GetMemory (411203h)
0041381B add esp,4
从上面的汇编代码可以看出,其实是0被压入到栈中作为参数,所以GetMemory(_pArray)无论做什么事,其实都与指针变量_pArray无关。GetMemory()分配的空间是让栈中的临时变量指向的,当函数退出时,栈得到恢复,结果申请的空间没有人管,就产生内存泄露的问题了。《C++ Primer》将参数传递分为引用传递和非引用传递两种,非引用传递其实可以理解为值传递。这样看来,指针传递在某种意义上也是值传递,因为传递的是指针的值(1个4BYTE的值)。值传递都不会改变传入实参的值的。而且普通的指针传递其实是改变的指针变量指向的内容。
下面再看一下Test002函数对应的反汇编代码的参数传递
__int64* _pArray = NULL;
004137E0 mov dword ptr [_pArray],0
GetMemory(_pArray);
004137E7 lea eax,[_pArray]
004137EA push eax
004137EB call GetMemory (4111FEh)
004137F0 add esp,4
从上面的汇编代码lea eax,[_pArray] 可以看出,_pArray的地址被压入到栈中去了。
然后看一看GetMemory(_pArray)的实现汇编代码。
0x0040159b +0: push ebp
0x0040159c +1: mov ebp,esp
0x0040159e +3: sub esp,0x18
0x004015a1 +6: mov DWORD PTR [esp],0x20
0x004015a8 +13: call 0x473ef0 _Znaj
0x004015ad +18: mov edx,DWORD PTR [ebp+0x8]
0x004015b0 +21: mov DWORD PTR [edx],eax
0x004015b2 +23: leave
0x004015b3 +24: ret
蓝色的代码是分配临时变量空间,然后调用分配空间函数分配空间,得到的空间指针即eax.
然后红色的汇编代码即从ebp+0x8的栈上取到上面压入栈中的参数_pArray的地址.
mov DWORD PTR [edx],eax即相当于把分配的空间指针eax让edx指向,也即让_pArray指向分配的空间eax.
总之,无论是哪种参数传递方式,参数都是通过栈上的临时变量来间接参与到被调用函数的。指针作为参数,其本身的值是不可能被改变的,能够改变的是其指向的内容。引用是通过指针来实现的,所以引用和指针在效率上一样的。
原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/258545.html