wenmo8 发布的文章

我们在写程序时,既有程序的逻辑代码,也有在程序中定义的变量等数据,那么当我们的程序进行时,我们的代码和数据究竟是存放在哪里的呢?下面就来总结一下。

一、程序运行时的内存空间情况

其实在程序运行时,由于内存的管理方式是以页为单位的,而且程序使用的地址都是虚拟地址,当程序要使用内存时,操作系统再把虚拟地址映射到真实的物理内存的地址上。所以在程序中,以虚拟地址来看,数据或代码是一块块地存在于内存中的,通常我们称其为一个段。而且代码和数据是分开存放的,即不储存于同于一个段中,而且各种数据也是分开存放在不同的段中的。

下面以一个简单的程序来看一下在Linux下的程序运行空间情况,代码文件名为space.c

#include
#include

int main()
{
printf("%d\n", getpid());
while(1);
return 0;
}
这个程序非常简单,输出当前进程的进程号,然后进入一个死循环,这个死循环的目的只是让程序不退出。而在Linux下有一个目录/proc/$(pid),这个目录保存了进程号为pid的进程运行时的所有信息,其中有一个文件maps,它记录了程序执行过程中的内存空间的情况。编译运行上面的代码,其运行结果如图1所示:
20160408_uOmp[1].jpg
从上面的图中,我们可以看到这样一个简单的程序,在执行时,需要哪些库和哪些空间。上面的图的各列的意思,不一一详述,只对重要的进行说明。
第一列的是一个段的起始地址和结束地址,第二列这个段的权限,第三列段的段内相对偏移量,第六列是这个段所存放的内容所对应的文件。从上图可以看到我们的程序进行首先要加载系统的两个共享库,然后再加载我们写的程序的代码。

对于第二列的权限,r:表示可读,w:表示可写,x:表示可执行,p:表示受保护(即只对本进程有效,不共享),与之相对的是s,意是就是共享。

从上图我们可以非常形象地看到一个程序进行时的内存分布情况。下面我们将会结合上图,进行更加深入的对内存中的数据段的解说。

二、程序运行时内存的各种数据段

1.bss段
该段用来存放没有被初始化或初始化为0的全局变量,因为是全局变量,所以在程序运行的整个生命周期内都存在于内存中。有趣的是这个段中的变量只占用程序运行时的内存空间,而不占用程序文件的储存空间。可以用以下程序来说明这点,文件名为bss.c

#include

int bss_data[1024 * 1024];

int main()
{
return 0;
}

这个程序非常简单,定义一个4M的全局变量,然后返回。编译成可执行文件bss,并查看可执行文件的文件属性如图2所示:
20160408_L3I4[1].jpg
从可执行文件的大小4774B可以看出,bss数据段(4M)并不占用程序文件的储存空间,在下面的data段中,我们可以看到data段的数据是占用可执行文件的储存空间的。

在图1中,有文件名且属性为rw-p的内存区间,就是bss段。

2.data段
初始化过的全局变量数据段,该段用来保存初始化了的非0的全局变量,如果全局变量初始化为0,则编译有时会出于优化的考虑,将其放在bss段中。因为也是全局变量,所以在程序运行的整个生命周期内都存在于内存中。与bss段不同的是,data段中的变量既占程序运行时的内存空间,也占程序文件的储存空间。可以用下面的程序来说明,文件名为data.c:
#include

int data_data[1024 * 1024] = {1};

int main()
{
return 0;
}

这个程序与上面的bss唯一的不同就是全局变量int型数组data_data,其中第0个元素的值初始化为1,其他元素的值初始化成默认的0,而因为数组的地址是连续的,所以只要有一个元素在data段中,则其他的元素也必然在data段中。编 译连接成可执行文件data,并查看可执行文件的文件属性如图3所示:
20160408_wJFl[1].jpg
从可执行文件的大小来看,data段数据(data_data数组的大小,4M)占用程序文件的储存空间。

在图1中,有文件名且属性为rw-p的内存区间,就是data段,它与bss段在内存中是共用一段内存的,不同的是,bss段数据不占用文件,而data段数据占用文件储存空间。

3.rodata段
该段是常量数据段,用于存放常量数据,ro就是Read Only之意。但是注意并不是所有的常量都是放在常量数据段的,其特殊情况如下:
1)有些立即数与指令编译在一起直接放在代码段(text段,下面会讲到)中。
2)对于字符串常量,编译器会去掉重复的常量,让程序的每个字符串常量只有一份。
3)有些系统中rodata段是多个进程共享的,目的是为了提高空间的利用率。

在图1中,有文件名的属性为r--p的内存区间就是rodata段。可见他是受保护的,只能被读取,从而提高程序的稳定性。

4.text段
text段就是代码段,用来存放程序的代码(如函数)和部分整数常量。它与rodata段的主要不同是,text段是可以执行的,而且不被不同的进程共享。

