Q:

What is the most memory-friendly way to declare integer literals?

I'm having SRAM overflow problems with my 8bit atmega328p in my Arduino Uno, which has 2KB of SRAM, so I'm defining all my for loops with bytes as counters instead of ints. As in:
for(byte i=0;i<16;i++) buf[i]=(char)ap1[i];

Would it make any difference if I declared the integer literal 16 as a constant? 
const byte BUFSIZE=16;

Or using the preprocessor:
#define BUFSIZE 16

There's also the macro PROGMEM which stores variables in flash memory, which I've decided to use for all my constants, but is it not the point of const to do this? as well as aiding the compiler in warning you if you screwed up changing the variable.
const byte BUFSIZE PROGMEM=16;

AFAIK, using const would save BUFSIZE in the flash memory, but how about using the preprocessor? Using the preprocesor would be the exact the same as using the literal 16, as far as i'm concerned.
This fear arose from the fact that string literals are saved in Flash and then transferred to SRAM, wasting twice the space, which you can solve using the arduino macro F("thisisastring"), which stores them in flash memory, and I don't want to waste 2 bytes of SRAM in every for loop I use

A:

I'm not familiar with the Atmel megaAVR microcontrollers or Arduino.  But generally speaking, your memory optimization ideas are misguided.
For example, it's likely that the compiler implements local loop variables within a register so that they don't consume any RAM at all.
And the integer literal constants, such as 16 from your example, also likely don't consume any RAM.  The compiler likely incorporates these constants into the code.
Whenever you optimize something it's best to go after the big fish first.  You're focusing on the tiniest fish.  To find the big fish, look at the *.map file produced by the linker.  The map file should show how much RAM and Flash memory is used by your program.  The RAM sections might be labeled "bss" and "data" in the map file.  Hopefully the map file will also detail how much RAM is used by each compilation unit.  Find the compilation units that are using the most RAM and focus on them.  Maybe there are large buffers or arrays defined in those compilation units that can be reduced in size or redesigned.
The map file is also where you could check to see if your optimizations have made any difference.  For example, try some of the optimization you described and see whether the map file changes significantly.

A:

Well, it's easy to just try and see... Let's try the following program:
#ifdef USE_CONST
const byte BUFSIZE = 16;
#else
#  define BUFSIZE 16
#endif

char buf[BUFSIZE], ap1[BUFSIZE];

int main(void)
{
    for (byte i = 0; i < BUFSIZE; i++)
        buf[i] = ap1[i];    
    return 0;
}

I compiled this for an Uno both with and without #define USE_CONST,
and it doesn't make any difference! avr-size reports the same sizes for
both versions, and the generated assemblies are identical: the optimizer
transformed the loop into something like
byte *Z = ap1;
byte *X = buf;
do {
    *X++ = *Z++;
} while (Z != ap1 + 16);

where X and Z are two of the CPU's pointer registers, and ap1 + 16 is
an immediate constant, i.e. part of the instruction itself, c.f. the
AVR addressing modes.
It is worth noting that, in C++,
const implies internal linkage.
Thus a const global variable is very much like a preprocessor constant.
This is unlike C, where you would need to qualify the variable as
static const in order to get the same behavior. Otherwise the compiler
would need to allocate storage to BUFSIZE, just in case it is
referenced as extern from another source file, even though it can
replace occurrences of BUFSIZE in the same file with its immediate
value.
On the other hand, the Arduino IDE compiles your code with
-ffunction-sections -fdata-sections
and links it with
--gc-sections,
which means the linker will eventually get rid of the unused reserved
storage.