在图1中,有文件名且属性为r-xp的内存区间就是text段。就如我们所知道的那样,代码段是不能被写的。

5.stack段
该段就是栈段,用来保存临时变量和函数参数。程序中的函数调用就是以栈的方式来实现的,通常栈是向下(即向低地址)增长的,当向栈中push一个元素,栈顶指针就会向低地址移动,当从栈中pop一个元素,栈顶指针就会向高地址移动。栈中的数据只在当前函数或下一层函数中有效,当函数返回时,这些数据自动被释放,如果继续对这些数据进行访问,将发生未知的错误。通常我们在程序中定义的不是用malloc系统函数或new出来的变量,都是存放在栈中的。例如,如下函数:
void func()
{
int a = 0;
int *n_ptr = malloc(sizeof(int));
char *c_ptr = new char;
}

整型变量a,整型指针变量n_ptr和char型指针变量c_ptr,都存放在栈段中,而n_ptr和c_ptr指向的变量,由于是malloc或new出来的,所以存放在堆中。当函数func返回时,a、n_ptr、c_ptr都会被释放,但是n_ptr和c_ptr指向的内存却不会释放。因为它们是存在于堆中的数据。

在图1中,文件名为stack的内存区间即为栈段。

6.heap段
heap(堆)是最自由的一种内存,它完全由程序来负责内存的管理,包括什么时候申请,什么时候释放,而且对它的使用也没有什么大小的限制。在C/C++中,用alloc系统函数和new申请的内存都存在于heap段中。

以上面的程序为例,它向堆申请了一个int和一个char的内存,因为没有调用free或delete,所以当函数返回时,堆中的int和char变量并没有释放,造成了内存泄漏。

由于在图1所对应的代码中没有使用alloc系统函数或new来申请内存,所以heap段并没有在图1中显示出来,所以以下面的程序来说明heap段的位置,代码文件为heap.c,代码如下:
#include
#include
#include

int main()
{
int *n_ptr = malloc(sizeof(int));
printf("%d\n", getpid());
while(1);
free(n_ptr);
return 0;
}

查看其运行时内存空间分布如下:20160408_gHuN[1].jpg
可以看到文件名为heap的内存区间就是heap段。从上图,也可以看出,虽然我们只申请4个字节(sizeof(int))的空间,但是在操作系统中,内存是以页的方式进行管理的,所以在分配heap内存时,还是一次分配就为我们分配了一个页的内存。注:无论是图1,还是上图,都有一些没有文件名的内存区间,其实没用文件名的内存区间表示使用mmap映射的匿名空间
转载于:https://my.oschina.net/jingxia/blog/697516

#include
#include

class CMyClass
{
public:
CMyClass() { printf(" Constructor\n"); }
~CMyClass() { printf(" Destructor\n"); }
};
CMyClass theObject1;
int main()
{
CMyClass theObject;
::ExitThread(0);
//exit(0);

// 在这个函数的结尾,编译器会自动添加一些必要的代码,
// 来调用theObject的析构函数
return 0;

}

exit(0):可以看到只析构了一个对象,而另外一个未被析构,其实没被析构的对象是局部对象,前面提到exit函数主要任务就是负责析构全局对象和变。

ExitProcess: 局部对象和全局对象都没被析构,因为调用了ExitProcess进程直接结束,而没有调用启动函数中的exit函数,所以全局对象也没被析构。

TerminateProcess: 函数的实际作用跟ExitProcess函数差不多,只不过,此函数可用来终止当前进程之外的另外一个其它进程。

程序中报 "char *" 类型的实参与 "LPWSTR" 类型的形参不兼容C/C++(167) 错误
#include
#include

int main(int argc, char* argv[])
{
char szCommandLine[] = "cmd";
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;

si.dwFlags = STARTF_USESHOWWINDOW; // 指定wShowWindow成员有效
si.wShowWindow = TRUE; // 此成员设为TRUE的话则显示新建进程的主窗口,
// 为FALSE的话则不显示
BOOL bRet = ::CreateProcess (
NULL, // 不在此指定可执行文件的文件名
szCommandLine, // 命令行参数
NULL, // 默认进程安全性
NULL, // 默认线程安全性
FALSE, // 指定当前进程内的句柄不可以被子进程继承
CREATE_NEW_CONSOLE, // 为新进程创建一个新的控制台窗口
NULL, // 使用本进程的环境变量
NULL, // 使用本进程的驱动器和目录
&si,
&pi);

if(bRet)
{
// 既然我们不使用两个句柄,最好是立刻将它们关闭
::CloseHandle (pi.hThread);
::CloseHandle (pi.hProcess);

printf(" 新进程的进程ID号:%d \n", pi.dwProcessId);
printf(" 新进程的主线程ID号:%d \n", pi.dwThreadId);
}
return 0;
}

解决办法
方法一、把工程设置里去掉UNICODE宏定义

项目->XXX属性->配置属性->常规->字符集 , 由使用Unicode字符集 改为 使用多字节字符集

方法二、在程序的开头加上 #undef UNICODE

安装memcached需要先安装libmemcached

一,安装libmemcached

1,下载 : https://launchpad.net/libmemcached/+download

2,安装 : tar -zxf .... cd ....  ./configure --prefix=/usr/local/related/libmemched   make && make install

二,安装memcached

1,下载:http://pecl.php.net/package/memcached

2,安装:tar -zxf ...... cd .... 安装它需要指定php-config与libmemcached的地址(如果它没有安装在默认地址)

./configure --prefix=/usr/local/related/memcached-3.0.4 --with-php-config=/usr/local/php/bin/php-config --with-libmemcached-dir=/usr/local/related/libmemcached-1.0.18/

可能会报一个错:

configure: error: no, sasl.h is not available. Run configure with --disable-memcached-sasl to disable this check

可以根据提示指定--disable-memcached-sasl 解决,也可以安装这个sasl文件:

To solve this issue with CentOS, you should be able to run:

yum install cyrus-sasl-devel

FYI, this question refers to CentOS, but for Ubuntu, the following should work:

sudo apt-get install libsasl2-dev

再次安装如果报错:

configure: error: no, libmemcached sasl support is not enabled. Run configure with --disable-memcached-sasl to disable this check

这是因为安装libmemcached时没有开启sasl支持

所以重新安装libmemcached

./configure --prefix=/usr/local/related/libmemcached --enable-sasl

 三,安装memcached服务

上面安装了php的memcached扩展后安装memcached服务

memcached服务器
memcached
下载地址http://memcached.org/
wget下载路径http://www.memcached.org/files/memcached-1.4.25.tar.gz
这里用到的是
memcached-1.4.25.tar.gz


memcached基于libevent的事件处理:libevent是个程序库,他将Linux 的epoll、BSD类操作系统的kqueue等时间处理功能封装成统一的接口。memcached使用这个libevent库,因此能在Linux、BSD、Solaris等操作系统上发挥其高性能
libevent
下载地址http://libevent.org/
wget下载路径http://jaist.dl.sourceforge.net/project/levent/release-2.0.22-stable/libevent-2.0.22-stable.tar.gz
这里用到的是
libevent-2.0.22-stable.tar.gz


用 WinSCP上传到指定的目录下,这里是
/usr/local/src


shell端
查询系统是否已安装libevent
RPM是RedHat Package Manager(RedHat软件包管理工具)类似Windows里面的“添加/删除程序”
-i            :install 安装
-v            :显示详细信息
-vv           :显示更加详细的信息
-h            :使用#显示安装进度
-U            :软件存在则升级软件,不存在则安装软件
-F            :软件存在则升级软件,不存在则不做任何动作
-e            :程序卸载--nodeps  不卸载相关依赖包,可能导致其他软件无法使用
-q            : 查询某个包是否安装
--test        :仅测试是否可以安装,但是不进行安装
--nodeps      :不考虑依赖关系进行安装,可能造成软件无法正常使用
--force       :忽略软件包及文件的冲突
--replacepkge :无论软件包是否已被安装,都强行安装软件包
--replacepkgs :重新安装软件包,如原有配置文件存在,可能无法覆盖
如下参数只能配合-q组合使用如-qa在所有已安装包中查询是否安装某个包
-a, --all      : 查询/验证所有包
-p, --package  : 查询/验证包文件
-l, --list     : 查询包中的列表文件
-d, --docfiles : 查询列表所有文档文件
-f, --file     : 查询/验证包拥有的文件
例rpm -ivh zsh-4.3.10-4.1.el6.x86_64.rpm安装zsh-4.3.10-4.1.el6.x86_64.rpm并显示详细信息和安装进度
|grep 搜索命令的输出中是否包含某个字符串,加亮显示(这里是-qa命令输出的字符串中查找)
这里显示libevent-2.0.21-4.el7.x86_64,说明已安装libevent-2.0.21-4.el7.x86_64
rpm -qa|grep libevent


卸载已安装的libevent
rpm -e libevent-2.0.21-4.el7.x86_64


进入到安装包目录
cd /usr/local/src


解压缩libevent到当前文件夹
tar -zxvf libevent-2.0.22-stable.tar.gz


进入解压缩目录
cd libevent-2.0.22-stable


配置安装目录
./configure --prefix=/usr/local/libevent


编译
make


安装
make install


返回上级目录
cd ../


解压缩memcached到当前文件夹
这个压缩包没有用gzip格式压缩  所以解压的时候也不用加上z,直接 tar -xvf 就可以了
tar -xvf memcached-1.4.25.tar.gz


进入解压缩目录
cd memcached-1.4.25


配置安装目录,及关联的libevent库安装目录
./configure --prefix=/usr/local/memcached --with-libevent=/usr/local/libevent


编译
make


安装
make install


创建文件夹用来保存memcached的进程文件
mkdir -m777 -p /usr/local/memcached/pid


启动memcached
-d  选项是启动一个守护进程。
-u  表示启动memcached的用户,这里为root,可以指定低权限用户启动memcached。
-m  是分配给Memcache使用的内存数量,单位是MB,默认64MB。内容容量达到指定的值之后memcached回自动删除不适用的缓存
-p  是设置Memcache的TCP监听的端口,最好是1024以上的端口,memcached默认端口11211。
-c  选项是最大运行的并发连接数,按照服务器的负载量来设定,默认是1024。
-P  是设置保存Memcache的pid文件,也就是保存进程ID到指定文件,只有在使用 -d 选项的时候才有意义。
-vv 输出详细信息
也可以启动多个守护进程,但是端口不能重复。这样就可以在一台机器上相当拥有多个Memcached服务器
/usr/local/memcached/bin/memcached -d -m 256 -u root -p 11211 -c 1024 -P /usr/local/memcached/pid/memcached.pid -vv


杀死memcached进程
kill `cat /usr/local/memcached/pid/memcached.pid`


/*
或者可以查看11211端口使用情况获取使用进程ID
lsof -i:11211


直接用kill 进程ID 来杀死进程,这里memcached的进程ID是20146
kill 20146
*/


将memcached放到service控制中将下面代码新建保存到/etc/init.d/memcached中
#!/bin/bash
# memcached MemCached
# it is v.1.4.25 version.
# chkconfig: - 85 15
# description: memcached is very good
# processname: memcached
MEMCACHED="/usr/local/memcached/bin/memcached"
PID_FILE="/usr/local/memcached/pid/memcached.pid"
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
start()
{
    $MEMCACHED -d -m 256 -u root -p 11211 -c 1024 -P ${PID_FILE}
}
stop()
{
    kill `cat $PID_FILE`
}
restart(){
    stop
    start
}
case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        stop
        sleep 3
        start
        ;;
    *)
    echo $"Usage: 0 {start|stop|restart}"
    exit 1
esac
exit 0
:wq  保存并退出
vim /etc/init.d/memcached


设置文件的访问权限
chmod 755 /etc/init.d/memcached


可以使用service控制memcached启用关闭了
service memcached start


让memcached服务加入到开机启动指令管理的服务列表中
chkconfig --add memcached


设置开机启动
chkconfig memcached on


开启防火墙11211端口的外部访问
firewall-cmd --zone=public --add-port=11211/tcp --permanent


重启防火墙
firewall-cmd --reload

附
linux启动memcached选项
-p   : 监听的TCP端口(默认: 11211)
-U   : 监听的UDP端口(默认: 11211, 0表示不监听)
-s   : 用于监听的UNIX套接字路径(禁用网络支持)
-a   : UNIX套接字访问掩码,八进制数字(默认:0700)
-l   : 监听的IP地址。(默认:INADDR_ANY,所有地址)
-d   : 作为守护进程来运行。
-r   : 最大核心文件限制。
-u   : 设定进程所属用户。(只有root用户可以使用这个参数)
-m   : 单个数据项的最大可用内存,以MB为单位。(默认:64MB)
-M   : 内存用光时报错。(不会删除数据)
-c   : 最大并发连接数。(默认:1024)
-k   : 锁定所有内存页。注意你可以锁定的内存上限。试图分配更多内存会失败的,所以留意启动守护进程时所用的用户可分配的内存上限。(不是前面的 -u  参数;在sh下,使用命令"ulimit -S -l NUM_KB"来设置。)
-v   : 提示信息(在事件循环中打印错误/警告信息。)
-vv  : 详细信息(还打印客户端命令/响应)
-vvv : 超详细信息(还打印内部状态的变化)
-h   : 打印这个帮助信息并退出。
-i   : 打印memcached和libevent的许可。
-P   : 保存进程ID到指定文件,只有在使用 -d 选项的时候才有意义。  
-f   : 块大小增长因子。(默认:1.25)
-n   : 分配给key+value+flags的最小空间(默认:48)
-L   : 尝试使用大内存页(如果可用的话)。提高内存页尺寸可以减少"页表缓冲(TLB)"丢失次数,提高运行效率。为了从操作系统获得大内存页,memcached会把全部数据项分配到一个大区块。
-D   : 使用  作为前缀和ID的分隔符。这个用于按前缀获得状态报告。默认是":"(冒号)。如果指定了这个参数,则状态收集会自动开启;如果没指定,则需要用命令"stats detail on"来开启。
-t   : 使用的线程数(默认:4)
-R   : 每个连接可处理的最大请求数。
-C   : 禁用CAS。
-b   : 设置后台日志队列的长度(默认:1024)
-B   : 绑定协议 - 可能值:ascii,binary,auto(默认)
-I   : 重写每个数据页尺寸。调整数据项最大尺寸。

SAP 中的LT
本人开始转行到SAP开发
2020-10-24 14:48:31
sap开发核心语言ABAP
有套视频大概一个多月可以入门,
我发现自学一个东西真的很有意思,每天下班后闭关修炼,加成自己,多年后你就是大神,你还怕没收入吗?咳咳有点说多了下面,我随便记录一下自己的学习比较毕竟散,我是用来自己看的。

FI 财务报表
co成本控制
sd销售模块
mm 物料管理
pp生产模块

abap开发模块
basis 补丁,硬件
pm 工厂管理
ps项目管理
QM质量管理
数据字典是一个工具,和新华字典类似
数据字典点主要功能为保证数据点完整性,一致性,安全性。
结构是什么?
结构就是有系列的字段组成
元素是什么?
元素就是单独点一些数据
数据类型是数据结构中的定义是一个值的集合以及定义在这个值集上的一组操作。在SAP中,数据类型有3种:

Data element:最基本的数据单位,没有结构,定义了数据的描述,数据类型和长度等其他特征。
Structure:由数据元素或者其他的数据类型组成的一个特定结构。
Table type:table类型的数据元素,可存放多行数据。
LIKE???LINE?OF
数据字典定义点表不是直接创建一个物理表,而是在中间层创建一个表,创建完成后它自动的在后台创建一个物理表
abap数据字典的基本对象,表,视图,数据类型,域,搜索帮助,锁对象。六大对象。
database-vice数据库视图
Projection -view投影视图
Maintenance view维护视图
Help view帮助视图
SAP
SE16:专门看表数据的。
SM30:查看视图数据的。
SAP数据类型
程序命名GUI法
以Z开头
报表是ZR
接口是I
打印是F
快速调整字体大小 Ctrl + 鼠标滚轮
剪切一行 Ctrl + Shift + X
删除一行 Ctrl + Shift + L
复制一行 Ctrl + Shift + T
转成小写 Ctrl + L
转成大写 Ctrl + U
大小写相互转换 Ctrl + K
取消 Ctrl + Z
重做 Ctrl + Y
原地复制一行 Ctrl + D
tableType:表类型。
我的程序
ZOROGRAM_F0029

Z51SAP_CAO
表格维护生成器
1.SE54
2.在se11表格中实用程序中选择维护生成器
权限组指点是查看的权限,选择无权限,函数组只要给个名字就可以了。
数据库视图
其中数据库视图主要是用来查数据的。
维护视图专门用来维护数据
LOC锁:
释放锁DEQ
加锁:ENQ

语法:
数据类型缩写
DECIMALS x表示小数 位。
C:文本型,默认长度为1,默认值为 space(空).
D: 日期型,默认长度8 允许长度8 ,默认值为 00000000 ,格式为 YYYYMMDD.
F:浮点型,默认长度8 允许长度8 ,默认值为 0.
I:整型,默认长度4 允许长度10 ,默认值为 0
N: 数值型,默认长度1允许长度31 ,默认值为 ‘00000000’ 表示存储数值类型的字符串。
P:压缩型,默认长度8 允许长度16 ,默认值为 0,将两个十进制数字压缩到1个字节注意如果需要存储小数必须指定小数的个数。
T:时间类型,默认长度6 允许长度6 ,默认值为 ‘000000’ 时间。
P型小数点要使用DECIMAL声明小数位n.
变量定义;DAta:后面跟name

like用在已经定于好的数据类型

type用在定义数据类型。

常量定义:constants;name
打印关键词 WRITE
move-corresponding 用于结构赋值,仅复制相同名称的字段

=赋值是基本赋值

WRITE xx(数据源) to xx(赋值对象)。

move xx to xx(同上)。
c类型转N类型只保留数值,其他忽略。

C类型不能直接转行I类型需要通过N类型转换。

小数位赋值时一定要“”否则系统不知道你中间那个点是结束还是什么。

系统常量的意思:
SY-SUBRC:语句执行后的返回值,0表示成功
SY-DATUM:当前服务器日期
SY-UZEIT:当前服务器时间
SY-ULINE:255长度的水平线
SY-VLINE:垂直线 SY-INDEX:循环说执行的次数
SY-TABIX:内表循环的次数
SY-DYNNR:当前Screen号
SY-MANDT:当前登录的Client号
SY-STEPL:返回当前操作的屏幕行号(Table Control)
SY-LOOPC:当前表格控件在屏幕中的总行数(Table Control)
SY-UCOMM:PAI所出发的功能代码
SY-DYNNR:当前屏幕号
SY-MSGID:Message Class
SY-MSGNR:Message Number
SY-MSGTY:Message Type
SY-MSGV1~4:Message Variant
SY-LINCT:REPROT语句中设定的LINE-COUNT
SY-LINSZ:REPROT语句中设定的LINE-SIZE
SY-SROWS:当前窗口的列表行数
SY-SCOLS:当前窗口的列表栏目数
SY-PAGNO:当前页的页码
SY-LINNO:当前选定行的行号
SY-COLNO:当前选定列的列号
SY-LSIND:当前列表索引,第一级列表为1
SY-LILLI:选择某行时光标行位置
SY-CUROW:选择某行时光标列位置
SY-REPID:返回当前程序名
MOVE-CORRESSPONDING to :此表达的是:
各种符号意思:
+
/

mod(除法的一种取余)
=或EQ(等于)
<>或><或者 NE(不等于)
<或LT(小于)

或GT(大于)
<=或LE(小于等于)
=或GE(大于等于)
逻辑运算符号
AND 且。
OR 或。
not 非。
移位
关键词
SHIFT XX(数据源) by x(整数需要移动多少位) PLACES (默认往left(左)移动right(右))
指定字符串c从c1位置开始移位。
shift c(数据源)up to c1(指定的位置)
write sy-subrc(检查是否成功,成功返回0否则返回4)

移除字符串c左边/右边的子字符串c1:
SHIFT c LEFT/RIGHT DELETING LEADING/ TRAILING c1

把‘abcdefg’中的abc替换成123
REPLACE ‘ABC’ WITH ‘123’ INTO ‘ABCDEFG’.
去除所有空格
condense (数据源) no-GAPS.

查找某个字符串
SEARCH (数据源) for(目标数据)

TYPE STANDARD TABLE OF定义标准内表

什么叫执行语句
除了定义点语句其他语句都叫执行语句。

条件控制语句
DATA: lv_number type int2.
DATA lv_result TYPE int2.
lv_number = 7.
lv_result = lv_number mod 2.
write: sy-uline.
IF lv_result = 0.
WRITE:/,‘偶数’.
else.
write:/,‘基数’.
ENDIF.

CLEAR 内表。
清除变量内容
常量不能被清空

CONTINUE:无条件终止当前循环,直接执行下一次循环
CHECK: 有条件终止当前循环
EXIT:终止所有循环

PERFORM作用是用来调用封装的代码。

WITH HEADER LINE这是一个旧bai说法,定义内表的时du候,你可以指定是否创建一个zhi同名的表头(工作区)
内表

内存中建立的临时表。

内表有三种类型

1standard:标准表

2sorted:排序表

3hashed:哈希表

共同点:

都可以对内存的数据进行插入,删除,修改操作
不同点:

标准表:在插入数据时并不对数据行的地址进行重新排序存储。

排序表:在增加和插入时要对数据存储的地址进行重新排序。

哈希表:只能通过关键字进行访问,在检索数据里与数据行数无关。

内表的初始化:CLEAR只能清空工作行。

数据库插入只有一个insert关键字

内表有三个关键字

insert插入一行或者多行数据。

append也是表示插入,内表仅用于存储数据,可以进行附加。

collect也是表示插入,内表去重复,统计字段之和。

initial:表示空行

SPLIT <需要拆分的程序> AT <拆分条件> INTO h1…hn(h为变量名称使用空格隔开)。

使用"LOOP … ASSIGNING …"可以直接修改内表中的数据,而不需要先将内表数据复制到相应工作区,然后再更新回去,性能提高。

BREAK-POINT.表示断点

参考定义
DATA: itab4 like itab1.“参考已定义的内表”
data: itab6 TYPE TABLE OF (数据库表名称).“参考数据库表定义内表”
DATA: itab7 TYPE STANDARD TABLE OF zschange.“参考表结构定义内表”
*排序表,哈希表
DATA itab8(内表名称) TYPE SORTED TABLE OF 数据库表名称 WITH UNIQUE KEY 关键字(数据库字段).“排序表”
DATA itab9(内表名称) TYPE HASHED TABLE OF 数据库表名称 WITH UNIQUE KEY carrid.“数据库字段”
*定义工作区
DATA:ls_itab1 type ty_inab1.

WITH HEADER LINE 此关键词就是在定义内表的时候定义一个名字相同的工作空间,(旧方法)。

通过DESCRIBE获得内表的行
DESCRIBE TABLE LINES n
DESCRIBE?TABLE?emp?LINES?n1.???"表中无数据,回执为0.

内表处理
*添加条目
ls_itab1-field1 = ‘00001’.
ls_itab1-field2 = 00001.
INSERT ls_itab1 INTO itab1 INDEX 1.
APPEND ls_itab1 to itab1 .
COLLECT ls_itab1 INTO itab1.
添加条目排序表
ls_itab1-field1 = ‘00001’.
ls_itab1-field2 = 00001.
INSERT ls_itab1 INTO itab8 INDEX 1.
APPEND ls_itab1 to itab8 .
COLLECT ls_itab1 INTO itab8.
添加一个内表到另一个内表中
append lines of itab1 to itab2.
append lines of itab1 FROM 1 to 2 to itab2.
INSERT LINES OF itab1 to itab2.
DELETE TABLE itab WITH TABLE KEY k1=v1…kn=vn.

按具体值删除

DELETE TABLE itab [FROM wa].

参照其它内表值删除

DELETE itab INDEX idx.

删除具体行数据

DELETE itab FROM idx1 TO idx2.

删除具体行数范围间数据

DELETE ADJACENT DUPLICATES FROM itab.

删除重复数据,执行此条件前必须先排序

BOOK1[] = BOOK[].内表赋值给内表。

APPEND INITIAL LINE TO

排序
sort itab(名称) [by f1 f2…fn]
sql
SELECT语法结构:
SELECT FROM
?INTO
WHERE
GROUP BY
ORDER BY

其中各关键字的属性描述如下:
SELECT :具体的查询字段。
SELECT SINGLE:定义单行查询。
FROM :所查询的透明表。
INTO :查询结果赋值对象,赋值到具体表或结构体。
INTO (…):将查询结果赋值到具体字段。
INTO CORRESPONDING FILES OF :将查询结果按字段匹配赋值给具体的内表或者结构体。
WHERE :查询条件。
GROUP BY :分组查询条件。
ORDER BY :排序条件。

使用SELECT…ENDSELECT语法能循环读取及操作查询
通过系统参数SY-DBCNT可以获取当前读取数据的行数
COUNT():统计查询总数
SUM():统计表中某个数值字段的总和
AVG():统计表中某个数值字段的平均值
MAX():统计表中某个字段的最大值
MIN() :统计表中某个字段的最小值。

IKE LINE OF后面接一个内表,表示一个DATA参数具有和内表一样的结构(structure),例如有一个TABLES:Z_USER,Z_USER有两个字段,一个ID,一个NAME,那么

DATA:WA LIKE LINE OF Z_USER 表示WA和Z_USER的STRUCTURE一样,可以吧WA当做Z_USER的WORK AREA来用。

LIKE TABLE OF 后面接一个STRUCTURE,表示一个DATA参数是一个内表,这个内表的结构和后面接的那个结构一样,

与alv事件相关事务代码
se37
REUSE_ALV_EVENTS_GET
常用事物
user_command 客户响应

top_of_page 标题栏的设置

pf_status_set 工具栏设置

调用alv显示:REUSE_ALV_EVENTS_GET(在工具模式中输入以上函数)

判断内表是否为空的语句为:
IF IT_DATA IS INITIAL. "如果内表为空

*执行体

ENDIF.

IF NOT IT_DATA IS INITIAL. "如果内表不为空

*执行体

ENDIF.
lav事件常用的
user_command

top_of_page

pf_status_set

rrc远程函数

使用CALL FUNCTION 语句调用方法函数注意函数名称必须是大写而且要用单引号包裹例子:

CALL FUNCTION ‘BC400_MOS_POWER’

EXPORTING表示输入参数的关键字。

IMPORTING表示输出参数的结果关键字。

se80叫做对象开发浏览器,可以查看所有的开发对象。

补充前导零的函数:‘CONVERSION_EXIT_ALPHA_INPUT’。

内存有两种,一种是sap内存,一种是abap内存,

sap内存要比abap中的内存要大。

sap内存不管你打开了多少个窗口,所有的内存都是共享的,

abap只是针对一个进程进行内存共享,如果一个用户开启多个窗口其中内存不是共享的,

CALL TRANSACTION ‘’.在同一个程序中调用另一个程序的语法。

还可以使用submit {程序名称}

abap内存共享成功需要他们定义的变量名称要一致才行。

DEFAULT 此关键词是设置默认值的意思。

MEMORY ID 往sap内存中设置默认值。

AS CHECKBOX 复选框关键字 长度只能唯一超过就报错,复选框如果选中对应的值是大写的X 否则就是空格。

RADIOBUTTON GROUP{名称}单选框,所以在书写的时候最少需要两个元素才能使用,当然可以定义多组单选框以名称为分组。

AS LISTBOX 下拉菜单。

VISIBLE LENGTH 10显示长度,我们肉眼能看到的长度并不是输出参数的长度。

SELECT-OPTIONS name for(参考)data_object
.
name 为选择选项的名称

data_object是一个预定义的变量,或者数据库表的字段。

SELECT-OPTIONS是当做内表来进行的包含四列 sing (符号),optin(比较符号),low(最小值),high(最大值)

它定义的类型是char2只能是字母来表达。

types 声明表。

调试的时候出现帽子一样的图标表示他是一个内表。

no INTERVALS 表示所有的选择元素都只有一个输入项。

屏幕事件就是点击某一个按钮触发不同的事件表示不同的功能。

INTO CORRESPONDING FIELDS OF的作用:匹配工作区
,(INTO CORRESPONDING FIELDS OF TABLE的作用是:表字段名转换在查询过程中我们通常会遇到这样的情况,将透明表查询值直接传递给内表:

两表中字段结构一样,但字段名称却不同

通常的情况下将字段名称设为一致的

除此之那还可以用AS关键字,就像SQL中的用法一样

程序有五种程序:可执行程序,模块池程序都可以插入屏幕,函数程序,接口程序,子程序。)

对话屏幕:客户操作之后和程序进行交互叫对话屏幕,

跟程序显示相关的程序都在pbo里边,用户触发了某一个事件,我们要进行响应这部分逻辑流写在了pai里边

LEAVE PROGRAM.退出屏幕。

LEAVE SCREEN:退出当前屏幕。

concatenate表示字符串拼接的意思。

在查询过程中我们通常会遇到这样的情况,将透明表查询值直接传递给内表:

两表中字段结构一样,但字段名称却不同

通常的情况下将字段名称设为一致的

除此之那还可以用AS关键字,就像SQL中的用法一样

*这个意思是新语法,不用自己再创建内表或者工作空间它自动创建

INTO TABLE @DATA(lt_zsdt02_021)

*FOR ALL ENTRIES IN这是一个固定写法,以内表中的某些字段为条件在数据库中取数,我们一般bai使用for all entries in 语句将该表与内du表串联。

FOR ALL ENTRIES IN @gt_item

WHERE zvbeln EQ @gt_item-zvbeln.

select single?single选取的数据要放到 工作区中,而不能放到表中。

INTO TABLE与APPENDING TABLE的区别 从字面看好像作用是相同的,但具体使用以来还是有区别的。

如果都是从数据库表中select一次数据,添加到内表中,他们的作用相同;

但是多次,他们的作用则有很大差别,INTO TABLE:将数据select出来添加到内表时会将内表先清空再添加,

而APPENDING TABLE则会直接追加,实现累计效果。

程序二:
LOOP AT it_marc.

it_marc-dispo = ‘G00’.

it_marc-plifz = 5.

MODIFY it_marc TRANSPORTING dispo plifz.

ENDLOOP.
程序二使用了TRANSPORTING子句,
更新内部表记录时仅更新DISPO,PLIFZ两个字段.

CALL METHOD

特殊符号 &表示拼接字符串代码如下:
DATA name(300) TYPE c VALUE 'spfli AS p ’
& ’ INNER JOIN sflight AS f ’
& ‘ON p~carrid = f~carrid and p~connid = f~connid’ &
'inner join sbook as b ’ &
‘ON b~carrid = f~carrid AND b~connid = f~connid AND b~fldate = f~fldate’.

abap 命名规范
数据定义(data definitions):

type类型 : TY_

全局变量 GV_

局部变量 LV_

全局工作区GS_

本地工作区: LS_

全局内表:GT_

局部内表: LT_

指针(field symbols):

本地结构:<LFS_*>

全局结构:<GFS_*>

功能模块:

输入参数:IV_ eg: IV_MATERIAL

输出参数): EV_

changing-parameter :CV_

表 :T_* eg:T_MATERIAL

类 (Class) :

输入参数:IV_ eg: IV_MATERIAL

输出参数: EV_

changing-parameter :CV_

结果 : RV_

异常 :ZCX_ eg: ZCX_ERROR

Parameter : P_*

Select-Options : S_*

Range Field : R_*

Interface : ZIF_*

LOOP … ASSIGNING …的使用

表示指针指向的地址。

Field-Symboles: like ITAB.

LOOP AT ITAB ASSIGNING .

I = SY-TABIX MOD 2.

IF I = 0.

<WA>-FLAG = 'X'.

ENDIF.

ENDLOOP.

事件
双击事件:&IC1
SKIP FIRST SCREEN意思是:跳过第一个屏幕。

REF TO(参考)用来定义类和接口。

触发异常:
Raise.
如果在function的调用中指定异常,控制直接返回调用程序。

如果未列出该异常,则程序会因运行是错误而终止。

变式是什么:
这个我不清楚确切的定bai义,但du根据我以往用的情况,这个变式多半是zhi指,你自己设定的特殊格式和内容。

比dao如你在使用一个报表时,你常用几个信息,你就可以将这些信息输入后,点那个小框框(变式),

保存一个名字,下次你再用的时候,可以直接将你保存的名字输入,就不必一个一个的重新填写了。
massge 类型 E类型就是在屏幕下方出现提示,I类型就是弹出一个提升框。
instance 级别,叫做实例属性 必须要创建一个对象接受才能拿来用。
constant 常量级别,可以当作静态属性来用。
判断对象是否创建成功 使用关键字 is bound (是否被绑定)。